OSDN Git Service

* doc/install.texi (Specific, mips-sgi-irix5): Document IRIX 5
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_ch7.adb
index 5ffa863..27505f2 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 1992-2004, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
--- ware  Foundation;  either version 2,  or (at your option) any later ver- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
 -- for  more details.  You should have  received  a copy of the GNU General --
--- Public License  distributed with GNAT;  see file COPYING.  If not, write --
--- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
--- MA 02111-1307, USA.                                                      --
+-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license.          --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
@@ -26,8 +25,8 @@
 
 --  This package contains the routines to process package specifications and
 --  bodies. The most important semantic aspects of package processing are the
---  handling of private and full declarations, and the construction of
---  dispatch tables for tagged types.
+--  handling of private and full declarations, and the construction of dispatch
+--  tables for tagged types.
 
 with Atree;    use Atree;
 with Debug;    use Debug;
@@ -35,6 +34,7 @@ with Einfo;    use Einfo;
 with Elists;   use Elists;
 with Errout;   use Errout;
 with Exp_Disp; use Exp_Disp;
+with Exp_Dist; use Exp_Dist;
 with Exp_Dbug; use Exp_Dbug;
 with Lib;      use Lib;
 with Lib.Xref; use Lib.Xref;
@@ -44,12 +44,15 @@ with Nlists;   use Nlists;
 with Opt;      use Opt;
 with Output;   use Output;
 with Sem;      use Sem;
+with Sem_Aux;  use Sem_Aux;
 with Sem_Cat;  use Sem_Cat;
 with Sem_Ch3;  use Sem_Ch3;
 with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
 with Sem_Ch10; use Sem_Ch10;
 with Sem_Ch12; use Sem_Ch12;
+with Sem_Disp; use Sem_Disp;
+with Sem_Prag; use Sem_Prag;
 with Sem_Util; use Sem_Util;
 with Sem_Warn; use Sem_Warn;
 with Snames;   use Snames;
@@ -57,6 +60,7 @@ with Stand;    use Stand;
 with Sinfo;    use Sinfo;
 with Sinput;   use Sinput;
 with Style;
+with Uintp;    use Uintp;
 
 package body Sem_Ch7 is
 
@@ -86,42 +90,86 @@ package body Sem_Ch7 is
    -- Local Subprograms --
    -----------------------
 
+   procedure Analyze_Package_Body_Helper (N : Node_Id);
+   --  Does all the real work of Analyze_Package_Body
+
+   procedure Check_Anonymous_Access_Types
+     (Spec_Id : Entity_Id;
+      P_Body  : Node_Id);
+   --  If the spec of a package has a limited_with_clause, it may declare
+   --  anonymous access types whose designated type is a limited view, such an
+   --  anonymous access return type for a function. This access type cannot be
+   --  elaborated in the spec itself, but it may need an itype reference if it
+   --  is used within a nested scope. In that case the itype reference is
+   --  created at the beginning of the corresponding package body and inserted
+   --  before other body declarations.
+
    procedure Install_Package_Entity (Id : Entity_Id);
-   --  Basic procedure for the previous two. Places one entity on its
-   --  visibility chain, and recurses on the visible part if the entity
-   --  is an inner package.
+   --  Supporting procedure for Install_{Visible,Private}_Declarations. Places
+   --  one entity on its visibility chain, and recurses on the visible part if
+   --  the entity is an inner package.
 
    function Is_Private_Base_Type (E : Entity_Id) return Boolean;
    --  True for a private type that is not a subtype
 
    function Is_Visible_Dependent (Dep : Entity_Id) return Boolean;
-   --  If the private dependent is a private type whose full view is
-   --  derived from the parent type, its full properties are revealed
-   --  only if we are in the immediate scope of the private dependent.
-   --  Should this predicate be tightened further???
+   --  If the private dependent is a private type whose full view is derived
+   --  from the parent type, its full properties are revealed only if we are in
+   --  the immediate scope of the private dependent. Should this predicate be
+   --  tightened further???
 
    procedure Declare_Inherited_Private_Subprograms (Id : Entity_Id);
-   --  Called upon entering the private part of a public child package
-   --  and the body of a nested package, to potentially declare certain
-   --  inherited subprograms that were inherited by types in the visible
-   --  part, but whose declaration was deferred because the parent
-   --  operation was private and not visible at that point. These
-   --  subprograms are located by traversing the visible part declarations
-   --  looking for non-private type extensions and then examining each of
-   --  the primitive operations of such types to find those that were
-   --  inherited but declared with a special internal name. Each such
-   --  operation is now declared as an operation with a normal name (using
-   --  the name of the parent operation) and replaces the previous implicit
-   --  operation in the primitive operations list of the type. If the
-   --  inherited private operation has been overridden, then it's
-   --  replaced by the overriding operation.
+   --  Called upon entering the private part of a public child package and the
+   --  body of a nested package, to potentially declare certain inherited
+   --  subprograms that were inherited by types in the visible part, but whose
+   --  declaration was deferred because the parent operation was private and
+   --  not visible at that point. These subprograms are located by traversing
+   --  the visible part declarations looking for non-private type extensions
+   --  and then examining each of the primitive operations of such types to
+   --  find those that were inherited but declared with a special internal
+   --  name. Each such operation is now declared as an operation with a normal
+   --  name (using the name of the parent operation) and replaces the previous
+   --  implicit operation in the primitive operations list of the type. If the
+   --  inherited private operation has been overridden, then it's replaced by
+   --  the overriding operation.
 
    --------------------------
    -- Analyze_Package_Body --
    --------------------------
 
    procedure Analyze_Package_Body (N : Node_Id) is
-      Loc              : constant Source_Ptr := Sloc (N);
+      Loc : constant Source_Ptr := Sloc (N);
+
+   begin
+      if Debug_Flag_C then
+         Write_Str ("==> package body ");
+         Write_Name (Chars (Defining_Entity (N)));
+         Write_Str (" from ");
+         Write_Location (Loc);
+         Write_Eol;
+         Indent;
+      end if;
+
+      --  The real work is split out into the helper, so it can do "return;"
+      --  without skipping the debug output.
+
+      Analyze_Package_Body_Helper (N);
+
+      if Debug_Flag_C then
+         Outdent;
+         Write_Str ("<== package body ");
+         Write_Name (Chars (Defining_Entity (N)));
+         Write_Str (" from ");
+         Write_Location (Loc);
+         Write_Eol;
+      end if;
+   end Analyze_Package_Body;
+
+   ---------------------------------
+   -- Analyze_Package_Body_Helper --
+   ---------------------------------
+
+   procedure Analyze_Package_Body_Helper (N : Node_Id) is
       HSS              : Node_Id;
       Body_Id          : Entity_Id;
       Spec_Id          : Entity_Id;
@@ -130,10 +178,10 @@ package body Sem_Ch7 is
       Pack_Decl        : Node_Id;
 
       procedure Install_Composite_Operations (P : Entity_Id);
-      --  Composite types declared in the current scope may depend on
-      --  types that were private at the point of declaration, and whose
-      --  full view is now in  scope. Indicate that the corresponding
-      --  operations on the composite type are available.
+      --  Composite types declared in the current scope may depend on types
+      --  that were private at the point of declaration, and whose full view
+      --  is now in scope. Indicate that the corresponding operations on the
+      --  composite type are available.
 
       ----------------------------------
       -- Install_Composite_Operations --
@@ -144,9 +192,7 @@ package body Sem_Ch7 is
 
       begin
          Id := First_Entity (P);
-
          while Present (Id) loop
-
             if Is_Type (Id)
               and then (Is_Limited_Composite (Id)
                          or else Is_Private_Composite (Id))
@@ -160,33 +206,25 @@ package body Sem_Ch7 is
          end loop;
       end Install_Composite_Operations;
 
-   --  Start of processing for Analyze_Package_Body
+   --  Start of processing for Analyze_Package_Body_Helper
 
    begin
-      --  Find corresponding package specification, and establish the
-      --  current scope. The visible defining entity for the package is the
-      --  defining occurrence in the spec. On exit from the package body, all
-      --  body declarations are attached to the defining entity for the body,
-      --  but the later is never used for name resolution. In this fashion
-      --  there is only one visible entity that denotes the package.
-
-      if Debug_Flag_C then
-         Write_Str ("====  Compiling package body ");
-         Write_Name (Chars (Defining_Entity (N)));
-         Write_Str (" from ");
-         Write_Location (Loc);
-         Write_Eol;
-      end if;
+      --  Find corresponding package specification, and establish the current
+      --  scope. The visible defining entity for the package is the defining
+      --  occurrence in the spec. On exit from the package body, all body
+      --  declarations are attached to the defining entity for the body, but
+      --  the later is never used for name resolution. In this fashion there
+      --  is only one visible entity that denotes the package.
 
-      --  Set Body_Id. Note that this Will be reset to point to the
-      --  generic copy later on in the generic case.
+      --  Set Body_Id. Note that this Will be reset to point to the generic
+      --  copy later on in the generic case.
 
       Body_Id := Defining_Entity (N);
 
       if Present (Corresponding_Spec (N)) then
 
-         --  Body is body of package instantiation. Corresponding spec
-         --  has already been set.
+         --  Body is body of package instantiation. Corresponding spec has
+         --  already been set.
 
          Spec_Id := Corresponding_Spec (N);
          Pack_Decl := Unit_Declaration_Node (Spec_Id);
@@ -195,7 +233,7 @@ package body Sem_Ch7 is
          Spec_Id := Current_Entity_In_Scope (Defining_Entity (N));
 
          if Present (Spec_Id)
-           and then Is_Package (Spec_Id)
+           and then Is_Package_Or_Generic_Package (Spec_Id)
          then
             Pack_Decl := Unit_Declaration_Node (Spec_Id);
 
@@ -213,7 +251,7 @@ package body Sem_Ch7 is
             return;
          end if;
 
-         if Is_Package (Spec_Id)
+         if Is_Package_Or_Generic_Package (Spec_Id)
            and then
              (Scope (Spec_Id) = Standard_Standard
                or else Is_Child_Unit (Spec_Id))
