Index: g-table.ads
===================================================================
--- g-table.ads	(revision 251753)
+++ g-table.ads	(working copy)
@@ -41,8 +41,6 @@
 --     GNAT.Table
 --     Table (the compiler unit)
 
-pragma Compiler_Unit_Warning;
-
 with GNAT.Dynamic_Tables;
 
 generic
Index: namet.h
===================================================================
--- namet.h	(revision 251753)
+++ namet.h	(working copy)
@@ -45,11 +45,11 @@
 };
 
 /* Pointer to names table vector. */
-#define Names_Ptr namet__name_entries__tab__the_instance
+#define Names_Ptr namet__name_entries__table
 extern struct Name_Entry *Names_Ptr;
 
 /* Pointer to name characters table. */
-#define Name_Chars_Ptr namet__name_chars__tab__the_instance
+#define Name_Chars_Ptr namet__name_chars__table
 extern char *Name_Chars_Ptr;
 
 /* This is Hostparm.Max_Line_Length.  */
Index: par_sco.adb
===================================================================
--- par_sco.adb	(revision 251753)
+++ par_sco.adb	(working copy)
@@ -44,7 +44,6 @@
 
 with GNAT.HTable;      use GNAT.HTable;
 with GNAT.Heap_Sort_G;
-with GNAT.Table;
 
 package body Par_SCO is
 
@@ -76,12 +75,13 @@
    --  running some steps multiple times (the second pass has to be started
    --  from multiple places).
 
-   package SCO_Raw_Table is new GNAT.Table
+   package SCO_Raw_Table is new Table.Table
      (Table_Component_Type => SCO_Table_Entry,
       Table_Index_Type     => Nat,
       Table_Low_Bound      => 1,
       Table_Initial        => 500,
-      Table_Increment      => 300);
+      Table_Increment      => 300,
+      Table_Name           => "Raw_Table");
 
    -----------------------
    -- Unit Number Table --