@@ -245,35 +283,36 @@ package body Sem_Ch7 is
 
       if Ekind (Spec_Id) = E_Generic_Package then
 
-         --  Disable expansion and perform semantic analysis on copy.
-         --  The unannotated body will be used in all instantiations.
+         --  Disable expansion and perform semantic analysis on copy. The
+         --  unannotated body will be used in all instantiations.
 
          Body_Id := Defining_Entity (N);
          Set_Ekind (Body_Id, E_Package_Body);
          Set_Scope (Body_Id, Scope (Spec_Id));
+         Set_Is_Obsolescent (Body_Id, Is_Obsolescent (Spec_Id));
          Set_Body_Entity (Spec_Id, Body_Id);
          Set_Spec_Entity (Body_Id, Spec_Id);
 
          New_N := Copy_Generic_Node (N, Empty, Instantiating => False);
          Rewrite (N, New_N);
 
-         --  Update Body_Id to point to the copied node for the remainder
-         --  of the processing.
+         --  Update Body_Id to point to the copied node for the remainder of
+         --  the processing.
 
          Body_Id := Defining_Entity (N);
          Start_Generic;
       end if;
 
       --  The Body_Id is that of the copied node in the generic case, the
-      --  current node otherwise. Note that N was rewritten above, so we
-      --  must be sure to get the latest Body_Id value.
+      --  current node otherwise. Note that N was rewritten above, so we must
+      --  be sure to get the latest Body_Id value.
 
       Set_Ekind (Body_Id, E_Package_Body);
       Set_Body_Entity (Spec_Id, Body_Id);
       Set_Spec_Entity (Body_Id, Spec_Id);
 
-      --  Defining name for the package body is not a visible entity: Only
-      --  the defining name for the declaration is visible.
+      --  Defining name for the package body is not a visible entity: Only the
+      --  defining name for the declaration is visible.
 
       Set_Etype (Body_Id, Standard_Void_Type);
       Set_Scope (Body_Id, Scope (Spec_Id));
@@ -294,7 +333,7 @@ package body Sem_Ch7 is
       Set_Has_Completion (Spec_Id);
       Last_Spec_Entity := Last_Entity (Spec_Id);
 
-      New_Scope (Spec_Id);
+      Push_Scope (Spec_Id);
 
       Set_Categorization_From_Pragmas (N);
 
@@ -303,6 +342,8 @@ package body Sem_Ch7 is
       Install_Private_With_Clauses (Spec_Id);
       Install_Composite_Operations (Spec_Id);
 
+      Check_Anonymous_Access_Types (Spec_Id, N);
+
       if Ekind (Spec_Id) = E_Generic_Package then
          Set_Use (Generic_Formal_Declarations (Pack_Decl));
       end if;
@@ -310,9 +351,9 @@ package body Sem_Ch7 is
       Set_Use (Visible_Declarations (Specification (Pack_Decl)));
       Set_Use (Private_Declarations (Specification (Pack_Decl)));
 
-      --  This is a nested package, so it may be necessary to declare
-      --  certain inherited subprograms that are not yet visible because
-      --  the parent type's subprograms are now visible.
+      --  This is a nested package, so it may be necessary to declare certain
+      --  inherited subprograms that are not yet visible because the parent
+      --  type's subprograms are now visible.
 
       if Ekind (Scope (Spec_Id)) = E_Package
         and then Scope (Spec_Id) /= Standard_Standard
@@ -322,6 +363,18 @@ package body Sem_Ch7 is
 
       if Present (Declarations (N)) then
          Analyze_Declarations (Declarations (N));
+         Inspect_Deferred_Constant_Completion (Declarations (N));
+      end if;
+
+      --  Analyze_Declarations has caused freezing of all types. Now generate
+      --  bodies for RACW primitives and stream attributes, if any.
+
+      if Ekind (Spec_Id) = E_Package and then Has_RACW (Spec_Id) then
+
+         --  Attach subprogram bodies to support RACWs declared in spec
+
+         Append_RACW_Bodies (Declarations (N), Spec_Id);
+         Analyze_List (Declarations (N));
       end if;
 
       HSS := Handled_Statement_Sequence (N);
@@ -345,22 +398,22 @@ package body Sem_Ch7 is
 
       Generate_Reference (Spec_Id, Body_Id, 'b', Set_Ref => False);
 
-      --  For a generic package, collect global references and mark
-      --  them on the original body so that they are not resolved
-      --  again at the point of instantiation.
+      --  For a generic package, collect global references and mark them on
+      --  the original body so that they are not resolved again at the point
+      --  of instantiation.
 
       if Ekind (Spec_Id) /= E_Package then
          Save_Global_References (Original_Node (N));
          End_Generic;
       end if;
 
-      --  The entities of the package body have so far been chained onto
-      --  the declaration chain for the spec. That's been fine while we
-      --  were in the body, since we wanted them to be visible, but now
-      --  that we are leaving the package body, they are no longer visible,
-      --  so we remove them from the entity chain of the package spec entity,
-      --  and copy them to the entity chain of the package body entity, where
-      --  they will never again be visible.
+      --  The entities of the package body have so far been chained onto the
+      --  declaration chain for the spec. That's been fine while we were in the
+      --  body, since we wanted them to be visible, but now that we are leaving
+      --  the package body, they are no longer visible, so we remove them from
+      --  the entity chain of the package spec entity, and copy them to the
+      --  entity chain of the package body entity, where they will never again
+      --  be visible.
 
       if Present (Last_Spec_Entity) then
          Set_First_Entity (Body_Id, Next_Entity (Last_Spec_Entity));
@@ -384,15 +437,13 @@ package body Sem_Ch7 is
 
       begin
          E := First_Entity (Body_Id);
-
          while Present (E) loop
             Set_Is_Immediately_Visible (E, False);
             Set_Is_Potentially_Use_Visible (E, False);
             Set_Is_Hidden (E);
 
-            --  Child units may appear on the entity list (for example if
-            --  they appear in the context of a subunit) but they are not
-            --  body entities.
+            --  Child units may appear on the entity list (e.g. if they appear
+            --  in the context of a subunit) but they are not body entities.
 
             if not Is_Child_Unit (E) then
                Set_Is_Package_Body_Entity (E);
@@ -418,9 +469,9 @@ package body Sem_Ch7 is
       --  following loop runs backwards from the end of the entities of the
       --  package body making these entities invisible until we reach a
       --  referencer, i.e. a declaration that could reference a previous
-      --  declaration, a generic body or an inlined body, or a stub (which
-      --  may contain either of these). This is of course an approximation,
-      --  but it is conservative and definitely correct.
+      --  declaration, a generic body or an inlined body, or a stub (which may
+      --  contain either of these). This is of course an approximation, but it
+      --  is conservative and definitely correct.
 
       --  We only do this at the outer (library) level non-generic packages.
       --  The reason is simply to cut down on the number of external symbols
@@ -438,16 +489,15 @@ package body Sem_Ch7 is
                Outer : Boolean)
                return  Boolean;
             --  Traverse the given list of declarations in reverse order.
-            --  Return True as soon as a referencer is reached. Return
-            --  False if none is found. The Outer parameter is True for
-            --  the outer level call, and False for inner level calls for
-            --  nested packages. If Outer is True, then any entities up
-            --  to the point of hitting a referencer get their Is_Public
-            --  flag cleared, so that the entities will be treated as
-            --  static entities in the C sense, and need not have fully
-            --  qualified names. For inner levels, we need all names to
-            --  be fully qualified to deal with the same name appearing
-            --  in parallel packages (right now this is tied to their
+            --  Return True as soon as a referencer is reached. Return False if
+            --  none is found. The Outer parameter is True for the outer level
+            --  call, and False for inner level calls for nested packages. If
+            --  Outer is True, then any entities up to the point of hitting a
+            --  referencer get their Is_Public flag cleared, so that the
+            --  entities will be treated as static entities in the C sense, and
+            --  need not have fully qualified names. For inner levels, we need
+            --  all names to be fully qualified to deal with the same name
+            --  appearing in parallel packages (right now this is tied to their
             --  being external).
 
             --------------------
@@ -470,7 +520,6 @@ package body Sem_Ch7 is
                end if;
 
                D := Last (L);
-
                while Present (D) loop
                   K := Nkind (D);
 
@@ -487,10 +536,10 @@ package body Sem_Ch7 is
 
                         --  Note that we test Has_Pragma_Inline here rather
                         --  than Is_Inlined. We are compiling this for a
-                        --  client, and it is the client who will decide
-                        --  if actual inlining should occur, so we need to
-                        --  assume that the procedure could be inlined for
-                        --  the purpose of accessing global entities.
+                        --  client, and it is the client who will decide if
+                        --  actual inlining should occur, so we need to assume
+                        --  that the procedure could be inlined for the purpose
+                        --  of accessing global entities.
 
                         if Has_Pragma_Inline (E) then
                            return True;
@@ -517,20 +566,19 @@ package body Sem_Ch7 is
                   then
                      E := Corresponding_Spec (D);
 
-                     --  Generic package body is a referencer. It would
-                     --  seem that we only have to consider generics that
-                     --  can be exported, i.e. where the corresponding spec
-                     --  is the spec of the current package, but because of
-                     --  nested instantiations, a fully private generic
-                     --  body may export other private body entities.
+                     --  Generic package body is a referencer. It would seem
+                     --  that we only have to consider generics that can be
+                     --  exported, i.e. where the corresponding spec is the
+                     --  spec of the current package, but because of nested
+                     --  instantiations, a fully private generic body may
+                     --  export other private body entities.
 
                      if Is_Generic_Unit (E) then
                         return True;
 
-                     --  For non-generic package body, recurse into body
-                     --  unless this is an instance, we ignore instances
-                     --  since they cannot have references that affect
-                     --  outer entities.
+                     --  For non-generic package body, recurse into body unless
+                     --  this is an instance, we ignore instances since they
+                     --  cannot have references that affect outer entities.
 
                      elsif not Is_Generic_Instance (E) then
                         if Has_Referencer
@@ -558,14 +606,14 @@ package body Sem_Ch7 is
                         end if;
                      end if;
 
-                  --  Objects and exceptions need not be public if we have
-                  --  not encountered a referencer so far. We only reset
-                  --  the flag for outer level entities that are not
-                  --  imported/exported, and which have no interface name.
+                  --  Objects and exceptions need not be public if we have not
+                  --  encountered a referencer so far. We only reset the flag
+                  --  for outer level entities that are not imported/exported,
+                  --  and which have no interface name.
 
-                  elsif K = N_Object_Declaration
-                    or else K = N_Exception_Declaration
-                    or else K = N_Subprogram_Declaration
+                  elsif Nkind_In (K, N_Object_Declaration,
+                                     N_Exception_Declaration,
+                                     N_Subprogram_Declaration)
                   then
                      E := Defining_Entity (D);
 
@@ -598,10 +646,10 @@ package body Sem_Ch7 is
       end if;
 
       --  If expander is not active, then here is where we turn off the
-      --  In_Package_Body flag, otherwise it is turned off at the end of
-      --  the corresponding expansion routine. If this is an instance body,
-      --  we need to qualify names of local entities, because the body may
-      --  have been compiled as a preliminary to another instantiation.
+      --  In_Package_Body flag, otherwise it is turned off at the end of the
+      --  corresponding expansion routine. If this is an instance body, we need
+      --  to qualify names of local entities, because the body may have been
+      --  compiled as a preliminary to another instantiation.
 
       if not Expander_Active then
          Set_In_Package_Body (Spec_Id, False);
@@ -612,7 +660,7 @@ package body Sem_Ch7 is
             Qualify_Entity_Names (N);
          end if;
       end if;
-   end Analyze_Package_Body;
+   end Analyze_Package_Body_Helper;
 
    ---------------------------------
    -- Analyze_Package_Declaration --
@@ -620,53 +668,107 @@ package body Sem_Ch7 is
 
    procedure Analyze_Package_Declaration (N : Node_Id) is
       Id : constant Node_Id := Defining_Entity (N);
+
       PF : Boolean;
+      --  True when in the context of a declared pure library unit
+
+      Body_Required : Boolean;
+      --  True when this package declaration requires a corresponding body
+
+      Comp_Unit : Boolean;
+      --  True when this package declaration is not a nested declaration
 
    begin
+      --  Ada 2005 (AI-217): Check if the package has been erroneously named
+      --  in a limited-with clause of its own context. In this case the error
+      --  has been previously notified by Analyze_Context.
+
+      --     limited with Pkg; -- ERROR
+      --     package Pkg is ...
+
+      if From_With_Type (Id) then
+         return;
+      end if;
+
+      if Debug_Flag_C then
+         Write_Str ("==> package spec ");
+         Write_Name (Chars (Id));
+         Write_Str (" from ");
+         Write_Location (Sloc (N));
+         Write_Eol;
+         Indent;
+      end if;
+
       Generate_Definition (Id);
       Enter_Name (Id);
       Set_Ekind (Id, E_Package);
       Set_Etype (Id, Standard_Void_Type);
 
-      New_Scope (Id);
+      Push_Scope (Id);
 
       PF := Is_Pure (Enclosing_Lib_Unit_Entity);
       Set_Is_Pure (Id, PF);
 
       Set_Categorization_From_Pragmas (N);
 
-      if Debug_Flag_C then
-         Write_Str ("====  Compiling package spec ");
-         Write_Name (Chars (Id));
-         Write_Str (" from ");
-         Write_Location (Sloc (N));
-         Write_Eol;
-      end if;
-
       Analyze (Specification (N));
       Validate_Categorization_Dependency (N, Id);
-      End_Package_Scope (Id);
 
-      --  For a compilation unit, indicate whether it needs a body, and
-      --  whether elaboration warnings may be meaningful on it.
+      Body_Required := Unit_Requires_Body (Id);
 
-      if Nkind (Parent (N)) = N_Compilation_Unit then
-         Set_Body_Required (Parent (N), Unit_Requires_Body (Id));
+      --  When this spec does not require an explicit body, we know that there
+      --  are no entities requiring completion in the language sense; we call
+      --  Check_Completion here only to ensure that any nested package
+      --  declaration that requires an implicit body gets one. (In the case
+      --  where a body is required, Check_Completion is called at the end of
+      --  the body's declarative part.)
 
-         if not Body_Required (Parent (N)) then
+      if not Body_Required then
+         Check_Completion;
+      end if;
+
+      Comp_Unit := Nkind (Parent (N)) = N_Compilation_Unit;
+      if Comp_Unit then
+
+         --  Set Body_Required indication on the compilation unit node, and
+         --  determine whether elaboration warnings may be meaningful on it.
+
+         Set_Body_Required (Parent (N), Body_Required);
+
+         if not Body_Required then
             Set_Suppress_Elaboration_Warnings (Id);
          end if;
 
+      end if;
+
+      End_Package_Scope (Id);
+
+      --  For the declaration of a library unit that is a remote types package,
+      --  check legality rules regarding availability of stream attributes for
+      --  types that contain non-remote access values. This subprogram performs
+      --  visibility tests that rely on the fact that we have exited the scope
+      --  of Id.
+
+      if Comp_Unit then
          Validate_RT_RAT_Component (N);
       end if;
+
+      if Debug_Flag_C then
+         Outdent;
+         Write_Str ("<== package spec ");
+         Write_Name (Chars (Id));
+         Write_Str (" from ");
+         Write_Location (Sloc (N));
+         Write_Eol;
+      end if;
    end Analyze_Package_Declaration;
 
    -----------------------------------
    -- Analyze_Package_Specification --
    -----------------------------------
 
-   --  Note that this code is shared for the analysis of generic package
-   --  specs (see Sem_Ch12.Analyze_Generic_Package_Declaration for details).
+   --  Note that this code is shared for the analysis of generic package specs
+   --  (see Sem_Ch12.Analyze_Generic_Package_Declaration for details).
 
    procedure Analyze_Package_Specification (N : Node_Id) is
       Id           : constant Entity_Id  := Defining_Entity (N);
@@ -677,11 +779,24 @@ package body Sem_Ch7 is
       L            : Entity_Id;
       Public_Child : Boolean;
 
+      Private_With_Clauses_Installed : Boolean := False;
+      --  In Ada 2005, private with_clauses are visible in the private part
+      --  of a nested package, even if it appears in the public part of the
+      --  enclosing package. This requires a separate step to install these
+      --  private_with_clauses, and remove them at the end of the nested
+      --  package.
+
+      procedure Analyze_PPCs (Decls : List_Id);
+      --  Given a list of declarations, go through looking for subprogram
+      --  specs, and for each one found, analyze any pre/postconditions that
+      --  are chained to the spec. This is the implementation of the late
+      --  visibility analysis for preconditions and postconditions in specs.
+
       procedure Clear_Constants (Id : Entity_Id; FE : Entity_Id);
-      --  Clears constant indications (Never_Set_In_Source, Constant_Value,
-      --  and Is_True_Constant) on all variables that are entities of Id,
-      --  and on the chain whose first element is FE. A recursive call is
-      --  made for all packages and generic packages.
+      --  Clears constant indications (Never_Set_In_Source, Constant_Value, and
+      --  Is_True_Constant) on all variables that are entities of Id, and on
+      --  the chain whose first element is FE. A recursive call is made for all
+      --  packages and generic packages.
 
       procedure Generate_Parent_References;
       --  For a child unit, generate references to parent units, for
@@ -691,17 +806,47 @@ package body Sem_Ch7 is
       --  Child and Unit are entities of compilation units. True if Child
       --  is a public child of Parent as defined in 10.1.1
 
-      procedure Inspect_Deferred_Constant_Completion;
-      --  Examines the deferred constants in the private part of the package
-      --  specification. Emits the error message "constant declaration requires
-      --  initialization expression " if not completed by an Import pragma.
-
       procedure Inspect_Unchecked_Union_Completion (Decls : List_Id);
       --  Detects all incomplete or private type declarations having a known
       --  discriminant part that are completed by an Unchecked_Union. Emits
       --  the error message "Unchecked_Union may not complete discriminated
       --  partial view".
 
+      procedure Install_Parent_Private_Declarations (Inst_Id : Entity_Id);
+      --  Given the package entity of a generic package instantiation or
+      --  formal package whose corresponding generic is a child unit, installs
+      --  the private declarations of each of the child unit's parents.
+      --  This has to be done at the point of entering the instance package's
+      --  private part rather than being done in Sem_Ch12.Install_Parent
+      --  (which is where the parents' visible declarations are installed).
+
+      ------------------
+      -- Analyze_PPCs --
+      ------------------
+
+      procedure Analyze_PPCs (Decls : List_Id) is
+         Decl : Node_Id;
+         Spec : Node_Id;
+         Sent : Entity_Id;
+         Prag : Node_Id;
+
+      begin
+         Decl := First (Decls);
+         while Present (Decl) loop
+            if Nkind (Original_Node (Decl)) = N_Subprogram_Declaration then
+               Spec := Specification (Original_Node (Decl));
+               Sent := Defining_Unit_Name (Spec);
+               Prag := Spec_PPC_List (Sent);
+               while Present (Prag) loop
+                  Analyze_PPC_In_Decl_Part (Prag, Sent);
+                  Prag := Next_Pragma (Prag);
+               end loop;
+            end if;
+
+            Next (Decl);
+         end loop;
+      end Analyze_PPCs;
+
       ---------------------
       -- Clear_Constants --
       ---------------------
@@ -710,29 +855,32 @@ package body Sem_Ch7 is
          E : Entity_Id;
 
       begin
-         --  Ignore package renamings, not interesting and they can
-         --  cause self referential loops in the code below.
+         --  Ignore package renamings, not interesting and they can cause self
+         --  referential loops in the code below.
 
          if Nkind (Parent (Id)) = N_Package_Renaming_Declaration then
             return;
          end if;
 
-         --  Note: in the loop below, the check for Next_Entity pointing
-         --  back to the package entity seems very odd, but it is needed,
-         --  because this kind of unexpected circularity does occur ???
+         --  Note: in the loop below, the check for Next_Entity pointing back
+         --  to the package entity may seem odd, but it is needed, because a
+         --  package can contain a renaming declaration to itself, and such
+         --  renamings are generated automatically within package instances.
 
          E := FE;
          while Present (E) and then E /= Id loop
-            if Ekind (E) = E_Variable then
+            if Is_Assignable (E) then
                Set_Never_Set_In_Source (E, False);
                Set_Is_True_Constant    (E, False);
                Set_Current_Value       (E, Empty);
-               Set_Is_Known_Non_Null   (E, False);
+               Set_Is_Known_Null       (E, False);
+               Set_Last_Assignment     (E, Empty);
 
-            elsif Ekind (E) = E_Package
-                    or else
-                  Ekind (E) = E_Generic_Package
-            then
+               if not Can_Never_Be_Null (E) then
+                  Set_Is_Known_Non_Null (E, False);
+               end if;
+
+            elsif Is_Package_Or_Generic_Package (E) then
                Clear_Constants (E, First_Entity (E));
                Clear_Constants (E, First_Private_Entity (E));
             end if;
@@ -754,11 +902,11 @@ package body Sem_Ch7 is
          then
             Generate_Reference (Id, Scope (Id), 'k', False);
 
-         elsif Nkind (Unit (Cunit (Main_Unit))) /= N_Subprogram_Body
-           and then Nkind (Unit (Cunit (Main_Unit))) /= N_Subunit
+         elsif not Nkind_In (Unit (Cunit (Main_Unit)), N_Subprogram_Body,
+                                                       N_Subunit)
          then
-            --  If current unit is an ancestor of main unit, generate
-            --  reference to its own parent.
+            --  If current unit is an ancestor of main unit, generate a
+            --  reference to its own parent.
 
             declare
                U         : Node_Id;
@@ -804,65 +952,31 @@ package body Sem_Ch7 is
          end if;
       end Is_Public_Child;
 
-      ------------------------------------------
-      -- Inspect_Deferred_Constant_Completion --
-      ------------------------------------------
-
-      procedure Inspect_Deferred_Constant_Completion is
-         Decl   : Node_Id;
-
-      begin
-         Decl := First (Priv_Decls);
-         while Present (Decl) loop
-
-            --  Deferred constant signature
-
-            if Nkind (Decl) = N_Object_Declaration
-              and then Constant_Present (Decl)
-              and then No (Expression (Decl))
-
-               --  No need to check internally generated constants
-
-              and then Comes_From_Source (Decl)
-
-               --  The constant is not completed. A full object declaration
-               --  or a pragma Import complete a deferred constant.
-
-              and then not Has_Completion (Defining_Identifier (Decl))
-            then
-               Error_Msg_N
-                 ("constant declaration requires initialization expression",
-                 Defining_Identifier (Decl));
-            end if;
-
-            Decl := Next (Decl);
-         end loop;
-      end Inspect_Deferred_Constant_Completion;
-
       ----------------------------------------
       -- Inspect_Unchecked_Union_Completion --
       ----------------------------------------
 
       procedure Inspect_Unchecked_Union_Completion (Decls : List_Id) is
-         Decl : Node_Id := First (Decls);
+         Decl : Node_Id;
 
       begin
+         Decl := First (Decls);
          while Present (Decl) loop
 
             --  We are looking at an incomplete or private type declaration
             --  with a known_discriminant_part whose full view is an
             --  Unchecked_Union.
 
-            if (Nkind (Decl) = N_Incomplete_Type_Declaration
-                  or else
-                Nkind (Decl) = N_Private_Type_Declaration)
+            if Nkind_In (Decl, N_Incomplete_Type_Declaration,
+                               N_Private_Type_Declaration)
               and then Has_Discriminants (Defining_Identifier (Decl))
               and then Present (Full_View (Defining_Identifier (Decl)))
-              and then Is_Unchecked_Union
-                (Full_View (Defining_Identifier (Decl)))
+              and then
+                Is_Unchecked_Union (Full_View (Defining_Identifier (Decl)))
             then
-               Error_Msg_N ("completion of discriminated partial view" &
-                 " cannot be an Unchecked_Union",
+               Error_Msg_N
+                 ("completion of discriminated partial view "
+                  & "cannot be an Unchecked_Union",
                  Full_View (Defining_Identifier (Decl)));
             end if;
 
@@ -870,11 +984,98 @@ package body Sem_Ch7 is
          end loop;
       end Inspect_Unchecked_Union_Completion;
 
+      -----------------------------------------
+      -- Install_Parent_Private_Declarations --
+      -----------------------------------------
+
+      procedure Install_Parent_Private_Declarations (Inst_Id : Entity_Id) is
+         Inst_Par  : Entity_Id;
+         Gen_Par   : Entity_Id;
+         Inst_Node : Node_Id;
+
+      begin
+         Inst_Par := Inst_Id;
+
+         Gen_Par :=
+           Generic_Parent (Specification (Unit_Declaration_Node (Inst_Par)));
+         while Present (Gen_Par) and then Is_Child_Unit (Gen_Par) loop
+            Inst_Node := Get_Package_Instantiation_Node (Inst_Par);
+
+            if Nkind_In (Inst_Node, N_Package_Instantiation,
+                                    N_Formal_Package_Declaration)
+              and then Nkind (Name (Inst_Node)) = N_Expanded_Name
+            then
+               Inst_Par := Entity (Prefix (Name (Inst_Node)));
+
+               if Present (Renamed_Entity (Inst_Par)) then
+                  Inst_Par := Renamed_Entity (Inst_Par);
+               end if;
+
+               Gen_Par :=
+                 Generic_Parent
+                   (Specification (Unit_Declaration_Node (Inst_Par)));
+
+               --  Install the private declarations and private use clauses
+               --  of a parent instance of the child instance, unless the
+               --  parent instance private declarations have already been
+               --  installed earlier in Analyze_Package_Specification, which
+               --  happens when a generic child is instantiated, and the
+               --  instance is a child of the parent instance.
+
+               --  Installing the use clauses of the parent instance twice
+               --  is both unnecessary and wrong, because it would cause the
+               --  clauses to be chained to themselves in the use clauses
+               --  list of the scope stack entry. That in turn would cause
+               --  an endless loop from End_Use_Clauses upon scope exit.
+
+               --  The parent is now fully visible. It may be a hidden open
+               --  scope if we are currently compiling some child instance
+               --  declared within it, but while the current instance is being
+               --  compiled the parent is immediately visible. In particular
+               --  its entities must remain visible if a stack save/restore
+               --  takes place through a call to Rtsfind.
+
+               if Present (Gen_Par) then
+                  if not In_Private_Part (Inst_Par) then
+                     Install_Private_Declarations (Inst_Par);
+                     Set_Use (Private_Declarations
+                                (Specification
+                                   (Unit_Declaration_Node (Inst_Par))));
+                     Set_Is_Hidden_Open_Scope (Inst_Par, False);
+                  end if;
+
+               --  If we've reached the end of the generic instance parents,
+               --  then finish off by looping through the nongeneric parents
+               --  and installing their private declarations.
+
+               else
+                  while Present (Inst_Par)
+                    and then Inst_Par /= Standard_Standard
+                    and then (not In_Open_Scopes (Inst_Par)
+                                or else not In_Private_Part (Inst_Par))
+                  loop
+                     Install_Private_Declarations (Inst_Par);
+                     Set_Use (Private_Declarations
+                                (Specification
+                                   (Unit_Declaration_Node (Inst_Par))));
+                     Inst_Par := Scope (Inst_Par);
+                  end loop;
+
+                  exit;
+               end if;
+
+            else
+               exit;
+            end if;
+         end loop;
+      end Install_Parent_Private_Declarations;
+
    --  Start of processing for Analyze_Package_Specification
 
    begin
       if Present (Vis_Decls) then
          Analyze_Declarations (Vis_Decls);
+         Analyze_PPCs (Vis_Decls);
       end if;
 
       --  Verify that incomplete types have received full declarations
@@ -896,17 +1097,17 @@ package body Sem_Ch7 is
          Validate_RCI_Declarations (Id);
       end if;
 
-      --  Save global references in the visible declarations, before
-      --  installing private declarations of parent unit if there is one,
-      --  because the privacy status of types defined in the parent will
-      --  change. This is only relevant for generic child units, but is
-      --  done in all cases for uniformity.
+      --  Save global references in the visible declarations, before installing
+      --  private declarations of parent unit if there is one, because the
+      --  privacy status of types defined in the parent will change. This is
+      --  only relevant for generic child units, but is done in all cases for
+      --  uniformity.
 
       if Ekind (Id) = E_Generic_Package
         and then Nkind (Orig_Decl) = N_Generic_Package_Declaration
       then
          declare
-            Orig_Spec : constant Node_Id    := Specification (Orig_Decl);
+            Orig_Spec : constant Node_Id := Specification (Orig_Decl);
             Save_Priv : constant List_Id := Private_Declarations (Orig_Spec);
 
          begin
@@ -916,8 +1117,8 @@ package body Sem_Ch7 is
          end;
       end if;
 
-      --  If package is a public child unit, then make the private
-      --  declarations of the parent visible.
+      --  If package is a public child unit, then make the private declarations
+      --  of the parent visible.
 
       Public_Child := False;
 
@@ -930,7 +1131,7 @@ package body Sem_Ch7 is
          Par := Id;
          Par_Spec := Parent_Spec (Parent (N));
 
-         --  If the package is formal package of an enclosing generic, is is
+         --  If the package is formal package of an enclosing generic, it is
          --  transformed into a local generic declaration, and compiled to make
          --  its spec available. We need to retrieve the original generic to
          --  determine whether it is a child unit, and install its parents.
@@ -948,6 +1149,7 @@ package body Sem_Ch7 is
 
             while Scope (Par) /= Standard_Standard
               and then Is_Public_Child (Id, Par)
+              and then In_Open_Scopes (Par)
             loop
                Public_Child := True;
                Par := Scope (Par);
@@ -961,29 +1163,58 @@ package body Sem_Ch7 is
 
       if Is_Compilation_Unit (Id) then
          Install_Private_With_Clauses (Id);
+      else
+
+         --  The current compilation unit may include private with_clauses,
+         --  which are visible in the private part of the current nested
+         --  package, and have to be installed now. This is not done for
+         --  nested instantiations, where the private with_clauses of the
+         --  enclosing unit have no effect once the instantiation info is
+         --  established and we start analyzing the package declaration.
+
+         declare
+            Comp_Unit : constant Entity_Id := Cunit_Entity (Current_Sem_Unit);
+         begin
+            if Is_Package_Or_Generic_Package (Comp_Unit)
+              and then not In_Private_Part (Comp_Unit)
+              and then not In_Instance
+            then
+               Install_Private_With_Clauses (Comp_Unit);
+               Private_With_Clauses_Installed := True;
+            end if;
+         end;
+      end if;
+
+      --  If this is a package associated with a generic instance or formal
+      --  package, then the private declarations of each of the generic's
+      --  parents must be installed at this point.
+
+      if Is_Generic_Instance (Id) then
+         Install_Parent_Private_Declarations (Id);
       end if;
 
-      --  Analyze private part if present. The flag In_Private_Part is
-      --  reset in End_Package_Scope.
+      --  Analyze private part if present. The flag In_Private_Part is reset
+      --  in End_Package_Scope.
 
       L := Last_Entity (Id);
 
       if Present (Priv_Decls) then
          Set_In_Private_Part (Id);
 
-         --  Upon entering a public child's private part, it may be
-         --  necessary to declare subprograms that were derived in
-         --  the package visible part but not yet made visible.
+         --  Upon entering a public child's private part, it may be necessary
+         --  to declare subprograms that were derived in the package's visible
+         --  part but not yet made visible.
 
          if Public_Child then
             Declare_Inherited_Private_Subprograms (Id);
          end if;
 
          Analyze_Declarations (Priv_Decls);
+         Analyze_PPCs (Priv_Decls);
 
          --  Check the private declarations for incomplete deferred constants
 
-         Inspect_Deferred_Constant_Completion;
+         Inspect_Deferred_Constant_Completion (Priv_Decls);
 
          --  The first private entity is the immediate follower of the last
          --  visible entity, if there was one.
@@ -994,11 +1225,10 @@ package body Sem_Ch7 is
             Set_First_Private_Entity (Id, First_Entity (Id));
          end if;
 
-      --  There may be inherited private subprograms that need to be
-      --  declared, even in the absence of an explicit private part.
-      --  If there are any public declarations in the package and
-      --  the package is a public child unit, then an implicit private
-      --  part is assumed.
+      --  There may be inherited private subprograms that need to be declared,
+      --  even in the absence of an explicit private part.  If there are any
+      --  public declarations in the package and the package is a public child
+      --  unit, then an implicit private part is assumed.
 
       elsif Present (L) and then Public_Child then
          Set_In_Private_Part (Id);
@@ -1006,15 +1236,27 @@ package body Sem_Ch7 is
          Set_First_Private_Entity (Id, Next_Entity (L));
       end if;
 
-      --  Check rule of 3.6(11), which in general requires
-      --  waiting till all full types have been seen.
-
       E := First_Entity (Id);
       while Present (E) loop
+
+         --  Check rule of 3.6(11), which in general requires waiting till all
+         --  full types have been seen.
+
          if Ekind (E) = E_Record_Type or else Ekind (E) = E_Array_Type then
             Check_Aliased_Component_Types (E);
          end if;
 
+         --  Check preelaborable initialization for full type completing a
+         --  private type for which pragma Preelaborable_Initialization given.
+
+         if Is_Type (E)
+           and then Must_Have_Preelab_Init (E)
+           and then not Has_Preelaborable_Initialization (E)
+         then
+            Error_Msg_N
+              ("full view of & does not have preelaborable initialization", E);
+         end if;
+
          Next_Entity (E);
       end loop;
 
@@ -1054,18 +1296,25 @@ package body Sem_Ch7 is
 
       Process_End_Label (N, 'e', Id);
 
-      --  For the case of a library level package, we must go through all
-      --  the entities clearing the indications that the value may be
-      --  constant and not modified. Why? Because any client of this
-      --  package may modify these values freely from anywhere. This
-      --  also applies to any nested packages or generic packages.
+      --  Remove private_with_clauses of enclosing compilation unit, if they
+      --  were installed.
+
+      if Private_With_Clauses_Installed then
+         Remove_Private_With_Clauses (Cunit (Current_Sem_Unit));
+      end if;
+
+      --  For the case of a library level package, we must go through all the
+      --  entities clearing the indications that the value may be constant and
+      --  not modified. Why? Because any client of this package may modify
+      --  these values freely from anywhere. This also applies to any nested
+      --  packages or generic packages.
 
-      --  For now we unconditionally clear constants for packages that
-      --  are instances of generic packages. The reason is that we do not
-      --  have the body yet, and we otherwise think things are unreferenced
-      --  when they are not. This should be fixed sometime (the effect is
-      --  not terrible, we just lose some warnings, and also some cases
-      --  of value propagation) ???
+      --  For now we unconditionally clear constants for packages that are
+      --  instances of generic packages. The reason is that we do not have the
+      --  body yet, and we otherwise think things are unreferenced when they
+      --  are not. This should be fixed sometime (the effect is not terrible,
+      --  we just lose some warnings, and also some cases of value propagation)
+      --  ???
 
       if Is_Library_Level_Entity (Id)
         or else Is_Generic_Instance (Id)
@@ -1088,8 +1337,7 @@ package body Sem_Ch7 is
       Set_Is_Pure         (Id, PF);
       Init_Size_Align     (Id);
 
-      if (Ekind (Current_Scope) /= E_Package
-          and then Ekind (Current_Scope) /= E_Generic_Package)
+      if not Is_Package_Or_Generic_Package (Current_Scope)
         or else In_Private_Part (Current_Scope)
       then
          Error_Msg_N ("invalid context for private declaration", N);
@@ -1099,62 +1347,53 @@ package body Sem_Ch7 is
       Set_Depends_On_Private (Id);
    end Analyze_Private_Type_Declaration;
 
-   -------------------------------------------
-   -- Declare_Inherited_Private_Subprograms --
-   -------------------------------------------
-
-   procedure Declare_Inherited_Private_Subprograms (Id : Entity_Id) is
-      E              : Entity_Id;
-      Op_List        : Elist_Id;
-      Op_Elmt        : Elmt_Id;
-      Op_Elmt_2      : Elmt_Id;
-      Prim_Op        : Entity_Id;
-      New_Op         : Entity_Id := Empty;
-      Parent_Subp    : Entity_Id;
-      Found_Explicit : Boolean;
-      Decl_Privates  : Boolean;
-
-      function Has_Overriding_Pragma (Subp : Entity_Id) return Boolean;
-      --  Check whether a pragma Overriding has been provided for a primitive
-      --  operation that is found to be overriding in the private part.
+   ----------------------------------
+   -- Check_Anonymous_Access_Types --
+   ----------------------------------
 
-      function Is_Primitive_Of (T : Entity_Id; S : Entity_Id) return Boolean;
-      --  Check whether an inherited subprogram is an operation of an
-      --  untagged derived type.
+   procedure Check_Anonymous_Access_Types
+     (Spec_Id : Entity_Id;
+      P_Body  : Node_Id)
+   is
+      E  : Entity_Id;
+      IR : Node_Id;
 
-      ---------------------------
-      -- Has_Overriding_Pragma --
-      ---------------------------
+   begin
+      --  Itype references are only needed by gigi, to force elaboration of
+      --  itypes. In the absence of code generation, they are not needed.
 
-      function Has_Overriding_Pragma (Subp : Entity_Id) return Boolean is
-         Decl : constant Node_Id := Unit_Declaration_Node (Subp);
-         Prag : Node_Id;
+      if not Expander_Active then
+         return;
+      end if;
 
-      begin
-         if No (Decl)
-           or else Nkind (Decl) /= N_Subprogram_Declaration
-           or else No (Next (Decl))
+      E := First_Entity (Spec_Id);
+      while Present (E) loop
+         if Ekind (E) = E_Anonymous_Access_Type
+           and then From_With_Type (E)
          then
-            return False;
-
-         else
-            Prag := Next (Decl);
+            IR := Make_Itype_Reference (Sloc (P_Body));
+            Set_Itype (IR, E);
 
-            while Present (Prag)
-              and then Nkind (Prag) = N_Pragma
-            loop
-               if Chars (Prag) = Name_Overriding
-                 or else Chars (Prag) = Name_Optional_Overriding
-               then
-                  return True;
-               else
-                  Next (Prag);
-               end if;
-            end loop;
+            if No (Declarations (P_Body)) then
+               Set_Declarations (P_Body, New_List (IR));
+            else
+               Prepend (IR, Declarations (P_Body));
+            end if;
          end if;
 
-         return False;
-      end Has_Overriding_Pragma;
+         Next_Entity (E);
+      end loop;
+   end Check_Anonymous_Access_Types;
+
+   -------------------------------------------
+   -- Declare_Inherited_Private_Subprograms --
+   -------------------------------------------
+
+   procedure Declare_Inherited_Private_Subprograms (Id : Entity_Id) is
+
+      function Is_Primitive_Of (T : Entity_Id; S : Entity_Id) return Boolean;
+      --  Check whether an inherited subprogram is an operation of an untagged
+      --  derived type.
 
       ---------------------
       -- Is_Primitive_Of --
@@ -1164,14 +1403,17 @@ package body Sem_Ch7 is
          Formal : Entity_Id;
 
       begin
-         if Etype (S) = T then
+         --  If the full view is a scalar type, the type is the anonymous base
+         --  type, but the operation mentions the first subtype, so check the
+         --  signature against the base type.
+
+         if Base_Type (Etype (S)) = Base_Type (T) then
             return True;
 
          else
             Formal := First_Formal (S);
-
             while Present (Formal) loop
-               if Etype (Formal) = T then
+               if Base_Type (Etype (Formal)) = Base_Type (T) then
                   return True;
                end if;
 
@@ -1182,16 +1424,27 @@ package body Sem_Ch7 is
          end if;
       end Is_Primitive_Of;
 
+      --  Local variables
+
+      E           : Entity_Id;
+      Op_List     : Elist_Id;
+      Op_Elmt     : Elmt_Id;
+      Op_Elmt_2   : Elmt_Id;
+      Prim_Op     : Entity_Id;
+      New_Op      : Entity_Id := Empty;
+      Parent_Subp : Entity_Id;
+      Tag         : Entity_Id;
+
    --  Start of processing for Declare_Inherited_Private_Subprograms
 
    begin
       E := First_Entity (Id);
       while Present (E) loop
 
-         --  If the entity is a nonprivate type extension whose parent
-         --  type is declared in an open scope, then the type may have
-         --  inherited operations that now need to be made visible.
-         --  Ditto if the entity is a formal derived type in a child unit.
+         --  If the entity is a nonprivate type extension whose parent type
+         --  is declared in an open scope, then the type may have inherited
+         --  operations that now need to be made visible. Ditto if the entity
+         --  is a formal derived type in a child unit.
 
          if ((Is_Derived_Type (E) and then not Is_Private_Type (E))
                or else
@@ -1201,112 +1454,111 @@ package body Sem_Ch7 is
            and then E = Base_Type (E)
          then
             if Is_Tagged_Type (E) then
-               Op_List       := Primitive_Operations (E);
-               New_Op        := Empty;
-               Decl_Privates := False;
+               Op_List := Primitive_Operations (E);
+               New_Op  := Empty;
+               Tag     := First_Tag_Component (E);
 
                Op_Elmt := First_Elmt (Op_List);
                while Present (Op_Elmt) loop
                   Prim_Op := Node (Op_Elmt);
 
-                  --  If the primitive operation is an implicit operation
-                  --  with an internal name whose parent operation has
-                  --  a normal name, then we now need to either declare the
-                  --  operation (i.e., make it visible), or replace it
-                  --  by an overriding operation if one exists.
+                  --  Search primitives that are implicit operations with an
+                  --  internal name whose parent operation has a normal name.
 
                   if Present (Alias (Prim_Op))
+                    and then Find_Dispatching_Type (Alias (Prim_Op)) /= E
                     and then not Comes_From_Source (Prim_Op)
                     and then Is_Internal_Name (Chars (Prim_Op))
                     and then not Is_Internal_Name (Chars (Alias (Prim_Op)))
                   then
                      Parent_Subp := Alias (Prim_Op);
 
-                     Found_Explicit := False;
+                     --  Case 1: Check if the type has also an explicit
+                     --  overriding for this primitive.
+
                      Op_Elmt_2 := Next_Elmt (Op_Elmt);
                      while Present (Op_Elmt_2) loop
                         if Chars (Node (Op_Elmt_2)) = Chars (Parent_Subp)
                           and then Type_Conformant (Prim_Op, Node (Op_Elmt_2))
                         then
                            --  The private inherited operation has been
-                           --  overridden by an explicit subprogram, so
-                           --  change the private op's list element to
-                           --  designate the explicit so the explicit
-                           --  one will get the right dispatching slot.
+                           --  overridden by an explicit subprogram: replace
+                           --  the former by the latter.
 
                            New_Op := Node (Op_Elmt_2);
                            Replace_Elmt (Op_Elmt, New_Op);
-                           Remove_Elmt (Op_List, Op_Elmt_2);
-                           Found_Explicit := True;
-                           Decl_Privates  := True;
+                           Remove_Elmt  (Op_List, Op_Elmt_2);
+                           Set_Is_Overriding_Operation (New_Op);
+                           Set_Overridden_Operation (New_Op, Parent_Subp);
 
-                           --  If explicit_overriding is in effect, check that
-                           --  the overriding operation is properly labelled.
+                           --  We don't need to inherit its dispatching slot.
+                           --  Set_All_DT_Position has previously ensured that
+                           --  the same slot was assigned to the two primitives
 
-                           if Explicit_Overriding
-                             and then Comes_From_Source (New_Op)
-                              and then not Has_Overriding_Pragma (New_Op)
+                           if Present (Tag)
+                             and then Present (DTC_Entity (New_Op))
+                             and then Present (DTC_Entity (Prim_Op))
                            then
-                              Error_Msg_NE
-                                ("Missing overriding pragma for&",
-                                  New_Op, New_Op);
+                              pragma Assert (DT_Position (New_Op)
+                                              = DT_Position (Prim_Op));
+                              null;
                            end if;
 
-                           exit;
+                           goto Next_Primitive;
                         end if;
 
                         Next_Elmt (Op_Elmt_2);
                      end loop;
 
-                     if not Found_Explicit then
-                        Derive_Subprogram
-                          (New_Op, Alias (Prim_Op), E, Etype (E));
+                     --  Case 2: We have not found any explicit overriding and
+                     --  hence we need to declare the operation (i.e., make it
+                     --  visible).
 
-                        pragma Assert
-                          (Is_Dispatching_Operation (New_Op)
-                            and then Node (Last_Elmt (Op_List)) = New_Op);
-
-                        --  Substitute the new operation for the old one
-                        --  in the type's primitive operations list. Since
-                        --  the new operation was also just added to the end
-                        --  of list, the last element must be removed.
+                     Derive_Subprogram (New_Op, Alias (Prim_Op), E, Etype (E));
 
-                        --  (Question: is there a simpler way of declaring
-                        --  the operation, say by just replacing the name
-                        --  of the earlier operation, reentering it in the
-                        --  in the symbol table (how?), and marking it as
-                        --  private???)
+                     --  Inherit the dispatching slot if E is already frozen
 
-                        Replace_Elmt (Op_Elmt, New_Op);
-                        Remove_Last_Elmt (Op_List);
-                        Decl_Privates := True;
+                     if Is_Frozen (E)
+                       and then Present (DTC_Entity (Alias (Prim_Op)))
+                     then
+                        Set_DTC_Entity_Value (E, New_Op);
+                        Set_DT_Position (New_Op,
+                          DT_Position (Alias (Prim_Op)));
                      end if;
+
+                     pragma Assert
+                       (Is_Dispatching_Operation (New_Op)
+                         and then Node (Last_Elmt (Op_List)) = New_Op);
+
+                     --  Substitute the new operation for the old one in the
+                     --  type's primitive operations list. Since the new
+                     --  operation was also just added to the end of list,
+                     --  the last element must be removed.
+
+                     --  (Question: is there a simpler way of declaring the
+                     --  operation, say by just replacing the name of the
+                     --  earlier operation, reentering it in the in the symbol
+                     --  table (how?), and marking it as private???)
+
+                     Replace_Elmt (Op_Elmt, New_Op);
+                     Remove_Last_Elmt (Op_List);
                   end if;
 
+                  <<Next_Primitive>>
                   Next_Elmt (Op_Elmt);
                end loop;
 
-               --  The type's DT attributes need to be recalculated
-               --  in the case where private dispatching operations
-               --  have been added or overridden. Normally this action
-               --  occurs during type freezing, but we force it here
-               --  since the type may already have been frozen (e.g.,
-               --  if the type's package has an empty private part).
-               --  This can only be done if expansion is active, otherwise
-               --  Tag may not be present.
-
-               if Decl_Privates
-                 and then Expander_Active
-               then
-                  Set_All_DT_Position (E);
+               --  Generate listing showing the contents of the dispatch table
+
+               if Debug_Flag_ZZ then
+                  Write_DT (E);
                end if;
 
             else
-               --   Non-tagged type, scan forward to locate
-               --   inherited hidden operations.
+               --  Non-tagged type, scan forward to locate inherited hidden
+               --  operations.
 
                Prim_Op := Next_Entity (E);
-
                while Present (Prim_Op) loop
                   if Is_Subprogram (Prim_Op)
                     and then Present (Alias (Prim_Op))
@@ -1360,8 +1612,8 @@ package body Sem_Ch7 is
       Next2 := Next_Entity (Full_Id);
       H2    := Homonym (Full_Id);
 
-      --  Reset full declaration pointer to reflect the switched entities
-      --  and readjust the next entity chains.
+      --  Reset full declaration pointer to reflect the switched entities and
+      --  readjust the next entity chains.
 
       Exchange_Entities (Id, Full_Id);
 
@@ -1404,17 +1656,16 @@ package body Sem_Ch7 is
       Full      : Entity_Id;
 
    begin
-      --  First exchange declarations for private types, so that the
-      --  full declaration is visible. For each private type, we check
-      --  its Private_Dependents list and also exchange any subtypes of
-      --  or derived types from it. Finally, if this is a Taft amendment
-      --  type, the incomplete declaration is irrelevant, and we want to
-      --  link the eventual full declaration with the original private
-      --  one so we also skip the exchange.
+      --  First exchange declarations for private types, so that the full
+      --  declaration is visible. For each private type, we check its
+      --  Private_Dependents list and also exchange any subtypes of or derived
+      --  types from it. Finally, if this is a Taft amendment type, the
+      --  incomplete declaration is irrelevant, and we want to link the
+      --  eventual full declaration with the original private one so we also
+      --  skip the exchange.
 
       Id := First_Entity (P);
       while Present (Id) and then Id /= First_Private_Entity (P) loop
-
          if Is_Private_Base_Type (Id)
            and then Comes_From_Source (Full_View (Id))
            and then Present (Full_View (Id))
@@ -1439,12 +1690,19 @@ package body Sem_Ch7 is
                --  can only happen in a package nested within a child package,
                --  when the parent type is defined in the parent unit. At this
                --  point the current type is not private either, and we have to
-               --  install the underlying full view, which is now visible.
+               --  install the underlying full view, which is now visible. Save
+               --  the current full view as well, so that all views can be
+               --  restored on exit. It may seem that after compiling the child
+               --  body there are not environments to restore, but the back-end
+               --  expects those links to be valid, and freeze nodes depend on
+               --  them.
 
                if No (Full_View (Full))
                  and then Present (Underlying_Full_View (Full))
                then
                   Set_Full_View (Id, Underlying_Full_View (Full));
+                  Set_Underlying_Full_View (Id, Full);
+
                   Set_Underlying_Full_View (Full, Empty);
                   Set_Is_Frozen (Full_View (Id));
                end if;
@@ -1459,8 +1717,8 @@ package body Sem_Ch7 is
                Priv := Node (Priv_Elmt);
 
                --  Before the exchange, verify that the presence of the
-               --  Full_View field. It will be empty if the entity
-               --  has already been installed due to a previous call.
+               --  Full_View field. It will be empty if the entity has already
+               --  been installed due to a previous call.
 
                if Present (Full_View (Priv))
                  and then Is_Visible_Dependent (Priv)
@@ -1488,7 +1746,6 @@ package body Sem_Ch7 is
       --  Next make other declarations in the private part visible as well
 
       Id := First_Private_Entity (P);
-
       while Present (Id) loop
          Install_Package_Entity (Id);
          Set_Is_Hidden (Id, False);
@@ -1506,12 +1763,21 @@ package body Sem_Ch7 is
    ----------------------------------
 
    procedure Install_Visible_Declarations (P : Entity_Id) is
-      Id : Entity_Id;
+      Id          : Entity_Id;
+      Last_Entity : Entity_Id;
 
    begin
-      Id := First_Entity (P);
+      pragma Assert
+        (Is_Package_Or_Generic_Package (P) or else Is_Record_Type (P));
 
-      while Present (Id) and then Id /= First_Private_Entity (P) loop
+      if Is_Package_Or_Generic_Package (P) then
+         Last_Entity := First_Private_Entity (P);
+      else
+         Last_Entity := Empty;
+      end if;
+
+      Id := First_Entity (P);
+      while Present (Id) and then Id /= Last_Entity loop
          Install_Package_Entity (Id);
          Next_Entity (Id);
       end loop;
@@ -1537,8 +1803,7 @@ package body Sem_Ch7 is
       S : constant Entity_Id := Scope (Dep);
 
    begin
-      --  Renamings created for actual types have the visibility of the
-      --  actual.
+      --  Renamings created for actual types have the visibility of the actual
 
       if Ekind (S) = E_Package
         and then Is_Generic_Instance (S)
@@ -1550,9 +1815,9 @@ package body Sem_Ch7 is
       elsif not (Is_Derived_Type (Dep))
         and then Is_Derived_Type (Full_View (Dep))
       then
-         --  When instantiating a package body, the scope stack is empty,
-         --  so check instead whether the dependent type is defined in
-         --  the same scope as the instance itself.
+         --  When instantiating a package body, the scope stack is empty, so
+         --  check instead whether the dependent type is defined in the same
+         --  scope as the instance itself.
 
          return In_Open_Scopes (S)
            or else (Is_Generic_Instance (Current_Scope)
@@ -1575,7 +1840,7 @@ package body Sem_Ch7 is
    begin
       if not Has_Completion (E)
         and then Nkind (P) = N_Package_Declaration
-        and then Present (Activation_Chain_Entity (P))
+        and then (Present (Activation_Chain_Entity (P)) or else Has_RACW (E))
       then
          B :=
            Make_Package_Body (Sloc (E),
@@ -1621,8 +1886,8 @@ package body Sem_Ch7 is
         No (Discriminant_Specifications (N))
           and then not Unknown_Discriminants_Present (N));
 
-      --  Set tagged flag before processing discriminants, to catch
-      --  illegal usage.
+      --  Set tagged flag before processing discriminants, to catch illegal
+      --  usage.
 
       Set_Is_Tagged_Type (Id, Tagged_Present (Def));
 
@@ -1630,7 +1895,7 @@ package body Sem_Ch7 is
       Set_Stored_Constraint (Id, No_Elist);
 
       if Present (Discriminant_Specifications (N)) then
-         New_Scope (Id);
+         Push_Scope (Id);
          Process_Discriminants (N);
          End_Scope;
 
@@ -1642,12 +1907,15 @@ package body Sem_Ch7 is
 
       if Tagged_Present (Def) then
          Set_Ekind                (Id, E_Record_Type_With_Private);
-         Make_Class_Wide_Type     (Id);
          Set_Primitive_Operations (Id, New_Elmt_List);
-         Set_Is_Abstract          (Id, Abstract_Present (Def));
+         Set_Is_Abstract_Type     (Id, Abstract_Present (Def));
          Set_Is_Limited_Record    (Id, Limited_Present (Def));
          Set_Has_Delayed_Freeze   (Id, True);
 
+         --  Create a class-wide type with the same attributes
+
+         Make_Class_Wide_Type     (Id);
+
       elsif Abstract_Present (Def) then
          Error_Msg_N ("only a tagged type can be abstract", N);
       end if;
@@ -1665,8 +1933,8 @@ package body Sem_Ch7 is
       Priv_Sub  : Entity_Id;
 
       procedure Preserve_Full_Attributes (Priv, Full : Entity_Id);
-      --  Copy to the private declaration the attributes of the full view
-      --  that need to be available for the partial view also.
+      --  Copy to the private declaration the attributes of the full view that
+      --  need to be available for the partial view also.
 
       function Type_In_Use (T : Entity_Id) return Boolean;
       --  Check whether type or base type appear in an active use_type clause
@@ -1680,11 +1948,20 @@ package body Sem_Ch7 is
 
       begin
          Set_Size_Info (Priv, (Full));
-         Set_RM_Size (Priv, RM_Size (Full));
-         Set_Size_Known_At_Compile_Time (Priv, Size_Known_At_Compile_Time
-                                                                      (Full));
-         Set_Is_Volatile       (Priv, Is_Volatile       (Full));
-         Set_Treat_As_Volatile (Priv, Treat_As_Volatile (Full));
+         Set_RM_Size                 (Priv, RM_Size (Full));
+         Set_Size_Known_At_Compile_Time
+                                     (Priv, Size_Known_At_Compile_Time (Full));
+         Set_Is_Volatile             (Priv, Is_Volatile                (Full));
+         Set_Treat_As_Volatile       (Priv, Treat_As_Volatile          (Full));
+         Set_Is_Ada_2005_Only        (Priv, Is_Ada_2005_Only           (Full));
+         Set_Has_Pragma_Unreferenced (Priv, Has_Pragma_Unreferenced    (Full));
+         Set_Has_Pragma_Unreferenced_Objects
+                                     (Priv, Has_Pragma_Unreferenced_Objects
+                                                                       (Full));
+         if Is_Unchecked_Union (Full) then
+            Set_Is_Unchecked_Union (Base_Type (Priv));
+         end if;
+         --  Why is atomic not copied here ???
 
          if Referenced (Full) then
             Set_Referenced (Priv);
@@ -1706,12 +1983,54 @@ package body Sem_Ch7 is
            and then not Error_Posted (Full)
          then
             if Priv_Is_Base_Type then
-               Set_Access_Disp_Table (Priv, Access_Disp_Table
-                                                           (Base_Type (Full)));
+
+               --  Ada 2005 (AI-345): The full view of a type implementing an
+               --  interface can be a task type.
+
+               --    type T is new I with private;
+               --  private
+               --    task type T is new I with ...
+
+               if Is_Interface (Etype (Priv))
+                 and then Is_Concurrent_Type (Base_Type (Full))
+               then
+                  --  Protect the frontend against previous errors
+
+                  if Present (Corresponding_Record_Type
+                               (Base_Type (Full)))
+                  then
+                     Set_Access_Disp_Table
+                       (Priv, Access_Disp_Table
+                               (Corresponding_Record_Type (Base_Type (Full))));
+
+                  --  Generic context, or previous errors
+
+                  else
+                     null;
+                  end if;
+
+               else
+                  Set_Access_Disp_Table
+                    (Priv, Access_Disp_Table (Base_Type (Full)));
+               end if;
+            end if;
+
+            if Is_Tagged_Type (Priv) then
+
+               --  If the type is tagged, the tag itself must be available on
+               --  the partial view, for expansion purposes.
+
+               Set_First_Entity (Priv, First_Entity (Full));
+
+               --  If there are discriminants in the partial view, these remain
+               --  visible. Otherwise only the tag itself is visible, and there
+               --  are no nameable components in the partial view.
+
+               if No (Last_Entity (Priv)) then
+                  Set_Last_Entity (Priv, First_Entity (Priv));
+               end if;
             end if;
 
-            Set_First_Entity (Priv, First_Entity (Full));
-            Set_Last_Entity  (Priv, Last_Entity (Full));
             Set_Has_Discriminants (Priv, Has_Discriminants (Full));
          end if;
       end Preserve_Full_Attributes;
@@ -1723,14 +2042,13 @@ package body Sem_Ch7 is
       function Type_In_Use (T : Entity_Id) return Boolean is
       begin
          return Scope (Base_Type (T)) = P
-           and then  (In_Use (T) or else In_Use (Base_Type (T)));
+           and then (In_Use (T) or else In_Use (Base_Type (T)));
       end Type_In_Use;
 
    --  Start of processing for Uninstall_Declarations
 
    begin
       Id := First_Entity (P);
-
       while Present (Id) and then Id /= First_Private_Entity (P) loop
          if Debug_Flag_E then
             Write_Str ("unlinking visible entity ");
@@ -1763,8 +2081,24 @@ package body Sem_Ch7 is
                            Type_In_Use
                              (Etype (Next_Formal (First_Formal (Id))))));
          else
-            Set_Is_Potentially_Use_Visible (Id,
-              In_Use (P) and not Is_Hidden (Id));
+            if In_Use (P) and then not Is_Hidden (Id) then
+
+               --  A child unit of a use-visible package remains use-visible
+               --  only if it is itself a visible child unit. Otherwise it
+               --  would remain visible in other contexts where P is use-
+               --  visible, because once compiled it stays in the entity list
+               --  of its parent unit.
+
+               if Is_Child_Unit (Id) then
+                  Set_Is_Potentially_Use_Visible (Id,
+                    Is_Visible_Child_Unit (Id));
+               else
+                  Set_Is_Potentially_Use_Visible (Id);
+               end if;
+
+            else
+               Set_Is_Potentially_Use_Visible (Id, False);
+            end if;
          end if;
 
          --  Local entities are not immediately visible outside of the package
@@ -1784,6 +2118,7 @@ package body Sem_Ch7 is
 
          if Is_Tagged_Type (Id) and then Ekind (Id) = E_Record_Type then
             Check_Abstract_Overriding (Id);
+            Check_Conventions (Id);
          end if;
 
          if (Ekind (Id) = E_Private_Type
@@ -1805,17 +2140,42 @@ package body Sem_Ch7 is
                  ("missing full declaration for private extension", Id);
             end if;
 
+         --  Case of constant, check for deferred constant declaration with
+         --  no full view. Likely just a matter of a missing expression, or
+         --  accidental use of the keyword constant.
+
          elsif Ekind (Id) = E_Constant
+
+           --  OK if constant value present
+
            and then No (Constant_Value (Id))
+
+           --  OK if full view present
+
            and then No (Full_View (Id))
+
+           --  OK if imported, since that provides the completion
+
            and then not Is_Imported (Id)
-           and then (Nkind (Parent (Id)) /= N_Object_Declaration
-                      or else not No_Initialization (Parent (Id)))
+
+           --  OK if object declaration replaced by renaming declaration as
+           --  a result of OK_To_Rename processing (e.g. for concatenation)
+
+           and then Nkind (Parent (Id)) /= N_Object_Renaming_Declaration
+
+           --  OK if object declaration with the No_Initialization flag set
+
+           and then not (Nkind (Parent (Id)) = N_Object_Declaration
+                           and then No_Initialization (Parent (Id)))
          then
+            --  If no private declaration is present, we assume the user did
+            --  not intend a deferred constant declaration and the problem
+            --  is simply that the initializing expression is missing.
+
             if not Has_Private_Declaration (Etype (Id)) then
 
-               --  We assume that the user did not not intend a deferred
-               --  constant declaration, and the expression is just missing.
+               --  We assume that the user did not intend a deferred constant
+               --  declaration, and the expression is just missing.
 
                Error_Msg_N
                  ("constant declaration requires initialization expression",
@@ -1823,18 +2183,21 @@ package body Sem_Ch7 is
 
                if Is_Limited_Type (Etype (Id)) then
                   Error_Msg_N
-                    ("\else remove keyword CONSTANT from declaration",
+                    ("\if variable intended, remove CONSTANT from declaration",
                     Parent (Id));
                end if;
 
+            --  Otherwise if a private declaration is present, then we are
+            --  missing the full declaration for the deferred constant.
+
             else
                Error_Msg_N
-                  ("missing full declaration for deferred constant ('R'M 7.4)",
+                  ("missing full declaration for deferred constant (RM 7.4)",
                      Id);
 
                if Is_Limited_Type (Etype (Id)) then
                   Error_Msg_N
-                    ("\else remove keyword CONSTANT from declaration",
+                    ("\if variable intended, remove CONSTANT from declaration",
                     Parent (Id));
                end if;
             end if;
@@ -1854,7 +2217,8 @@ package body Sem_Ch7 is
       end if;
 
       --  Make private entities invisible and exchange full and private
-      --  declarations for private types.
+      --  declarations for private types. Id is now the first private entity
+      --  in the package.
 
       while Present (Id) loop
          if Debug_Flag_E then
@@ -1865,6 +2229,7 @@ package body Sem_Ch7 is
 
          if Is_Tagged_Type (Id) and then Ekind (Id) = E_Record_Type then
             Check_Abstract_Overriding (Id);
+            Check_Conventions (Id);
          end if;
 
          Set_Is_Immediately_Visible (Id, False);
@@ -1874,10 +2239,10 @@ package body Sem_Ch7 is
          then
             Full := Full_View (Id);
 
-            --  If the partial view is not declared in the visible part
-            --  of the package (as is the case when it is a type derived
-            --  from some other private type in the private part of the
-            --  current package), no exchange takes place.
+            --  If the partial view is not declared in the visible part of the
+            --  package (as is the case when it is a type derived from some
+            --  other private type in the private part of the current package),
+            --  no exchange takes place.
 
             if No (Parent (Id))
               or else List_Containing (Parent (Id))
@@ -1888,10 +2253,10 @@ package body Sem_Ch7 is
 
             --  The entry in the private part points to the full declaration,
             --  which is currently visible. Exchange them so only the private
-            --  type declaration remains accessible, and link private and
-            --  full declaration in the opposite direction. Before the actual
-            --  exchange, we copy back attributes of the full view that
-            --  must be available to the partial view too.
+            --  type declaration remains accessible, and link private and full
+            --  declaration in the opposite direction. Before the actual
+            --  exchange, we copy back attributes of the full view that must
+            --  be available to the partial view too.
 
             Preserve_Full_Attributes (Id, Full);
 
@@ -1905,15 +2270,14 @@ package body Sem_Ch7 is
             end if;
 
             Priv_Elmt := First_Elmt (Private_Dependents (Id));
-            Exchange_Declarations (Id);
 
             --  Swap out the subtypes and derived types of Id that were
             --  compiled in this scope, or installed previously by
             --  Install_Private_Declarations.
-            --  Before we do the swap, we verify the presence of the
-            --  Full_View field which may be empty due to a swap by
-            --  a previous call to End_Package_Scope (e.g. from the
-            --  freezing mechanism).
+
+            --  Before we do the swap, we verify the presence of the Full_View
+            --  field which may be empty due to a swap by a previous call to
+            --  End_Package_Scope (e.g. from the freezing mechanism).
 
             while Present (Priv_Elmt) loop
                Priv_Sub := Node (Priv_Elmt);
@@ -1937,13 +2301,69 @@ package body Sem_Ch7 is
                Next_Elmt (Priv_Elmt);
             end loop;
 
+            --  Now restore the type itself to its private view
+
+            Exchange_Declarations (Id);
+
+            --  If we have installed an underlying full view for a type derived
+            --  from a private type in a child unit, restore the proper views
+            --  of private and full view. See corresponding code in
+            --  Install_Private_Declarations.
+
+            --  After the exchange, Full denotes the private type in the
+            --  visible part of the package.
+
+            if Is_Private_Base_Type (Full)
+              and then Present (Full_View (Full))
+              and then Present (Underlying_Full_View (Full))
+              and then In_Package_Body (Current_Scope)
+            then
+               Set_Full_View (Full, Underlying_Full_View (Full));
+               Set_Underlying_Full_View (Full, Empty);
+            end if;
+
          elsif Ekind (Id) = E_Incomplete_Type
+           and then Comes_From_Source (Id)
            and then No (Full_View (Id))
          then
-            --  Mark Taft amendment types
+            --  Mark Taft amendment types. Verify that there are no primitive
+            --  operations declared for the type (3.10.1(9)).
 
             Set_Has_Completion_In_Body (Id);
 
+            declare
+               Elmt : Elmt_Id;
+               Subp : Entity_Id;
+
+            begin
+               Elmt := First_Elmt (Private_Dependents (Id));
+               while Present (Elmt) loop
+                  Subp := Node (Elmt);
+
+                  if Is_Overloadable (Subp) then
+                     Error_Msg_NE
+                       ("type& must be completed in the private part",
+                         Parent (Subp), Id);
+
+                  --  The return type of an access_to_function cannot be a
+                  --  Taft-amendment type.
+
+                  elsif Ekind (Subp) = E_Subprogram_Type then
+                     if Etype (Subp) = Id
+                       or else
+                         (Is_Class_Wide_Type (Etype (Subp))
+                            and then Etype (Etype (Subp)) = Id)
+                     then
+                        Error_Msg_NE
+                          ("type& must be completed in the private part",
+                             Associated_Node_For_Itype (Subp), Id);
+                     end if;
+                  end if;
+
+                  Next_Elmt (Elmt);
+               end loop;
+            end;
+
          elsif not Is_Child_Unit (Id)
            and then (not Is_Private_Type (Id)
                       or else No (Full_View (Id)))
@@ -1965,9 +2385,9 @@ package body Sem_Ch7 is
       E : Entity_Id;
 
    begin
-      --  Imported entity never requires body. Right now, only
-      --  subprograms can be imported, but perhaps in the future
-      --  we will allow import of packages.
+      --  Imported entity never requires body. Right now, only subprograms can
+      --  be imported, but perhaps in the future we will allow import of
+      --  packages.
 
       if Is_Imported (P) then
          return False;
@@ -1993,7 +2413,6 @@ package body Sem_Ch7 is
       then
          declare
             G_P : constant Entity_Id := Generic_Parent (Parent (P));
-
          begin
             if Has_Pragma_Elaborate_Body (G_P) then
                return True;
@@ -2021,13 +2440,17 @@ package body Sem_Ch7 is
          then
             null;
 
-         --  Otherwise test to see if entity requires a completion
+         --  Otherwise test to see if entity requires a completion.
+         --  Note that subprogram entities whose declaration does not come
+         --  from source are ignored here on the basis that we assume the
+         --  expander will provide an implicit completion at some point.
 
          elsif (Is_Overloadable (E)
                and then Ekind (E) /= E_Enumeration_Literal
                and then Ekind (E) /= E_Operator
-               and then not Is_Abstract (E)
-               and then not Has_Completion (E))
+               and then not Is_Abstract_Subprogram (E)
+               and then not Has_Completion (E)
+               and then Comes_From_Source (Parent (E)))
 
            or else
              (Ekind (E) = E_Package