Index: scos.ads
===================================================================
--- scos.ads	(revision 251753)
+++ scos.ads	(working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 2009-2016, Free Software Foundation, Inc.         --
+--          Copyright (C) 2009-2017, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -29,10 +29,9 @@
 --  is used in the ALI file.
 
 with Namet; use Namet;
+with Table;
 with Types; use Types;
 
-with GNAT.Table;
-
 package SCOs is
 
    --  SCO information can exist in one of two forms. In the ALI file, it is
@@ -383,12 +382,13 @@
       --  For the SCO for a pragma/aspect, gives the pragma/apsect name
    end record;
 
-   package SCO_Table is new GNAT.Table (
+   package SCO_Table is new Table.Table (
      Table_Component_Type => SCO_Table_Entry,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => 500,
-     Table_Increment      => 300);
+     Table_Increment      => 300,
+     Table_Name           => "Table");
 
    Is_Decision : constant array (Character) of Boolean :=
      ('E' | 'G' | 'I' | 'P' | 'a' | 'A' | 'W' | 'X' => True,
@@ -530,12 +530,13 @@
 
    end record;
 
-   package SCO_Unit_Table is new GNAT.Table (
+   package SCO_Unit_Table is new Table.Table (
      Table_Component_Type => SCO_Unit_Table_Entry,
      Table_Index_Type     => SCO_Unit_Index,
      Table_Low_Bound      => 0, -- see note above on sorting
      Table_Initial        => 20,
-     Table_Increment      => 200);
+     Table_Increment      => 200,
+     Table_Name           => "Unit_Table");
 
    -----------------------
    -- Generic instances --
@@ -551,12 +552,13 @@
       Enclosing_Instance : SCO_Instance_Index;
    end record;
 
-   package SCO_Instance_Table is new GNAT.Table (
+   package SCO_Instance_Table is new Table.Table (
      Table_Component_Type => SCO_Instance_Table_Entry,
      Table_Index_Type     => SCO_Instance_Index,
      Table_Low_Bound      => 1,
      Table_Initial        => 20,
-     Table_Increment      => 200);
+     Table_Increment      => 200,
+     Table_Name           => "Instance_Table");
 
    -----------------
    -- Subprograms --
Index: scos.h
===================================================================
--- scos.h	(revision 251753)
+++ scos.h	(working copy)
@@ -45,16 +45,14 @@
 
 typedef struct SCO_Unit_Table_Entry *SCO_Unit_Table_Type;
 
-/* The following depends on the fact that The_Instance.Table
-   is the first component. */
-extern SCO_Unit_Table_Type scos__sco_unit_table__the_instance;
-#define SCO_Unit_Table scos__sco_unit_table__the_instance
+extern SCO_Unit_Table_Type scos__sco_unit_table__table;
+#define SCO_Unit_Table scos__sco_unit_table__table
 
-extern Int scos__sco_unit_table__first(void);
-#define SCO_Unit_Table_First scos__sco_unit_table__first
+extern Int scos__sco_unit_table__min;
+#define SCO_Unit_Table_Min scos__sco_unit_table__min
 
-extern Int scos__sco_unit_table__last(void);
-#define SCO_Unit_Table_Last scos__sco_unit_table__last
+extern Int scos__sco_unit_table__last_val;
+#define SCO_Unit_Table_Last_Val scos__sco_unit_table__last_val
 
 
 /* SCOs table:  */
@@ -76,16 +74,14 @@
 
 typedef struct SCO_Table_Entry *SCO_Table_Type;
 
-/* The following depends on the fact that The_Instance.Table
-   is the first component. */
-extern SCO_Table_Type scos__sco_table__the_instance;
-#define SCO_Table scos__sco_table__the_instance
+extern SCO_Table_Type scos__sco_table__table;
+#define SCO_Table scos__sco_table__table
 
-extern Int scos__sco_table__first(void);
-#define SCO_Table_First scos__sco_table__first
+extern Int scos__sco_table__min;
+#define SCO_Table_Min scos__sco_table__min
 
-extern Int scos__sco_table__last(void);
-#define SCO_Table_Last scos__sco_table__last
+extern Int scos__sco_table__last_val;
+#define SCO_Table_Last_Val scos__sco_table__last_val
 
 #ifdef __cplusplus
 }
Index: spark_xrefs.ads
===================================================================
--- spark_xrefs.ads	(revision 251753)
+++ spark_xrefs.ads	(working copy)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 2011-2016, Free Software Foundation, Inc.         --
+--          Copyright (C) 2011-2017, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -29,8 +29,8 @@
 --  file, and by Get_SPARK_Xrefs/Put_SPARK_Xrefs to read/write the textual
 --  representation that is stored in the ALI file.
 
+with Table;
 with Types;      use Types;
-with GNAT.Table;
 
 package SPARK_Xrefs is
 
@@ -258,12 +258,13 @@
       --  Column number for the reference
    end record;
 
-   package SPARK_Xref_Table is new GNAT.Table (
+   package SPARK_Xref_Table is new Table.Table (
      Table_Component_Type => SPARK_Xref_Record,
      Table_Index_Type     => Xref_Index,
      Table_Low_Bound      => 1,
      Table_Initial        => 2000,
-     Table_Increment      => 300);
+     Table_Increment      => 300,
+     Table_Name           => "Xref_Table");
 
    -----------------
    -- Scope Table --
@@ -323,12 +324,13 @@
       --  Entity (subprogram or package) for the scope
    end record;
 
-   package SPARK_Scope_Table is new GNAT.Table (
+   package SPARK_Scope_Table is new Table.Table (
      Table_Component_Type => SPARK_Scope_Record,
      Table_Index_Type     => Scope_Index,
      Table_Low_Bound      => 1,
      Table_Initial        => 200,
-     Table_Increment      => 300);
+     Table_Increment      => 300,
+     Table_Name           => "Scope_Table");
 
    ----------------
    -- File Table --
@@ -360,12 +362,13 @@
       --  Ending index in Scope table for this unit
    end record;
 
-   package SPARK_File_Table is new GNAT.Table (
+   package SPARK_File_Table is new Table.Table (
      Table_Component_Type => SPARK_File_Record,
      Table_Index_Type     => File_Index,
      Table_Low_Bound      => 1,
      Table_Initial        => 20,
-     Table_Increment      => 200);
+     Table_Increment      => 200,
+     Table_Name           => "File_Table");
 
    ---------------
    -- Constants --
Index: table.adb
===================================================================
--- table.adb	(revision 251753)
+++ table.adb	(working copy)
@@ -29,6 +29,9 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Debug;   use Debug;
+with Opt;     use Opt;
+with Output;  use Output;
 with System;  use System;
 with Tree_IO; use Tree_IO;
 
@@ -36,20 +39,370 @@
 
 with Unchecked_Conversion;
 
+pragma Elaborate_All (Output);
+
 package body Table is
    package body Table is
 
+      Min : constant Int := Int (Table_Low_Bound);
+      --  Subscript of the minimum entry in the currently allocated table
+
+      Length : Int := 0;
+      --  Number of entries in currently allocated table. The value of zero
+      --  ensures that we initially allocate the table.
+
+      -----------------------
+      -- Local Subprograms --
+      -----------------------
+
+      procedure Reallocate;
+      --  Reallocate the existing table according to the current value stored
+      --  in Max. Works correctly to do an initial allocation if the table
+      --  is currently null.
+
       function Tree_Get_Table_Address return Address;
       --  Return Null_Address if the table length is zero,
       --  Table (First)'Address if not.
 
+      pragma Warnings (Off);
+      --  Turn off warnings. The following unchecked conversions are only used
+      --  internally in this package, and cannot never result in any instances
+      --  of improperly aliased pointers for the client of the package.
+
+      function To_Address is new Unchecked_Conversion (Table_Ptr, Address);
+      function To_Pointer is new Unchecked_Conversion (Address, Table_Ptr);
+
+      pragma Warnings (On);
+
+      ------------
+      -- Append --
+      ------------
+
+      procedure Append (New_Val : Table_Component_Type) is
+      begin
+         Set_Item (Table_Index_Type (Last_Val + 1), New_Val);
+      end Append;
+
+      ----------------
+      -- Append_All --
+      ----------------
+
+      procedure Append_All (New_Vals : Table_Type) is
+      begin
+         for J in New_Vals'Range loop
+            Append (New_Vals (J));
+         end loop;
+      end Append_All;
+
+      --------------------
+      -- Decrement_Last --
+      --------------------
+
+      procedure Decrement_Last is
+      begin
+         Last_Val := Last_Val - 1;
+      end Decrement_Last;
+
+      ----------
+      -- Free --
+      ----------
+
+      procedure Free is
+      begin
+         Free (To_Address (Table));
+         Table := null;
+         Length := 0;
+      end Free;
+
+      --------------------
+      -- Increment_Last --
+      --------------------
+
+      procedure Increment_Last is
+      begin
+         Last_Val := Last_Val + 1;
+
+         if Last_Val > Max then
+            Reallocate;
+         end if;
+      end Increment_Last;
+
+      ----------
+      -- Init --
+      ----------
+
+      procedure Init is
+         Old_Length : constant Int := Length;
+
+      begin
+         Locked   := False;
+         Last_Val := Min - 1;
+         Max      := Min + (Table_Initial * Table_Factor) - 1;
+         Length   := Max - Min + 1;
+
+         --  If table is same size as before (happens when table is never
+         --  expanded which is a common case), then simply reuse it. Note
+         --  that this also means that an explicit Init call right after
+         --  the implicit one in the package body is harmless.
+
+         if Old_Length = Length then
+            return;
+
+         --  Otherwise we can use Reallocate to get a table of the right size.
+         --  Note that Reallocate works fine to allocate a table of the right
+         --  initial size when it is first allocated.
+
+         else
+            Reallocate;
+         end if;
+      end Init;
+
+      ----------
+      -- Last --
+      ----------
+
+      function Last return Table_Index_Type is
+      begin
+         return Table_Index_Type (Last_Val);
+      end Last;
+
+      ----------------
+      -- Reallocate --
+      ----------------
+
+      procedure Reallocate is
+         New_Size   : Memory.size_t;
+         New_Length : Long_Long_Integer;
+
+      begin
+         if Max < Last_Val then
+            pragma Assert (not Locked);
+
+            --  Make sure that we have at least the initial allocation. This
+            --  is needed in cases where a zero length table is written out.
+
+            Length := Int'Max (Length, Table_Initial);
+
+            --  Now increment table length until it is sufficiently large. Use
+            --  the increment value or 10, which ever is larger (the reason
+            --  for the use of 10 here is to ensure that the table does really
+            --  increase in size (which would not be the case for a table of
+            --  length 10 increased by 3% for instance). Do the intermediate
+            --  calculation in Long_Long_Integer to avoid overflow.
+
+            while Max < Last_Val loop
+               New_Length :=
+                 Long_Long_Integer (Length) *
+                    (100 + Long_Long_Integer (Table_Increment)) / 100;
+               Length := Int'Max (Int (New_Length), Length + 10);
+               Max := Min + Length - 1;
+            end loop;
+
+            if Debug_Flag_D then
+               Write_Str ("--> Allocating new ");
+               Write_Str (Table_Name);
+               Write_Str (" table, size = ");
+               Write_Int (Max - Min + 1);
+               Write_Eol;
+            end if;
+         end if;
+
+         --  Do the intermediate calculation in size_t to avoid signed overflow
+
+         New_Size :=
+           Memory.size_t (Max - Min + 1) *
+                                    (Table_Type'Component_Size / Storage_Unit);
+
+         if Table = null then
+            Table := To_Pointer (Alloc (New_Size));
+
+         elsif New_Size > 0 then
+            Table :=
+              To_Pointer (Realloc (Ptr  => To_Address (Table),
+                                   Size => New_Size));
+         end if;
+
+         if Length /= 0 and then Table = null then
+            Set_Standard_Error;
+            Write_Str ("available memory exhausted");
+            Write_Eol;
+            Set_Standard_Output;
+            raise Unrecoverable_Error;
+         end if;
+      end Reallocate;
+
+      -------------
+      -- Release --
+      -------------
+
+      procedure Release is
+         Extra_Length : Int;
+         Size         : Memory.size_t;
+
+      begin
+         Length := Last_Val - Int (Table_Low_Bound) + 1;
+         Size   := Memory.size_t (Length) *
+                     (Table_Type'Component_Size / Storage_Unit);
+
+         --  If the size of the table exceeds the release threshold then leave
+         --  space to store as many extra elements as 0.1% of the table length.
+
+         if Release_Threshold > 0
+           and then Size > Memory.size_t (Release_Threshold)
+         then
+            Extra_Length := Length / 1000;
+            Length := Length + Extra_Length;
+            Max    := Int (Table_Low_Bound) + Length - 1;
+
+            if Debug_Flag_D then
+               Write_Str ("--> Release_Threshold reached (length=");
+               Write_Int (Int (Size));
+               Write_Str ("): leaving room space for ");
+               Write_Int (Extra_Length);
+               Write_Str (" components");
+               Write_Eol;
+            end if;
+         else
+            Max := Last_Val;
+         end if;
+
+         Reallocate;
+      end Release;
+
+      -------------
+      -- Restore --
+      -------------
+
+      procedure Restore (T : Saved_Table) is
+      begin
+         Free (To_Address (Table));
+         Last_Val := T.Last_Val;
+         Max      := T.Max;
+         Table    := T.Table;
+         Length   := Max - Min + 1;
+      end Restore;
+
+      ----------
+      -- Save --
+      ----------
+
+      function Save return Saved_Table is
+         Res : Saved_Table;
+
+      begin
+         Res.Last_Val := Last_Val;
+         Res.Max      := Max;
+         Res.Table    := Table;
+
+         Table  := null;
+         Length := 0;
+         Init;
+         return Res;
+      end Save;
+
+      --------------
+      -- Set_Item --
+      --------------
+
+      procedure Set_Item
+         (Index : Table_Index_Type;
+          Item  : Table_Component_Type)
+      is
+         --  If Item is a value within the current allocation, and we are going
+         --  to reallocate, then we must preserve an intermediate copy here
+         --  before calling Increment_Last. Otherwise, if Table_Component_Type
+         --  is passed by reference, we are going to end up copying from
+         --  storage that might have been deallocated from Increment_Last
+         --  calling Reallocate.
+
+         subtype Allocated_Table_T is
+           Table_Type (Table'First .. Table_Index_Type (Max + 1));
+         --  A constrained table subtype one element larger than the currently
+         --  allocated table.
+
+         Allocated_Table_Address : constant System.Address :=
+                                     Table.all'Address;
+         --  Used for address clause below (we can't use non-static expression
+         --  Table.all'Address directly in the clause because some older
+         --  versions of the compiler do not allow it).
+
+         Allocated_Table : Allocated_Table_T;
+         pragma Import (Ada, Allocated_Table);
+         pragma Suppress (Range_Check, On => Allocated_Table);
+         for Allocated_Table'Address use Allocated_Table_Address;
+         --  Allocated_Table represents the currently allocated array, plus one
+         --  element (the supplementary element is used to have a convenient
+         --  way of computing the address just past the end of the current
+         --  allocation). Range checks are suppressed because this unit
+         --  uses direct calls to System.Memory for allocation, and this can
+         --  yield misaligned storage (and we cannot rely on the bootstrap
+         --  compiler supporting specifically disabling alignment checks, so we
+         --  need to suppress all range checks). It is safe to suppress this
+         --  check here because we know that a (possibly misaligned) object
+         --  of that type does actually exist at that address.
+         --  ??? We should really improve the allocation circuitry here to
+         --  guarantee proper alignment.
+
+         Need_Realloc : constant Boolean := Int (Index) > Max;
+         --  True if this operation requires storage reallocation (which may
+         --  involve moving table contents around).
+
+      begin
+         --  If we're going to reallocate, check whether Item references an
+         --  element of the currently allocated table.
+
+         if Need_Realloc
+           and then Allocated_Table'Address <= Item'Address
+           and then Item'Address <
+                      Allocated_Table (Table_Index_Type (Max + 1))'Address
+         then
+            --  If so, save a copy on the stack because Increment_Last will
+            --  reallocate storage and might deallocate the current table.
+
+            declare
+               Item_Copy : constant Table_Component_Type := Item;
+            begin
+               Set_Last (Index);
+               Table (Index) := Item_Copy;
+            end;
+
+         else
+            --  Here we know that either we won't reallocate (case of Index <
+            --  Max) or that Item is not in the currently allocated table.
+
+            if Int (Index) > Last_Val then
+               Set_Last (Index);
+            end if;
+
+            Table (Index) := Item;
+         end if;
+      end Set_Item;
+
+      --------------
+      -- Set_Last --
+      --------------
+
+      procedure Set_Last (New_Val : Table_Index_Type) is
+      begin
+         if Int (New_Val) < Last_Val then
+            Last_Val := Int (New_Val);
+
+         else
+            Last_Val := Int (New_Val);
+
+            if Last_Val > Max then
+               Reallocate;
+            end if;
+         end if;
+      end Set_Last;
+
       ----------------------------
       -- Tree_Get_Table_Address --
       ----------------------------
 
       function Tree_Get_Table_Address return Address is
       begin
-         if Is_Empty then
+         if Length = 0 then
             return Null_Address;
          else
             return Table (First)'Address;
@@ -65,15 +418,15 @@
       --  does an implicit Release.
 
       procedure Tree_Read is
-         Last : Int;
       begin
-         Init;
-         Tree_Read_Int (Last);
-         Set_Last (Table_Last_Type (Last));
+         Tree_Read_Int (Max);
+         Last_Val := Max;
+         Length := Max - Min + 1;
+         Reallocate;
 
          Tree_Read_Data
            (Tree_Get_Table_Address,
-             (Last - Int (First) + 1) *
+             (Last_Val - Int (First) + 1) *
 
                --  Note the importance of parenthesizing the following division
                --  to avoid the possibility of intermediate overflow.
@@ -93,9 +446,11 @@
          Tree_Write_Int (Int (Last));
          Tree_Write_Data
            (Tree_Get_Table_Address,
-            (Int (Last - First) + 1) *
+            (Last_Val - Int (First) + 1) *
               (Table_Type'Component_Size / Storage_Unit));
       end Tree_Write;
 
+   begin
+      Init;
    end Table;
 end Table;
Index: table.ads
===================================================================
--- table.ads	(revision 251753)
+++ table.ads	(working copy)
@@ -29,20 +29,19 @@
 --                                                                          --
 ------------------------------------------------------------------------------
 
---  This package is a wrapper for GNAT.Table, for use in the compiler front
---  end. It adds the Tree_Write/Tree_Read functionality; everything else is
---  just a renaming of GNAT.Table. See GNAT.Table (g-table.ads) and
---  GNAT.Dynamic_Tables (g-dyntab.ads) for documentation.
+--  This package provides an implementation of dynamically resizable one
+--  dimensional arrays. The idea is to mimic the normal Ada semantics for
+--  arrays as closely as possible with the one additional capability of
+--  dynamically modifying the value of the Last attribute.
 
---  Note that these three interfaces should remain synchronized to keep as much
---  coherency as possible among these related units:
---
---     GNAT.Dynamic_Tables
---     GNAT.Table
---     Table (the compiler unit)
+--  This package uses a very efficient memory management scheme and any
+--  change must be carefully evaluated on compilation of real software.
 
+--  Note that this interface should remain synchronized with those in
+--  GNAT.Table and GNAT.Dynamic_Tables to keep coherency between these
+--  three related units.
+
 with Types; use Types;
-with GNAT.Table;
 
 package Table is
    pragma Elaborate_Body;
@@ -51,66 +50,199 @@
       type Table_Component_Type is private;
       type Table_Index_Type     is range <>;
 
-      Table_Low_Bound   : Table_Index_Type := Table_Index_Type'First;
-      Table_Initial     : Pos := 8;
-      Table_Increment   : Nat := 100;
-      Table_Name        : String; -- for debugging printouts
+      Table_Low_Bound   : Table_Index_Type;
+      Table_Initial     : Pos;
+      Table_Increment   : Nat;
+      Table_Name        : String;
       Release_Threshold : Nat := 0;
 
    package Table is
 
-      package Tab is new GNAT.Table
-        (Table_Component_Type,
-         Table_Index_Type,
-         Table_Low_Bound,
-         Positive (Table_Initial),
-         Natural (Table_Increment),
-         Table_Name,
-         Natural (Release_Threshold));
+      --  Table_Component_Type and Table_Index_Type specify the type of the
+      --  array, Table_Low_Bound is the lower bound. Table_Index_Type must be
+      --  an integer type. The effect is roughly to declare:
 
-      subtype Valid_Table_Index_Type is Tab.Valid_Table_Index_Type;
-      subtype Table_Last_Type is Tab.Table_Last_Type;
-      subtype Table_Type is Tab.Table_Type;
+      --    Table : array (Table_Index_Type range Table_Low_Bound .. <>)
+      --                       of Table_Component_Type;
 
-      subtype Table_Ptr is Tab.Table_Ptr;
+      --    Note: since the upper bound can be one less than the lower
+      --    bound for an empty array, the table index type must be able
+      --    to cover this range, e.g. if the lower bound is 1, then the
+      --    Table_Index_Type should be Natural rather than Positive.
 
-      Table : Table_Ptr renames Tab.Table;
+      --  Table_Component_Type may be any Ada type, except that controlled
+      --  types are not supported. Note however that default initialization
+      --  will NOT occur for array components.
 
-      Locked : Boolean renames Tab.Locked;
+      --  The Table_Initial values controls the allocation of the table when
+      --  it is first allocated, either by default, or by an explicit Init
+      --  call. The value used is Opt.Table_Factor * Table_Initial.
 
-      function Is_Empty return Boolean renames Tab.Is_Empty;
+      --  The Table_Increment value controls the amount of increase, if the
+      --  table has to be increased in size. The value given is a percentage
+      --  value (e.g. 100 = increase table size by 100%, i.e. double it).
 
-      procedure Init renames Tab.Init;
+      --  The Table_Name parameter is simply use in debug output messages it
+      --  has no other usage, and is not referenced in non-debugging mode.
 
-      function First return Table_Index_Type renames Tab.First;
-      function Last return Table_Last_Type renames Tab.Last;
+      --  The Last and Set_Last subprograms provide control over the current
+      --  logical allocation. They are quite efficient, so they can be used
+      --  freely (expensive reallocation occurs only at major granularity
+      --  chunks controlled by the allocation parameters).
 
-      procedure Release renames Tab.Release;
+      --  Note: We do not make the table components aliased, since this would
+      --  restrict the use of table for discriminated types. If it is necessary
+      --  to take the access of a table element, use Unrestricted_Access.
 
-      procedure Free renames Tab.Free;
+      --  WARNING: On HPPA, the virtual addressing approach used in this unit
+      --  is incompatible with the indexing instructions on the HPPA. So when
+      --  using this unit, compile your application with -mdisable-indexing.
 
-      procedure Set_Last (New_Val : Table_Last_Type) renames Tab.Set_Last;
+      --  WARNING: If the table is reallocated, then the address of all its
+      --  components will change. So do not capture the address of an element
+      --  and then use the address later after the table may be reallocated.
+      --  One tricky case of this is passing an element of the table to a
+      --  subprogram by reference where the table gets reallocated during
+      --  the execution of the subprogram. The best rule to follow is never
+      --  to pass a table element as a parameter except for the case of IN
+      --  mode parameters with scalar values.
 
-      procedure Increment_Last renames Tab.Increment_Last;
-      procedure Decrement_Last renames Tab.Decrement_Last;
+      type Table_Type is
+        array (Table_Index_Type range <>) of Table_Component_Type;
 
-      procedure Append (New_Val : Table_Component_Type) renames Tab.Append;
-      procedure Append_All (New_Vals : Table_Type) renames Tab.Append_All;
+      subtype Big_Table_Type is
+        Table_Type (Table_Low_Bound .. Table_Index_Type'Last);
+      --  We work with pointers to a bogus array type that is constrained
+      --  with the maximum possible range bound. This means that the pointer
+      --  is a thin pointer, which is more efficient. Since subscript checks
+      --  in any case must be on the logical, rather than physical bounds,
+      --  safety is not compromised by this approach.
 
+      type Table_Ptr is access all Big_Table_Type;
+      for Table_Ptr'Storage_Size use 0;
+      --  The table is actually represented as a pointer to allow reallocation
+
+      Table : aliased Table_Ptr := null;
+      --  The table itself. The lower bound is the value of Low_Bound.
+      --  Logically the upper bound is the current value of Last (although
+      --  the actual size of the allocated table may be larger than this).
+      --  The program may only access and modify Table entries in the range
+      --  First .. Last.
+
+      Locked : Boolean := False;
+      --  Table expansion is permitted only if this switch is set to False. A
+      --  client may set Locked to True, in which case any attempt to expand
+      --  the table will cause an assertion failure. Note that while a table
+      --  is locked, its address in memory remains fixed and unchanging. This
+      --  feature is used to control table expansion during Gigi processing.
+      --  Gigi assumes that tables other than the Uint and Ureal tables do
+      --  not move during processing, which means that they cannot be expanded.
+      --  The Locked flag is used to enforce this restriction.
+
+      procedure Init;
+      --  This procedure allocates a new table of size Initial (freeing any
+      --  previously allocated larger table). It is not necessary to call
+      --  Init when a table is first instantiated (since the instantiation does
+      --  the same initialization steps). However, it is harmless to do so, and
+      --  Init is convenient in reestablishing a table for new use.
+
+      function Last return Table_Index_Type;
+      pragma Inline (Last);
+      --  Returns the current value of the last used entry in the table, which
+      --  can then be used as a subscript for Table. Note that the only way to
+      --  modify Last is to call the Set_Last procedure. Last must always be
+      --  used to determine the logically last entry.
+
+      procedure Release;
+      --  Storage is allocated in chunks according to the values given in the
+      --  Initial and Increment parameters. If Release_Threshold is 0 or the
+      --  length of the table does not exceed this threshold then a call to
+      --  Release releases all storage that is allocated, but is not logically
+      --  part of the current array value; otherwise the call to Release leaves
+      --  the current array value plus 0.1% of the current table length free
+      --  elements located at the end of the table (this parameter facilitates
+      --  reopening large tables and adding a few elements without allocating a
+      --  chunk of memory). In both cases current array values are not affected
+      --  by this call.
+
+      procedure Free;
+      --  Free all allocated memory for the table. A call to init is required
+      --  before any use of this table after calling Free.
+
+      First : constant Table_Index_Type := Table_Low_Bound;
+      --  Export First as synonym for Low_Bound (parallel with use of Last)
+
+      procedure Set_Last (New_Val : Table_Index_Type);
+      pragma Inline (Set_Last);
+      --  This procedure sets Last to the indicated value. If necessary the
+      --  table is reallocated to accommodate the new value (i.e. on return
+      --  the allocated table has an upper bound of at least Last). If Set_Last
+      --  reduces the size of the table, then logically entries are removed
+      --  from the table. If Set_Last increases the size of the table, then
+      --  new entries are logically added to the table.
+
+      procedure Increment_Last;
+      pragma Inline (Increment_Last);
+      --  Adds 1 to Last (same as Set_Last (Last + 1)
+
+      procedure Decrement_Last;
+      pragma Inline (Decrement_Last);
+      --  Subtracts 1 from Last (same as Set_Last (Last - 1)
+
+      procedure Append (New_Val : Table_Component_Type);
+      pragma Inline (Append);
+      --  Equivalent to:
+      --    x.Increment_Last;
+      --    x.Table (x.Last) := New_Val;
+      --  i.e. the table size is increased by one, and the given new item
+      --  stored in the newly created table element.
+
+      procedure Append_All (New_Vals : Table_Type);
+      --  Appends all components of New_Vals
+
       procedure Set_Item
-        (Index : Valid_Table_Index_Type;
-         Item  : Table_Component_Type) renames Tab.Set_Item;
+        (Index : Table_Index_Type;
+         Item  : Table_Component_Type);
+      pragma Inline (Set_Item);
+      --  Put Item in the table at position Index. The table is expanded if
+      --  current table length is less than Index and in that case Last is set
+      --  to Index. Item will replace any value already present in the table
+      --  at this position.
 
-      subtype Saved_Table is Tab.Saved_Table;
-      function Save return Saved_Table renames Tab.Save;
-      procedure Restore (T : in out Saved_Table) renames Tab.Restore;
+      type Saved_Table is private;
+      --  Type used for Save/Restore subprograms
 
+      function Save return Saved_Table;
+      --  Resets table to empty, but saves old contents of table in returned
+      --  value, for possible later restoration by a call to Restore.
+
+      procedure Restore (T : Saved_Table);
+      --  Given a Saved_Table value returned by a prior call to Save, restores
+      --  the table to the state it was in at the time of the Save call.
+
       procedure Tree_Write;
       --  Writes out contents of table using Tree_IO
 
       procedure Tree_Read;
       --  Initializes table by reading contents previously written with the
-      --  Tree_Write call, also using Tree_IO.
+      --  Tree_Write call (also using Tree_IO).
 
+   private
+
+      Last_Val : Int;
+      --  Current value of Last. Note that we declare this in the private part
+      --  because we don't want the client to modify Last except through one of
+      --  the official interfaces (since a modification to Last may require a
+      --  reallocation of the table).
+
+      Max : Int;
+      --  Subscript of the maximum entry in the currently allocated table
+
+      type Saved_Table is record
+         Last_Val : Int;
+         Max      : Int;
+         Table    : Table_Ptr;
+      end record;
+
    end Table;
 end Table;
Index: uintp.h
===================================================================
--- uintp.h	(revision 251753)
+++ uintp.h	(working copy)
@@ -101,11 +101,11 @@
    the integer value itself.  The origin of the Uints_Ptr table is adjusted so
    that a Uint value of Uint_Bias indexes the first element.  */
 
-#define Uints_Ptr (uintp__uints__tab__the_instance - Uint_Table_Start)
-extern struct Uint_Entry *uintp__uints__tab__the_instance;
+#define Uints_Ptr (uintp__uints__table - Uint_Table_Start)
+extern struct Uint_Entry *uintp__uints__table;
 
-#define Udigits_Ptr uintp__udigits__tab__the_instance
-extern int *uintp__udigits__tab__the_instance;
+#define Udigits_Ptr uintp__udigits__table
+extern int *uintp__udigits__table;
 
 #ifdef __cplusplus
 }
