------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             E X P _ D I S P                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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 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 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.      --
--                                                                          --
------------------------------------------------------------------------------

with Atree;          use Atree;
with Checks;         use Checks;
with Debug;          use Debug;
with Einfo;          use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Einfo.Utils;    use Einfo.Utils;
with Elists;         use Elists;
with Errout;         use Errout;
with Expander;       use Expander;
with Exp_Atag;       use Exp_Atag;
with Exp_Ch6;        use Exp_Ch6;
with Exp_CG;         use Exp_CG;
with Exp_Dbug;       use Exp_Dbug;
with Exp_Tss;        use Exp_Tss;
with Exp_Util;       use Exp_Util;
with Freeze;         use Freeze;
with Ghost;          use Ghost;
with Itypes;         use Itypes;
with Layout;         use Layout;
with Nlists;         use Nlists;
with Nmake;          use Nmake;
with Namet;          use Namet;
with Opt;            use Opt;
with Output;         use Output;
with Restrict;       use Restrict;
with Rident;         use Rident;
with Rtsfind;        use Rtsfind;
with Sem;            use Sem;
with Sem_Aux;        use Sem_Aux;
with Sem_Ch6;        use Sem_Ch6;
with Sem_Ch7;        use Sem_Ch7;
with Sem_Ch8;        use Sem_Ch8;
with Sem_Disp;       use Sem_Disp;
with Sem_Eval;       use Sem_Eval;
with Sem_Res;        use Sem_Res;
with Sem_Type;       use Sem_Type;
with Sem_Util;       use Sem_Util;
with Sinfo;          use Sinfo;
with Sinfo.Nodes;    use Sinfo.Nodes;
with Sinfo.Utils;    use Sinfo.Utils;
with Sinput;         use Sinput;
with Snames;         use Snames;
with Stand;          use Stand;
with Stringt;        use Stringt;
with SCIL_LL;        use SCIL_LL;
with Tbuild;         use Tbuild;

package body Exp_Disp is

   -----------------------
   -- Local Subprograms --
   -----------------------

   function Default_Prim_Op_Position (E : Entity_Id) return Uint;
   --  Ada 2005 (AI-251): Returns the fixed position in the dispatch table
   --  of the default primitive operations.

   function Has_DT (Typ : Entity_Id) return Boolean;
   pragma Inline (Has_DT);
   --  Returns true if we generate a dispatch table for tagged type Typ

   function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean;
   --  Returns true if Prim is not a predefined dispatching primitive but it is
   --  an alias of a predefined dispatching primitive (i.e. through a renaming)

   function New_Value (From : Node_Id) return Node_Id;
   --  From is the original Expression. New_Value is equivalent to a call to
   --  Duplicate_Subexpr with an explicit dereference when From is an access
   --  parameter.

   function Prim_Op_Kind
     (Prim : Entity_Id;
      Typ  : Entity_Id) return Node_Id;
   --  Ada 2005 (AI-345): Determine the primitive operation kind of Prim
   --  according to its type Typ. Return a reference to an RE_Prim_Op_Kind
   --  enumeration value.

   function Tagged_Kind (T : Entity_Id) return Node_Id;
   --  Ada 2005 (AI-345): Determine the tagged kind of T and return a reference
   --  to an RE_Tagged_Kind enumeration value.

   ----------------------
   -- Apply_Tag_Checks --
   ----------------------

   procedure Apply_Tag_Checks (Call_Node : Node_Id) is
      Loc        : constant Source_Ptr := Sloc (Call_Node);
      Ctrl_Arg   : constant Node_Id   := Controlling_Argument (Call_Node);
      Ctrl_Typ   : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
      Param_List : constant List_Id   := Parameter_Associations (Call_Node);

      Subp            : Entity_Id;
      CW_Typ          : Entity_Id;
      Param           : Node_Id;
      Typ             : Entity_Id;
      Eq_Prim_Op      : Entity_Id := Empty;

   begin
      if No_Run_Time_Mode then
         Error_Msg_CRT ("tagged types", Call_Node);
         return;
      end if;

      --  Apply_Tag_Checks is called directly from the semantics, so we
      --  need a check to see whether expansion is active before proceeding.
      --  In addition, there is no need to expand the call when compiling
      --  under restriction No_Dispatching_Calls; the semantic analyzer has
      --  previously notified the violation of this restriction.

      if not Expander_Active
        or else Restriction_Active (No_Dispatching_Calls)
      then
         return;
      end if;

      --  Set subprogram. If this is an inherited operation that was
      --  overridden, the body that is being called is its alias.

      Subp := Entity (Name (Call_Node));

      if Present (Alias (Subp))
        and then Is_Inherited_Operation (Subp)
        and then No (DTC_Entity (Subp))
      then
         Subp := Alias (Subp);
      end if;

      --  Definition of the class-wide type and the tagged type

      --  If the controlling argument is itself a tag rather than a tagged
      --  object, then use the class-wide type associated with the subprogram's
      --  controlling type. This case can occur when a call to an inherited
      --  primitive has an actual that originated from a default parameter
      --  given by a tag-indeterminate call and when there is no other
      --  controlling argument providing the tag (AI-239 requires dispatching).
      --  This capability of dispatching directly by tag is also needed by the
      --  implementation of AI-260 (for the generic dispatching constructors).

      if Is_RTE (Ctrl_Typ, RE_Tag)
        or else Is_RTE (Ctrl_Typ, RE_Interface_Tag)
      then
         CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));

      --  Class_Wide_Type is applied to the expressions used to initialize
      --  CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
      --  there are cases where the controlling type is resolved to a specific
      --  type (such as for designated types of arguments such as CW'Access).

      elsif Is_Access_Type (Ctrl_Typ) then
         CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));

      else
         CW_Typ := Class_Wide_Type (Ctrl_Typ);
      end if;

      Typ := Find_Specific_Type (CW_Typ);

      if not Is_Limited_Type (Typ) then
         Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
      end if;

      --  Dispatching call to C++ primitive

      if Is_CPP_Class (Typ) then
         null;

      --  Dispatching call to Ada primitive

      elsif Present (Param_List) then

         --  Generate the Tag checks when appropriate

         Param := First_Actual (Call_Node);
         while Present (Param) loop

            --  No tag check with itself

            if Param = Ctrl_Arg then
               null;

            --  No tag check for parameter whose type is neither tagged nor
            --  access to tagged (for access parameters)

            elsif No (Find_Controlling_Arg (Param)) then
               null;

            --  No tag check for function dispatching on result if the
            --  Tag given by the context is this one

            elsif Find_Controlling_Arg (Param) = Ctrl_Arg then
               null;

            --  "=" is the only dispatching operation allowed to get operands
            --  with incompatible tags (it just returns false). We use
            --  Duplicate_Subexpr_Move_Checks instead of calling Relocate_Node
            --  because the value will be duplicated to check the tags.

            elsif Subp = Eq_Prim_Op then
               null;

            --  No check in presence of suppress flags

            elsif Tag_Checks_Suppressed (Etype (Param))
              or else (Is_Access_Type (Etype (Param))
                         and then Tag_Checks_Suppressed
                                    (Designated_Type (Etype (Param))))
            then
               null;

            --  Optimization: no tag checks if the parameters are identical

            elsif Is_Entity_Name (Param)
              and then Is_Entity_Name (Ctrl_Arg)
              and then Entity (Param) = Entity (Ctrl_Arg)
            then
               null;

            --  Now we need to generate the Tag check

            else
               --  Generate code for tag equality check

               --  Perhaps should have Checks.Apply_Tag_Equality_Check???

               Insert_Action (Ctrl_Arg,
                 Make_Implicit_If_Statement (Call_Node,
                   Condition =>
                     Make_Op_Ne (Loc,
                       Left_Opnd =>
                         Make_Selected_Component (Loc,
                           Prefix => New_Value (Ctrl_Arg),
                           Selector_Name =>
                             New_Occurrence_Of
                               (First_Tag_Component (Typ), Loc)),

                       Right_Opnd =>
                         Make_Selected_Component (Loc,
                           Prefix =>
                             Unchecked_Convert_To (Typ, New_Value (Param)),
                           Selector_Name =>
                             New_Occurrence_Of
                               (First_Tag_Component (Typ), Loc))),

                   Then_Statements =>
                     New_List (New_Constraint_Error (Loc))));
            end if;

            Next_Actual (Param);
         end loop;
      end if;
   end Apply_Tag_Checks;

   ------------------------
   -- Building_Static_DT --
   ------------------------

   function Building_Static_DT (Typ : Entity_Id) return Boolean is
      Root_Typ  : Entity_Id := Root_Type (Typ);
      Static_DT : Boolean;

   begin
      --  Handle private types

      if Present (Full_View (Root_Typ)) then
         Root_Typ := Full_View (Root_Typ);
      end if;

      Static_DT :=
        Building_Static_Dispatch_Tables
          and then Is_Library_Level_Tagged_Type (Typ)

          --  If the type is derived from a CPP class we cannot statically
          --  build the dispatch tables because we must inherit primitives
          --  from the CPP side.

          and then not Is_CPP_Class (Root_Typ);

      if not Static_DT then
         Check_Restriction (Static_Dispatch_Tables, Typ);
      end if;

      return Static_DT;
   end Building_Static_DT;

   ----------------------------------
   -- Building_Static_Secondary_DT --
   ----------------------------------

   function Building_Static_Secondary_DT (Typ : Entity_Id) return Boolean is
      Full_Typ  : Entity_Id := Typ;
      Root_Typ  : Entity_Id := Root_Type (Typ);
      Static_DT : Boolean;

   begin
      --  Handle private types

      if Present (Full_View (Typ)) then
         Full_Typ := Full_View (Typ);
      end if;

      if Present (Full_View (Root_Typ)) then
         Root_Typ := Full_View (Root_Typ);
      end if;

      Static_DT :=
        Building_Static_DT (Full_Typ)
          and then not Is_Interface (Full_Typ)
          and then Has_Interfaces (Full_Typ)
          and then (Full_Typ = Root_Typ
                     or else not Is_Variable_Size_Record (Etype (Full_Typ)));

      if not Static_DT
        and then not Is_Interface (Full_Typ)
        and then Has_Interfaces (Full_Typ)
      then
         Check_Restriction (Static_Dispatch_Tables, Typ);
      end if;

      return Static_DT;
   end Building_Static_Secondary_DT;

   ----------------------------------
   -- Build_Static_Dispatch_Tables --
   ----------------------------------

   procedure Build_Static_Dispatch_Tables (N : Entity_Id) is
      Target_List : List_Id;

      procedure Build_Dispatch_Tables (List : List_Id);
      --  Build the static dispatch table of tagged types found in the list of
      --  declarations. The generated nodes are added at the end of Target_List

      procedure Build_Package_Dispatch_Tables (N : Node_Id);
      --  Build static dispatch tables associated with package declaration N

      ---------------------------
      -- Build_Dispatch_Tables --
      ---------------------------

      procedure Build_Dispatch_Tables (List : List_Id) is
         D : Node_Id;

      begin
         D := First (List);
         while Present (D) loop

            --  Handle nested packages and package bodies recursively. The
            --  generated code is placed on the Target_List established for
            --  the enclosing compilation unit.

            if Nkind (D) = N_Package_Declaration then
               Build_Package_Dispatch_Tables (D);

            elsif Nkind (D) = N_Package_Body then
               Build_Dispatch_Tables (Declarations (D));

            elsif Nkind (D) = N_Package_Body_Stub
              and then Present (Library_Unit (D))
            then
               Build_Dispatch_Tables
                 (Declarations (Proper_Body (Unit (Library_Unit (D)))));

            --  Handle full type declarations and derivations of library level
            --  tagged types

            elsif Nkind (D) in
                    N_Full_Type_Declaration | N_Derived_Type_Definition
              and then Is_Library_Level_Tagged_Type (Defining_Entity (D))
              and then Ekind (Defining_Entity (D)) /= E_Record_Subtype
              and then not Is_Private_Type (Defining_Entity (D))
            then
               --  We do not generate dispatch tables for the internal types
               --  created for a type extension with unknown discriminants
               --  The needed information is shared with the source type,
               --  See Expand_N_Record_Extension.

               if Is_Underlying_Record_View (Defining_Entity (D))
                 or else
                  (not Comes_From_Source (Defining_Entity (D))
                     and then
                       Has_Unknown_Discriminants (Etype (Defining_Entity (D)))
                     and then
                       not Comes_From_Source
                             (First_Subtype (Defining_Entity (D))))
               then
                  null;
               else
                  Insert_List_After_And_Analyze (Last (Target_List),
                    Make_DT (Defining_Entity (D)));
               end if;

            --  Handle private types of library level tagged types. We must
            --  exchange the private and full-view to ensure the correct
            --  expansion. If the full view is a synchronized type ignore
            --  the type because the table will be built for the corresponding
            --  record type, that has its own declaration.

            elsif (Nkind (D) = N_Private_Type_Declaration
                     or else Nkind (D) = N_Private_Extension_Declaration)
               and then Present (Full_View (Defining_Entity (D)))
            then
               declare
                  E1 : constant Entity_Id := Defining_Entity (D);
                  E2 : constant Entity_Id := Full_View (E1);

               begin
                  if Is_Library_Level_Tagged_Type (E2)
                    and then Ekind (E2) /= E_Record_Subtype
                    and then not Is_Concurrent_Type (E2)
                  then
                     Exchange_Declarations (E1);
                     Insert_List_After_And_Analyze (Last (Target_List),
                       Make_DT (E1));
                     Exchange_Declarations (E2);
                  end if;
               end;
            end if;

            Next (D);
         end loop;
      end Build_Dispatch_Tables;

      -----------------------------------
      -- Build_Package_Dispatch_Tables --
      -----------------------------------

      procedure Build_Package_Dispatch_Tables (N : Node_Id) is
         Spec       : constant Node_Id   := Specification (N);
         Id         : constant Entity_Id := Defining_Entity (N);
         Vis_Decls  : constant List_Id   := Visible_Declarations (Spec);
         Priv_Decls : constant List_Id   := Private_Declarations (Spec);

      begin
         Push_Scope (Id);

         if Present (Priv_Decls) then
            Build_Dispatch_Tables (Vis_Decls);
            Build_Dispatch_Tables (Priv_Decls);

         elsif Present (Vis_Decls) then
            Build_Dispatch_Tables (Vis_Decls);
         end if;

         Pop_Scope;
      end Build_Package_Dispatch_Tables;

   --  Start of processing for Build_Static_Dispatch_Tables

   begin
      if not Expander_Active
        or else not Tagged_Type_Expansion
      then
         return;
      end if;

      if Nkind (N) = N_Package_Declaration then
         declare
            Spec       : constant Node_Id := Specification (N);
            Vis_Decls  : constant List_Id := Visible_Declarations (Spec);
            Priv_Decls : constant List_Id := Private_Declarations (Spec);

         begin
            if Present (Priv_Decls)
              and then Is_Non_Empty_List (Priv_Decls)
            then
               Target_List := Priv_Decls;

            elsif not Present (Vis_Decls) then
               Target_List := New_List;
               Set_Private_Declarations (Spec, Target_List);
            else
               Target_List := Vis_Decls;
            end if;

            Build_Package_Dispatch_Tables (N);
         end;

      else pragma Assert (Nkind (N) = N_Package_Body);
         Target_List := Declarations (N);
         Build_Dispatch_Tables (Target_List);
      end if;
   end Build_Static_Dispatch_Tables;

   ------------------------------
   -- Convert_Tag_To_Interface --
   ------------------------------

   function Convert_Tag_To_Interface
     (Typ  : Entity_Id;
      Expr : Node_Id) return Node_Id
   is
      Loc       : constant Source_Ptr := Sloc (Expr);
      Anon_Type : Entity_Id;
      Result    : Node_Id;

   begin
      pragma Assert (Is_Class_Wide_Type (Typ)
        and then Is_Interface (Typ)
        and then
          ((Nkind (Expr) = N_Selected_Component
             and then Is_Tag (Entity (Selector_Name (Expr))))
           or else
           (Nkind (Expr) = N_Function_Call
             and then Is_RTE (Entity (Name (Expr)), RE_Displace))));

      Anon_Type := Create_Itype (E_Anonymous_Access_Type, Expr);
      Set_Directly_Designated_Type (Anon_Type, Typ);
      Set_Etype (Anon_Type, Anon_Type);
      Set_Can_Never_Be_Null (Anon_Type);

      --  Decorate the size and alignment attributes of the anonymous access
      --  type, as required by the back end.

      Layout_Type (Anon_Type);

      if Nkind (Expr) = N_Selected_Component
        and then Is_Tag (Entity (Selector_Name (Expr)))
      then
         Result :=
           Make_Explicit_Dereference (Loc,
             Unchecked_Convert_To (Anon_Type,
               Make_Attribute_Reference (Loc,
                 Prefix         => Expr,
                 Attribute_Name => Name_Address)));
      else
         Result :=
           Make_Explicit_Dereference (Loc,
             Unchecked_Convert_To (Anon_Type, Expr));
      end if;

      return Result;
   end Convert_Tag_To_Interface;

   -------------------
   -- CPP_Num_Prims --
   -------------------

   function CPP_Num_Prims (Typ : Entity_Id) return Nat is
      CPP_Typ  : Entity_Id;
      Tag_Comp : Entity_Id;

   begin
      if not Is_Tagged_Type (Typ)
        or else not Is_CPP_Class (Root_Type (Typ))
      then
         return 0;

      else
         CPP_Typ  := Enclosing_CPP_Parent (Typ);
         Tag_Comp := First_Tag_Component (CPP_Typ);

         --  If number of primitives already set in the tag component, use it

         if Present (Tag_Comp)
           and then Present (DT_Entry_Count (Tag_Comp))
         then
            return UI_To_Int (DT_Entry_Count (Tag_Comp));

         --  Otherwise, count the primitives of the enclosing CPP type

         else
            return List_Length (Primitive_Operations (CPP_Typ));
         end if;
      end if;
   end CPP_Num_Prims;

   ------------------------------
   -- Default_Prim_Op_Position --
   ------------------------------

   function Default_Prim_Op_Position (E : Entity_Id) return Uint is
      TSS_Name : TSS_Name_Type;

   begin
      Get_Name_String (Chars (E));
      TSS_Name :=
        TSS_Name_Type
          (Name_Buffer (Name_Len - TSS_Name'Length + 1 .. Name_Len));

      if Chars (E) = Name_uSize then
         return Uint_1;

      elsif TSS_Name = TSS_Stream_Read then
         return Uint_2;

      elsif TSS_Name = TSS_Stream_Write then
         return Uint_3;

      elsif TSS_Name = TSS_Stream_Input then
         return Uint_4;

      elsif TSS_Name = TSS_Stream_Output then
         return Uint_5;

      elsif Chars (E) = Name_Op_Eq then
         return Uint_6;

      elsif Chars (E) = Name_uAssign then
         return Uint_7;

      elsif TSS_Name = TSS_Deep_Adjust then
         return Uint_8;

      elsif TSS_Name = TSS_Deep_Finalize then
         return Uint_9;

      elsif TSS_Name = TSS_Put_Image then
         return Uint_10;

      --  In VM targets unconditionally allow obtaining the position associated
      --  with predefined interface primitives since in these platforms any
      --  tagged type has these primitives.

      elsif Ada_Version >= Ada_2005 or else not Tagged_Type_Expansion then
         if Chars (E) = Name_uDisp_Asynchronous_Select then
            return Uint_11;

         elsif Chars (E) = Name_uDisp_Conditional_Select then
            return Uint_12;

         elsif Chars (E) = Name_uDisp_Get_Prim_Op_Kind then
            return Uint_13;

         elsif Chars (E) = Name_uDisp_Get_Task_Id then
            return Uint_14;

         elsif Chars (E) = Name_uDisp_Requeue then
            return Uint_15;

         elsif Chars (E) = Name_uDisp_Timed_Select then
            return Uint_16;
         end if;
      end if;

      raise Program_Error;
   end Default_Prim_Op_Position;

   ----------------------
   -- Elab_Flag_Needed --
   ----------------------

   function Elab_Flag_Needed (Typ : Entity_Id) return Boolean is
   begin
      return Ada_Version >= Ada_2005
        and then not Is_Interface (Typ)
        and then Has_Interfaces (Typ)
        and then not Building_Static_DT (Typ);
   end Elab_Flag_Needed;

   -----------------------------
   -- Expand_Dispatching_Call --
   -----------------------------

   procedure Expand_Dispatching_Call (Call_Node : Node_Id) is
      Loc      : constant Source_Ptr := Sloc (Call_Node);
      Call_Typ : constant Entity_Id  := Etype (Call_Node);

      Ctrl_Arg   : constant Node_Id   := Controlling_Argument (Call_Node);
      Ctrl_Typ   : constant Entity_Id := Base_Type (Etype (Ctrl_Arg));
      Param_List : constant List_Id   := Parameter_Associations (Call_Node);

      Subp            : Entity_Id;
      CW_Typ          : Entity_Id;
      New_Call        : Node_Id;
      New_Call_Name   : Node_Id;
      New_Params      : List_Id := No_List;
      Param           : Node_Id;
      Res_Typ         : Entity_Id;
      Subp_Ptr_Typ    : Entity_Id;
      Subp_Typ        : Entity_Id;
      Typ             : Entity_Id;
      Eq_Prim_Op      : Entity_Id := Empty;
      Controlling_Tag : Node_Id;

      procedure Build_Class_Wide_Check (E : Entity_Id);
      --  If the denoted subprogram has a class-wide precondition, generate a
      --  check using that precondition before the dispatching call, because
      --  this is the only class-wide precondition that applies to the call;
      --  otherwise climb to the ancestors searching for the enclosing
      --  overridden primitive of E that has a class-wide precondition (and
      --  use it to generate the check).

      function New_Value (From : Node_Id) return Node_Id;
      --  From is the original Expression. New_Value is equivalent to a call
      --  to Duplicate_Subexpr with an explicit dereference when From is an
      --  access parameter.

      ----------------------------
      -- Build_Class_Wide_Check --
      ----------------------------

      procedure Build_Class_Wide_Check (E : Entity_Id) is
         Subp : Entity_Id := E;

         function Has_Class_Wide_Precondition
           (Subp : Entity_Id) return Boolean;
         --  Evaluates if the dispatching subprogram Subp has a class-wide
         --  precondition.

         function Replace_Formals (N : Node_Id) return Traverse_Result;
         --  Replace occurrences of the formals of the subprogram by the
         --  corresponding actuals in the call, given that this check is
         --  performed outside of the body of the subprogram.

         --  If the dispatching call appears in the same scope as the
         --  declaration of the dispatching subprogram (for example in
         --  the expression of a local expression function), the spec
         --  has not been analyzed yet, in which case we use the Chars
         --  field to recognize intended occurrences of the formals.

         ---------------------------------
         -- Has_Class_Wide_Precondition --
         ---------------------------------

         function Has_Class_Wide_Precondition
           (Subp : Entity_Id) return Boolean
         is
            Prec : Node_Id := Empty;

         begin
            if Present (Contract (Subp))
              and then Present (Pre_Post_Conditions (Contract (Subp)))
            then
               Prec := Pre_Post_Conditions (Contract (Subp));

               while Present (Prec) loop
                  exit when Pragma_Name (Prec) = Name_Precondition
                    and then Class_Present (Prec);
                  Prec := Next_Pragma (Prec);
               end loop;
            end if;

            return Present (Prec)
              and then not Is_Ignored (Prec);
         end Has_Class_Wide_Precondition;

         ---------------------
         -- Replace_Formals --
         ---------------------

         function Replace_Formals (N : Node_Id) return Traverse_Result is
            A : Node_Id;
            F : Entity_Id;
         begin
            if Is_Entity_Name (N) then
               F := First_Formal (Subp);
               A := First_Actual (Call_Node);

               if Present (Entity (N)) and then Is_Formal (Entity (N)) then
                  while Present (F) loop
                     if F = Entity (N) then
                        if not Is_Controlling_Actual (N) then
                           Rewrite (N, New_Copy_Tree (A));

                           --  If the formal is class-wide, and thus not a
                           --  controlling argument, preserve its type because
                           --  it may appear in a nested call with a class-wide
                           --  parameter.

                           if Is_Class_Wide_Type (Etype (F)) then
                              Set_Etype (N, Etype (F));

                           --  Conversely, if this is a controlling argument
                           --  (in a dispatching call in the condition) that
                           --  is a dereference, the source is an access-to-
                           --  -class-wide type, so preserve the dispatching
                           --  nature of the call in the rewritten condition.

                           elsif Nkind (Parent (N)) = N_Explicit_Dereference
                             and then Is_Controlling_Actual (Parent (N))
                           then
                              Set_Controlling_Argument (Parent (Parent (N)),
                                 Parent (N));
                           end if;

                        --  Ensure that the type of the controlling actual
                        --  matches the type of the controlling formal of the
                        --  parent primitive Subp defining the class-wide
                        --  precondition.

                        elsif Is_Class_Wide_Type (Etype (A)) then
                           Rewrite (N,
                             Convert_To
                               (Class_Wide_Type (Etype (F)),
                                New_Copy_Tree (A)));

                        else
                           Rewrite (N,
                             Convert_To
                               (Etype (F),
                                New_Copy_Tree (A)));
                        end if;

                        exit;
                     end if;

                     Next_Formal (F);
                     Next_Actual (A);
                  end loop;

               --  If the node is not analyzed, recognize occurrences of a
               --  formal by name, as would be done when resolving the aspect
               --  expression in the context of the subprogram.

               elsif not Analyzed (N)
                 and then Nkind (N) = N_Identifier
                 and then No (Entity (N))
               then
                  while Present (F) loop
                     if Chars (N) = Chars (F) then
                        Rewrite (N, New_Copy_Tree (A));
                        return Skip;
                     end if;

                     Next_Formal (F);
                     Next_Actual (A);
                  end loop;
               end if;
            end if;

            return OK;
         end Replace_Formals;

         procedure Update is new Traverse_Proc (Replace_Formals);

         --  Local variables

         Str_Loc : constant String := Build_Location_String (Loc);

         A    : Node_Id;
         Cond : Node_Id;
         Msg  : Node_Id;
         Prec : Node_Id;

      --  Start of processing for Build_Class_Wide_Check

      begin
         --  Climb searching for the enclosing class-wide precondition

         while not Has_Class_Wide_Precondition (Subp)
           and then Present (Overridden_Operation (Subp))
         loop
            Subp := Overridden_Operation (Subp);
         end loop;

         --  Locate class-wide precondition, if any

         if Present (Contract (Subp))
           and then Present (Pre_Post_Conditions (Contract (Subp)))
         then
            Prec := Pre_Post_Conditions (Contract (Subp));

            while Present (Prec) loop
               exit when Pragma_Name (Prec) = Name_Precondition
                 and then Class_Present (Prec);
               Prec := Next_Pragma (Prec);
            end loop;

            if No (Prec) or else Is_Ignored (Prec) then
               return;
            end if;

            --  Ensure that the evaluation of the actuals will not produce side
            --  effects (since the check will use a copy of the actuals).

            A := First_Actual (Call_Node);
            while Present (A) loop
               Remove_Side_Effects (A);
               Next_Actual (A);
            end loop;

            --  The expression for the precondition is analyzed within the
            --  generated pragma. The message text is the last parameter of
            --  the generated pragma, indicating source of precondition.

            Cond :=
              New_Copy_Tree
                (Expression (First (Pragma_Argument_Associations (Prec))));
            Update (Cond);

            --  Build message indicating the failed precondition and the
            --  dispatching call that caused it.

            Msg := Expression (Last (Pragma_Argument_Associations (Prec)));
            Name_Len := 0;
            Append (Global_Name_Buffer, Strval (Msg));
            Append (Global_Name_Buffer, " in dispatching call at ");
            Append (Global_Name_Buffer, Str_Loc);
            Msg := Make_String_Literal (Loc, Name_Buffer (1 .. Name_Len));

            Insert_Action (Call_Node,
              Make_If_Statement (Loc,
                Condition       => Make_Op_Not (Loc, Cond),
                Then_Statements => New_List (
                  Make_Procedure_Call_Statement (Loc,
                    Name                   =>
                      New_Occurrence_Of (RTE (RE_Raise_Assert_Failure), Loc),
                    Parameter_Associations => New_List (Msg)))));
         end if;
      end Build_Class_Wide_Check;

      ---------------
      -- New_Value --
      ---------------

      function New_Value (From : Node_Id) return Node_Id is
         Res : constant Node_Id := Duplicate_Subexpr (From);
      begin
         if Is_Access_Type (Etype (From)) then
            return
              Make_Explicit_Dereference (Sloc (From),
                Prefix => Res);
         else
            return Res;
         end if;
      end New_Value;

      --  Local variables

      New_Node          : Node_Id;
      SCIL_Node         : Node_Id := Empty;
      SCIL_Related_Node : Node_Id := Call_Node;

   --  Start of processing for Expand_Dispatching_Call

   begin
      if No_Run_Time_Mode then
         Error_Msg_CRT ("tagged types", Call_Node);
         return;
      end if;

      --  Expand_Dispatching_Call is called directly from the semantics, so we
      --  only proceed if the expander is active.

      if not Expander_Active

        --  And there is no need to expand the call if we are compiling under
        --  restriction No_Dispatching_Calls; the semantic analyzer has
        --  previously notified the violation of this restriction.

        or else Restriction_Active (No_Dispatching_Calls)

        --  No action needed if the dispatching call has been already expanded

        or else Is_Expanded_Dispatching_Call (Name (Call_Node))
      then
         return;
      end if;

      --  Set subprogram. If this is an inherited operation that was
      --  overridden, the body that is being called is its alias.

      Subp := Entity (Name (Call_Node));

      if Present (Alias (Subp))
        and then Is_Inherited_Operation (Subp)
        and then No (DTC_Entity (Subp))
      then
         Subp := Alias (Subp);
      end if;

      Build_Class_Wide_Check (Subp);

      --  Definition of the class-wide type and the tagged type

      --  If the controlling argument is itself a tag rather than a tagged
      --  object, then use the class-wide type associated with the subprogram's
      --  controlling type. This case can occur when a call to an inherited
      --  primitive has an actual that originated from a default parameter
      --  given by a tag-indeterminate call and when there is no other
      --  controlling argument providing the tag (AI-239 requires dispatching).
      --  This capability of dispatching directly by tag is also needed by the
      --  implementation of AI-260 (for the generic dispatching constructors).

      if Is_RTE (Ctrl_Typ, RE_Tag)
        or else Is_RTE (Ctrl_Typ, RE_Interface_Tag)
      then
         CW_Typ := Class_Wide_Type (Find_Dispatching_Type (Subp));

      --  Class_Wide_Type is applied to the expressions used to initialize
      --  CW_Typ, to ensure that CW_Typ always denotes a class-wide type, since
      --  there are cases where the controlling type is resolved to a specific
      --  type (such as for designated types of arguments such as CW'Access).

      elsif Is_Access_Type (Ctrl_Typ) then
         CW_Typ := Class_Wide_Type (Designated_Type (Ctrl_Typ));

      else
         CW_Typ := Class_Wide_Type (Ctrl_Typ);
      end if;

      Typ := Find_Specific_Type (CW_Typ);

      if not Is_Limited_Type (Typ) then
         Eq_Prim_Op := Find_Prim_Op (Typ, Name_Op_Eq);
      end if;

      --  Dispatching call to C++ primitive. Create a new parameter list
      --  with no tag checks.

      New_Params := New_List;

      if Is_CPP_Class (Typ) then
         Param := First_Actual (Call_Node);
         while Present (Param) loop
            Append_To (New_Params, Relocate_Node (Param));
            Next_Actual (Param);
         end loop;

      --  Dispatching call to Ada primitive

      elsif Present (Param_List) then
         Apply_Tag_Checks (Call_Node);

         Param := First_Actual (Call_Node);
         while Present (Param) loop

            --  Cases in which we may have generated run-time checks. Note that
            --  we strip any qualification from Param before comparing with the
            --  already-stripped controlling argument.

            if Unqualify (Param) = Ctrl_Arg or else Subp = Eq_Prim_Op then
               Append_To (New_Params,
                 Duplicate_Subexpr_Move_Checks (Param));

            elsif Nkind (Parent (Param)) /= N_Parameter_Association
              or else not Is_Accessibility_Actual (Parent (Param))
            then
               Append_To (New_Params, Relocate_Node (Param));
            end if;

            Next_Actual (Param);
         end loop;
      end if;

      --  Generate the appropriate subprogram pointer type

      if Etype (Subp) = Typ then
         Res_Typ := CW_Typ;
      else
         Res_Typ := Etype (Subp);
      end if;

      Subp_Typ     := Create_Itype (E_Subprogram_Type, Call_Node);
      Subp_Ptr_Typ := Create_Itype (E_Access_Subprogram_Type, Call_Node);
      Set_Etype          (Subp_Typ, Res_Typ);
      Set_Returns_By_Ref (Subp_Typ, Returns_By_Ref (Subp));
      Set_Convention     (Subp_Typ, Convention (Subp));

      --  Notify gigi that the designated type is a dispatching primitive

      Set_Is_Dispatch_Table_Entity (Subp_Typ);

      --  Create a new list of parameters which is a copy of the old formal
      --  list including the creation of a new set of matching entities.

      declare
         Old_Formal  : Entity_Id := First_Formal (Subp);
         New_Formal  : Entity_Id;
         Last_Formal : Entity_Id := Empty;

      begin
         if Present (Old_Formal) then
            New_Formal := New_Copy (Old_Formal);
            Set_First_Entity (Subp_Typ, New_Formal);
            Param := First_Actual (Call_Node);

            loop
               Set_Scope (New_Formal, Subp_Typ);

               --  Change all the controlling argument types to be class-wide
               --  to avoid a recursion in dispatching.

               if Is_Controlling_Formal (New_Formal) then
                  Set_Etype (New_Formal, Etype (Param));
               end if;

               --  If the type of the formal is an itype, there was code here
               --  introduced in 1998 in revision 1.46, to create a new itype
               --  by copy. This seems useless, and in fact leads to semantic
               --  errors when the itype is the completion of a type derived
               --  from a private type.

               Last_Formal := New_Formal;
               Next_Formal (Old_Formal);
               exit when No (Old_Formal);

               Link_Entities (New_Formal, New_Copy (Old_Formal));
               Next_Entity   (New_Formal);
               Next_Actual   (Param);
            end loop;

            Unlink_Next_Entity (New_Formal);
            Set_Last_Entity (Subp_Typ, Last_Formal);
         end if;

         --  Now that the explicit formals have been duplicated, any extra
         --  formals needed by the subprogram must be duplicated; we know
         --  that extra formals are available because they were added when
         --  the tagged type was frozen (see Expand_Freeze_Record_Type).

         pragma Assert (Is_Frozen (Typ));

         --  Warning: The addition of the extra formals cannot be performed
         --  here invoking Create_Extra_Formals since we must ensure that all
         --  the extra formals of the pointer type and the target subprogram
         --  match (and for functions that return a tagged type the profile of
         --  the built subprogram type always returns a class-wide type, which
         --  may affect the addition of some extra formals).

         if Present (Last_Formal)
           and then Present (Extra_Formal (Last_Formal))
         then
            Old_Formal := Extra_Formal (Last_Formal);
            New_Formal := New_Copy (Old_Formal);
            Set_Scope (New_Formal, Subp_Typ);

            Set_Extra_Formal (Last_Formal, New_Formal);
            Set_Extra_Formals (Subp_Typ, New_Formal);

            if Ekind (Subp) = E_Function
              and then Present (Extra_Accessibility_Of_Result (Subp))
              and then Extra_Accessibility_Of_Result (Subp) = Old_Formal
            then
               Set_Extra_Accessibility_Of_Result (Subp_Typ, New_Formal);
            end if;

            Old_Formal := Extra_Formal (Old_Formal);
            while Present (Old_Formal) loop
               Set_Extra_Formal (New_Formal, New_Copy (Old_Formal));
               New_Formal := Extra_Formal (New_Formal);
               Set_Scope (New_Formal, Subp_Typ);

               if Ekind (Subp) = E_Function
                 and then Present (Extra_Accessibility_Of_Result (Subp))
                 and then Extra_Accessibility_Of_Result (Subp) = Old_Formal
               then
                  Set_Extra_Accessibility_Of_Result (Subp_Typ, New_Formal);
               end if;

               Old_Formal := Extra_Formal (Old_Formal);
            end loop;
         end if;
      end;

      --  Complete description of pointer type, including size information, as
      --  must be done with itypes to prevent order-of-elaboration anomalies
      --  in gigi.

      Set_Etype (Subp_Ptr_Typ, Subp_Ptr_Typ);
      Set_Directly_Designated_Type (Subp_Ptr_Typ, Subp_Typ);
      Set_Convention (Subp_Ptr_Typ, Convention (Subp_Typ));
      Layout_Type    (Subp_Ptr_Typ);

      --  If the controlling argument is a value of type Ada.Tag or an abstract
      --  interface class-wide type then use it directly. Otherwise, the tag
      --  must be extracted from the controlling object.

      if Is_RTE (Ctrl_Typ, RE_Tag)
        or else Is_RTE (Ctrl_Typ, RE_Interface_Tag)
      then
         Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);

      --  Extract the tag from an unchecked type conversion. Done to avoid
      --  the expansion of additional code just to obtain the value of such
      --  tag because the current management of interface type conversions
      --  generates in some cases this unchecked type conversion with the
      --  tag of the object (see Expand_Interface_Conversion).

      elsif Nkind (Ctrl_Arg) = N_Unchecked_Type_Conversion
        and then
          (Is_RTE (Etype (Expression (Ctrl_Arg)), RE_Tag)
            or else
           Is_RTE (Etype (Expression (Ctrl_Arg)), RE_Interface_Tag))
      then
         Controlling_Tag := Duplicate_Subexpr (Expression (Ctrl_Arg));

      --  Ada 2005 (AI-251): Abstract interface class-wide type

      elsif Is_Interface (Ctrl_Typ)
        and then Is_Class_Wide_Type (Ctrl_Typ)
      then
         Controlling_Tag := Duplicate_Subexpr (Ctrl_Arg);

      elsif Is_Access_Type (Ctrl_Typ) then
         Controlling_Tag :=
           Make_Selected_Component (Loc,
             Prefix        =>
               Make_Explicit_Dereference (Loc,
                 Duplicate_Subexpr_Move_Checks (Ctrl_Arg)),
             Selector_Name => New_Occurrence_Of (DTC_Entity (Subp), Loc));

      else
         Controlling_Tag :=
           Make_Selected_Component (Loc,
             Prefix        => Duplicate_Subexpr_Move_Checks (Ctrl_Arg),
             Selector_Name => New_Occurrence_Of (DTC_Entity (Subp), Loc));
      end if;

      --  Handle dispatching calls to predefined primitives

      if Is_Predefined_Dispatching_Operation (Subp)
        or else Is_Predefined_Dispatching_Alias (Subp)
      then
         Build_Get_Predefined_Prim_Op_Address (Loc,
           Tag_Node => Controlling_Tag,
           Position => DT_Position (Subp),
           New_Node => New_Node);

      --  Handle dispatching calls to user-defined primitives

      else
         Build_Get_Prim_Op_Address (Loc,
           Typ      => Underlying_Type (Find_Dispatching_Type (Subp)),
           Tag_Node => Controlling_Tag,
           Position => DT_Position (Subp),
           New_Node => New_Node);
      end if;

      New_Call_Name :=
        Unchecked_Convert_To (Subp_Ptr_Typ, New_Node);

      --  Generate the SCIL node for this dispatching call. Done now because
      --  attribute SCIL_Controlling_Tag must be set after the new call name
      --  is built to reference the nodes that will see the SCIL backend
      --  (because Build_Get_Prim_Op_Address generates an unchecked type
      --  conversion which relocates the controlling tag node).

      if Generate_SCIL then
         SCIL_Node := Make_SCIL_Dispatching_Call (Sloc (Call_Node));
         Set_SCIL_Entity      (SCIL_Node, Typ);
         Set_SCIL_Target_Prim (SCIL_Node, Subp);

         --  Common case: the controlling tag is the tag of an object
         --  (for example, obj.tag)

         if Nkind (Controlling_Tag) = N_Selected_Component then
            Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);

         --  Handle renaming of selected component

         elsif Nkind (Controlling_Tag) = N_Identifier
           and then Nkind (Parent (Entity (Controlling_Tag))) =
                                             N_Object_Renaming_Declaration
           and then Nkind (Name (Parent (Entity (Controlling_Tag)))) =
                                             N_Selected_Component
         then
            Set_SCIL_Controlling_Tag (SCIL_Node,
              Name (Parent (Entity (Controlling_Tag))));

         --  If the controlling tag is an identifier, the SCIL node references
         --  the corresponding object or parameter declaration

         elsif Nkind (Controlling_Tag) = N_Identifier
           and then Nkind (Parent (Entity (Controlling_Tag))) in
                      N_Object_Declaration | N_Parameter_Specification
         then
            Set_SCIL_Controlling_Tag (SCIL_Node,
              Parent (Entity (Controlling_Tag)));

         --  If the controlling tag is a dereference, the SCIL node references
         --  the corresponding object or parameter declaration

         elsif Nkind (Controlling_Tag) = N_Explicit_Dereference
            and then Nkind (Prefix (Controlling_Tag)) = N_Identifier
            and then Nkind (Parent (Entity (Prefix (Controlling_Tag)))) in
                       N_Object_Declaration | N_Parameter_Specification
         then
            Set_SCIL_Controlling_Tag (SCIL_Node,
              Parent (Entity (Prefix (Controlling_Tag))));

         --  For a direct reference of the tag of the type the SCIL node
         --  references the internal object declaration containing the tag
         --  of the type.

         elsif Nkind (Controlling_Tag) = N_Attribute_Reference
            and then Attribute_Name (Controlling_Tag) = Name_Tag
         then
            Set_SCIL_Controlling_Tag (SCIL_Node,
              Parent
                (Node
                  (First_Elmt
                    (Access_Disp_Table (Entity (Prefix (Controlling_Tag)))))));

         --  Interfaces are not supported. For now we leave the SCIL node
         --  decorated with the Controlling_Tag. More work needed here???

         elsif Is_Interface (Etype (Controlling_Tag)) then
            Set_SCIL_Controlling_Tag (SCIL_Node, Controlling_Tag);

         else
            pragma Assert (False);
            null;
         end if;
      end if;

      if Nkind (Call_Node) = N_Function_Call then
         New_Call :=
           Make_Function_Call (Loc,
             Name                   => New_Call_Name,
             Parameter_Associations => New_Params);

         --  If this is a dispatching "=", we must first compare the tags so
         --  we generate: x.tag = y.tag and then x = y

         if Subp = Eq_Prim_Op then
            Param := First_Actual (Call_Node);
            New_Call :=
              Make_And_Then (Loc,
                Left_Opnd =>
                     Make_Op_Eq (Loc,
                       Left_Opnd =>
                         Make_Selected_Component (Loc,
                           Prefix        => New_Value (Param),
                           Selector_Name =>
                             New_Occurrence_Of (First_Tag_Component (Typ),
                                               Loc)),

                       Right_Opnd =>
                         Make_Selected_Component (Loc,
                           Prefix        =>
                             Unchecked_Convert_To (Typ,
                               New_Value (Next_Actual (Param))),
                           Selector_Name =>
                             New_Occurrence_Of
                               (First_Tag_Component (Typ), Loc))),
                Right_Opnd => New_Call);

            SCIL_Related_Node := Right_Opnd (New_Call);
         end if;

      else
         New_Call :=
           Make_Procedure_Call_Statement (Loc,
             Name                   => New_Call_Name,
             Parameter_Associations => New_Params);
      end if;

      --  Register the dispatching call in the call graph nodes table

      Register_CG_Node (Call_Node);

      Rewrite (Call_Node, New_Call);

      --  Associate the SCIL node of this dispatching call

      if Generate_SCIL then
         Set_SCIL_Node (SCIL_Related_Node, SCIL_Node);
      end if;

      --  Suppress all checks during the analysis of the expanded code to avoid
      --  the generation of spurious warnings under ZFP run-time.

      Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
   end Expand_Dispatching_Call;

   ---------------------------------
   -- Expand_Interface_Conversion --
   ---------------------------------

   procedure Expand_Interface_Conversion (N : Node_Id) is
      function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id;
      --  Return the underlying record type of Typ

      ----------------------------
      -- Underlying_Record_Type --
      ----------------------------

      function Underlying_Record_Type (Typ : Entity_Id) return Entity_Id is
         E : Entity_Id := Typ;

      begin
         --  Handle access types

         if Is_Access_Type (E) then
            E := Directly_Designated_Type (E);
         end if;

         --  Handle class-wide types. This conversion can appear explicitly in
         --  the source code. Example: I'Class (Obj)

         if Is_Class_Wide_Type (E) then
            E := Root_Type (E);
         end if;

         --  If the target type is a tagged synchronized type, the dispatch
         --  table info is in the corresponding record type.

         if Is_Concurrent_Type (E) then
            E := Corresponding_Record_Type (E);
         end if;

         --  Handle private types

         E := Underlying_Type (E);

         --  Handle subtypes

         return Base_Type (E);
      end Underlying_Record_Type;

      --  Local variables

      Loc         : constant Source_Ptr := Sloc (N);
      Etyp        : constant Entity_Id  := Etype (N);
      Operand     : constant Node_Id    := Expression (N);
      Operand_Typ : Entity_Id           := Etype (Operand);
      Func        : Node_Id;
      Iface_Typ   : constant Entity_Id  := Underlying_Record_Type (Etype (N));
      Iface_Tag   : Entity_Id;
      Is_Static   : Boolean;

   --  Start of processing for Expand_Interface_Conversion

   begin
      --  Freeze the entity associated with the target interface to have
      --  available the attribute Access_Disp_Table.

      Freeze_Before (N, Iface_Typ);

      --  Ada 2005 (AI-345): Handle synchronized interface type derivations

      if Is_Concurrent_Type (Operand_Typ) then
         Operand_Typ := Base_Type (Corresponding_Record_Type (Operand_Typ));
      end if;

      --  No displacement of the pointer to the object needed when the type of
      --  the operand is not an interface type and the interface is one of
      --  its parent types (since they share the primary dispatch table).

      declare
         Opnd : Entity_Id := Operand_Typ;

      begin
         if Is_Access_Type (Opnd) then
            Opnd := Designated_Type (Opnd);
         end if;

         Opnd := Underlying_Record_Type (Opnd);

         if not Is_Interface (Opnd)
           and then Is_Ancestor (Iface_Typ, Opnd, Use_Full_View => True)
         then
            return;
         end if;

         --  When the type of the operand and the target interface type match,
         --  it is generally safe to skip generating code to displace the
         --  pointer to the object to reference the secondary dispatch table
         --  associated with the target interface type. The exception to this
         --  general rule is when the underlying object of the type conversion
         --  is an object built by means of a dispatching constructor (since in
         --  such case the expansion of the constructor call is a direct call
         --  to an object primitive, i.e. without thunks, and the expansion of
         --  the constructor call adds an explicit conversion to the target
         --  interface type to force the displacement of the pointer to the
         --  object to reference the corresponding secondary dispatch table
         --  (cf. Make_DT and Expand_Dispatching_Constructor_Call)).

         --  At this stage we cannot identify whether the underlying object is
         --  a BIP object and hence we cannot skip generating the code to try
         --  displacing the pointer to the object. However, under configurable
         --  runtime it is safe to skip generating code to displace the pointer
         --  to the object, because generic dispatching constructors are not
         --  supported.

         if Opnd = Iface_Typ and then not RTE_Available (RE_Displace) then
            return;
         end if;
      end;

      --  Evaluate if we can statically displace the pointer to the object

      declare
         Opnd_Typ : constant Node_Id := Underlying_Record_Type (Operand_Typ);

      begin
         Is_Static :=
            not Is_Interface (Opnd_Typ)
              and then Interface_Present_In_Ancestor
                         (Typ   => Opnd_Typ,
                          Iface => Iface_Typ)
              and then (Etype (Opnd_Typ) = Opnd_Typ
                         or else not
                           Is_Variable_Size_Record (Etype (Opnd_Typ)));
      end;

      if not Tagged_Type_Expansion then
         return;

      --  A static conversion to an interface type that is not class-wide is
      --  curious but legal if the interface operation is a null procedure.
      --  If the operation is abstract it will be rejected later.

      elsif Is_Static
        and then Is_Interface (Etype (N))
        and then not Is_Class_Wide_Type (Etype (N))
        and then Comes_From_Source (N)
      then
         Rewrite (N, Unchecked_Convert_To (Etype (N), N));
         Analyze (N);
         return;
      end if;

      if not Is_Static then

         --  Give error if configurable run-time and Displace not available

         if not RTE_Available (RE_Displace) then
            Error_Msg_CRT ("dynamic interface conversion", N);
            return;
         end if;

         --  Handle conversion of access-to-class-wide interface types. Target
         --  can be an access to an object or an access to another class-wide
         --  interface (see -1- and -2- in the following example):

         --     type Iface1_Ref is access all Iface1'Class;
         --     type Iface2_Ref is access all Iface1'Class;

         --     Acc1 : Iface1_Ref := new ...
         --     Obj  : Obj_Ref    := Obj_Ref (Acc);    -- 1
         --     Acc2 : Iface2_Ref := Iface2_Ref (Acc); -- 2

         if Is_Access_Type (Operand_Typ) then
            Rewrite (N,
              Unchecked_Convert_To (Etype (N),
                Make_Function_Call (Loc,
                  Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
                  Parameter_Associations => New_List (

                    Unchecked_Convert_To (RTE (RE_Address),
                      Relocate_Node (Expression (N))),

                    New_Occurrence_Of
                      (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
                       Loc)))));

            Analyze (N);
            return;
         end if;

         Rewrite (N,
           Make_Function_Call (Loc,
             Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
             Parameter_Associations => New_List (
               Make_Attribute_Reference (Loc,
                 Prefix => Relocate_Node (Expression (N)),
                 Attribute_Name => Name_Address),

               New_Occurrence_Of
                 (Node (First_Elmt (Access_Disp_Table (Iface_Typ))),
                  Loc))));

         Analyze (N);

         --  If target is a class-wide interface, change the type of the data
         --  returned by IW_Convert to indicate this is a dispatching call.

         declare
            New_Itype : Entity_Id;

         begin
            New_Itype := Create_Itype (E_Anonymous_Access_Type, N);
            Set_Etype (New_Itype, New_Itype);
            Set_Directly_Designated_Type (New_Itype, Etyp);

            Rewrite (N,
              Make_Explicit_Dereference (Loc,
                Prefix =>
                  Unchecked_Convert_To (New_Itype, Relocate_Node (N))));
            Analyze (N);
            Freeze_Itype (New_Itype, N);

            return;
         end;
      end if;

      Iface_Tag := Find_Interface_Tag (Operand_Typ, Iface_Typ);
      pragma Assert (Present (Iface_Tag));

      --  Keep separate access types to interfaces because one internal
      --  function is used to handle the null value (see following comments)

      if not Is_Access_Type (Etype (N)) then

         --  Statically displace the pointer to the object to reference the
         --  component containing the secondary dispatch table.

         Rewrite (N,
           Convert_Tag_To_Interface (Class_Wide_Type (Iface_Typ),
             Make_Selected_Component (Loc,
               Prefix => Relocate_Node (Expression (N)),
               Selector_Name => New_Occurrence_Of (Iface_Tag, Loc))));

      else
         --  Build internal function to handle the case in which the actual is
         --  null. If the actual is null returns null because no displacement
         --  is required; otherwise performs a type conversion that will be
         --  expanded in the code that returns the value of the displaced
         --  actual. That is:

         --     function Func (O : Address) return Iface_Typ is
         --        type Op_Typ is access all Operand_Typ;
         --        Aux : Op_Typ := To_Op_Typ (O);
         --     begin
         --        if O = Null_Address then
         --           return null;
         --        else
         --           return Iface_Typ!(Aux.Iface_Tag'Address);
         --        end if;
         --     end Func;

         declare
            Desig_Typ    : Entity_Id;
            Fent         : Entity_Id;
            New_Typ_Decl : Node_Id;
            Stats        : List_Id;

         begin
            Desig_Typ := Etype (Expression (N));

            if Is_Access_Type (Desig_Typ) then
               Desig_Typ :=
                 Available_View (Directly_Designated_Type (Desig_Typ));
            end if;

            if Is_Concurrent_Type (Desig_Typ) then
               Desig_Typ := Base_Type (Corresponding_Record_Type (Desig_Typ));
            end if;

            New_Typ_Decl :=
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'T'),
                Type_Definition =>
                  Make_Access_To_Object_Definition (Loc,
                    All_Present            => True,
                    Null_Exclusion_Present => False,
                    Constant_Present       => False,
                    Subtype_Indication     =>
                      New_Occurrence_Of (Desig_Typ, Loc)));

            Stats := New_List (
              Make_Simple_Return_Statement (Loc,
                Unchecked_Convert_To (Etype (N),
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                      Make_Selected_Component (Loc,
                        Prefix        =>
                          Unchecked_Convert_To
                            (Defining_Identifier (New_Typ_Decl),
                             Make_Identifier (Loc, Name_uO)),
                        Selector_Name =>
                          New_Occurrence_Of (Iface_Tag, Loc)),
                    Attribute_Name => Name_Address))));

            --  If the type is null-excluding, no need for the null branch.
            --  Otherwise we need to check for it and return null.

            if not Can_Never_Be_Null (Etype (N)) then
               Stats := New_List (
                 Make_If_Statement (Loc,
                  Condition       =>
                    Make_Op_Eq (Loc,
                       Left_Opnd  => Make_Identifier (Loc, Name_uO),
                       Right_Opnd => New_Occurrence_Of
                                       (RTE (RE_Null_Address), Loc)),

                 Then_Statements => New_List (
                   Make_Simple_Return_Statement (Loc, Make_Null (Loc))),
                 Else_Statements => Stats));
            end if;

            Fent := Make_Temporary (Loc, 'F');
            Func :=
              Make_Subprogram_Body (Loc,
                Specification =>
                  Make_Function_Specification (Loc,
                    Defining_Unit_Name => Fent,

                    Parameter_Specifications => New_List (
                      Make_Parameter_Specification (Loc,
                        Defining_Identifier =>
                          Make_Defining_Identifier (Loc, Name_uO),
                        Parameter_Type =>
                          New_Occurrence_Of (RTE (RE_Address), Loc))),

                    Result_Definition =>
                      New_Occurrence_Of (Etype (N), Loc)),

                Declarations => New_List (New_Typ_Decl),

                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc, Stats));

            --  Place function body before the expression containing the
            --  conversion. We suppress all checks because the body of the
            --  internally generated function already takes care of the case
            --  in which the actual is null; therefore there is no need to
            --  double check that the pointer is not null when the program
            --  executes the alternative that performs the type conversion).

            Insert_Action (N, Func, Suppress => All_Checks);

            if Is_Access_Type (Etype (Expression (N))) then

               --  Generate: Func (Address!(Expression))

               Rewrite (N,
                 Make_Function_Call (Loc,
                   Name                   => New_Occurrence_Of (Fent, Loc),
                   Parameter_Associations => New_List (
                     Unchecked_Convert_To (RTE (RE_Address),
                       Relocate_Node (Expression (N))))));

            else
               --  Generate: Func (Operand_Typ!(Expression)'Address)

               Rewrite (N,
                 Make_Function_Call (Loc,
                   Name                   => New_Occurrence_Of (Fent, Loc),
                   Parameter_Associations => New_List (
                     Make_Attribute_Reference (Loc,
                       Prefix  => Unchecked_Convert_To (Operand_Typ,
                                    Relocate_Node (Expression (N))),
                       Attribute_Name => Name_Address))));
            end if;
         end;
      end if;

      Analyze (N);
   end Expand_Interface_Conversion;

   ------------------------------
   -- Expand_Interface_Actuals --
   ------------------------------

   procedure Expand_Interface_Actuals (Call_Node : Node_Id) is
      Actual     : Node_Id;
      Actual_Dup : Node_Id;
      Actual_Typ : Entity_Id;
      Anon       : Entity_Id;
      Conversion : Node_Id;
      Formal     : Entity_Id;
      Formal_Typ : Entity_Id;
      Subp       : Entity_Id;
      Formal_DDT : Entity_Id := Empty;  -- initialize to prevent warning
      Actual_DDT : Entity_Id := Empty;  -- initialize to prevent warning

   begin
      --  This subprogram is called directly from the semantics, so we need a
      --  check to see whether expansion is active before proceeding.

      if not Expander_Active then
         return;
      end if;

      --  Call using access to subprogram with explicit dereference

      if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
         Subp := Etype (Name (Call_Node));

      --  Call using selected component

      elsif Nkind (Name (Call_Node)) = N_Selected_Component then
         Subp := Entity (Selector_Name (Name (Call_Node)));

      --  Call using direct name

      else
         Subp := Entity (Name (Call_Node));
      end if;

      --  Ada 2005 (AI-251): Look for interface type formals to force "this"
      --  displacement

      Formal := First_Formal (Subp);
      Actual := First_Actual (Call_Node);
      while Present (Formal) loop
         Formal_Typ := Etype (Formal);

         if Has_Non_Limited_View (Formal_Typ) then
            Formal_Typ := Non_Limited_View (Formal_Typ);
         end if;

         if Ekind (Formal_Typ) = E_Record_Type_With_Private then
            Formal_Typ := Full_View (Formal_Typ);
         end if;

         if Is_Access_Type (Formal_Typ) then
            Formal_DDT := Directly_Designated_Type (Formal_Typ);

            if Has_Non_Limited_View (Formal_DDT) then
               Formal_DDT := Non_Limited_View (Formal_DDT);
            end if;
         end if;

         Actual_Typ := Etype (Actual);

         if Has_Non_Limited_View (Actual_Typ) then
            Actual_Typ := Non_Limited_View (Actual_Typ);
         end if;

         if Is_Access_Type (Actual_Typ) then
            Actual_DDT := Directly_Designated_Type (Actual_Typ);

            if Has_Non_Limited_View (Actual_DDT) then
               Actual_DDT := Non_Limited_View (Actual_DDT);
            end if;
         end if;

         if Is_Interface (Formal_Typ)
           and then Is_Class_Wide_Type (Formal_Typ)
         then
            --  No need to displace the pointer if the type of the actual
            --  coincides with the type of the formal.

            if Actual_Typ = Formal_Typ then
               null;

            --  No need to displace the pointer if the interface type is a
            --  parent of the type of the actual because in this case the
            --  interface primitives are located in the primary dispatch table.

            elsif Is_Ancestor (Formal_Typ, Actual_Typ,
                               Use_Full_View => True)
            then
               null;

            --  Implicit conversion to the class-wide formal type to force the
            --  displacement of the pointer.

            else
               --  Normally, expansion of actuals for calls to build-in-place
               --  functions happens as part of Expand_Actuals, but in this
               --  case the call will be wrapped in a conversion and soon after
               --  expanded further to handle the displacement for a class-wide
               --  interface conversion, so if this is a BIP call then we need
               --  to handle it now.

               if Is_Build_In_Place_Function_Call (Actual) then
                  Make_Build_In_Place_Call_In_Anonymous_Context (Actual);
               end if;

               Conversion := Convert_To (Formal_Typ, Relocate_Node (Actual));
               Rewrite (Actual, Conversion);
               Analyze_And_Resolve (Actual, Formal_Typ);
            end if;

         --  Access to class-wide interface type

         elsif Is_Access_Type (Formal_Typ)
           and then Is_Interface (Formal_DDT)
           and then Is_Class_Wide_Type (Formal_DDT)
           and then Interface_Present_In_Ancestor
                      (Typ   => Actual_DDT,
                       Iface => Etype (Formal_DDT))
         then
            --  Handle attributes 'Access and 'Unchecked_Access

            if Nkind (Actual) = N_Attribute_Reference
              and then
               (Attribute_Name (Actual) = Name_Access
                 or else Attribute_Name (Actual) = Name_Unchecked_Access)
            then
               --  This case must have been handled by the analysis and
               --  expansion of 'Access. The only exception is when types
               --  match and no further expansion is required.

               pragma Assert (Base_Type (Etype (Prefix (Actual)))
                               = Base_Type (Formal_DDT));
               null;

            --  No need to displace the pointer if the type of the actual
            --  coincides with the type of the formal.

            elsif Actual_DDT = Formal_DDT then
               null;

            --  No need to displace the pointer if the interface type is
            --  a parent of the type of the actual because in this case the
            --  interface primitives are located in the primary dispatch table.

            elsif Is_Ancestor (Formal_DDT, Actual_DDT,
                               Use_Full_View => True)
            then
               null;

            else
               Actual_Dup := Relocate_Node (Actual);

               if From_Limited_With (Actual_Typ) then

                  --  If the type of the actual parameter comes from a limited
                  --  with_clause and the nonlimited view is already available,
                  --  we replace the anonymous access type by a duplicate
                  --  declaration whose designated type is the nonlimited view.

                  if Has_Non_Limited_View (Actual_DDT) then
                     Anon := New_Copy (Actual_Typ);

                     if Is_Itype (Anon) then
                        Set_Scope (Anon, Current_Scope);
                     end if;

                     Set_Directly_Designated_Type
                       (Anon, Non_Limited_View (Actual_DDT));
                     Set_Etype (Actual_Dup, Anon);
                  end if;
               end if;

               Conversion := Convert_To (Formal_Typ, Actual_Dup);
               Rewrite (Actual, Conversion);
               Analyze_And_Resolve (Actual, Formal_Typ);
            end if;
         end if;

         Next_Actual (Actual);
         Next_Formal (Formal);
      end loop;
   end Expand_Interface_Actuals;

   ----------------------------
   -- Expand_Interface_Thunk --
   ----------------------------

   procedure Expand_Interface_Thunk
     (Prim       : Node_Id;
      Thunk_Id   : out Entity_Id;
      Thunk_Code : out Node_Id;
      Iface      : Entity_Id)
   is
      Loc     : constant Source_Ptr := Sloc (Prim);
      Actuals : constant List_Id    := New_List;
      Decl    : constant List_Id    := New_List;
      Formals : constant List_Id    := New_List;
      Target  : constant Entity_Id  := Ultimate_Alias (Prim);

      Decl_1        : Node_Id;
      Decl_2        : Node_Id;
      Expr          : Node_Id;
      Formal        : Node_Id;
      Ftyp          : Entity_Id;
      Iface_Formal  : Node_Id := Empty;  -- initialize to prevent warning
      Is_Predef_Op  : constant Boolean :=
                        Is_Predefined_Dispatching_Operation (Prim)
                          or else Is_Predefined_Dispatching_Operation (Target);
      New_Arg       : Node_Id;
      Offset_To_Top : Node_Id;
      Target_Formal : Entity_Id;

   begin
      Thunk_Id   := Empty;
      Thunk_Code := Empty;

      --  No thunk needed if the primitive has been eliminated

      if Is_Eliminated (Target) then
         return;

      --  In case of primitives that are functions without formals and a
      --  controlling result there is no need to build the thunk.

      elsif not Present (First_Formal (Target)) then
         pragma Assert (Ekind (Target) = E_Function
           and then Has_Controlling_Result (Target));
         return;
      end if;

      --  Duplicate the formals of the Target primitive. In the thunk, the type
      --  of the controlling formal is the covered interface type (instead of
      --  the target tagged type). Done to avoid problems with discriminated
      --  tagged types because, if the controlling type has discriminants with
      --  default values, then the type conversions done inside the body of
      --  the thunk (after the displacement of the pointer to the base of the
      --  actual object) generate code that modify its contents.

      --  Note: This special management is not done for predefined primitives
      --  because they don't have available the Interface_Alias attribute (see
      --  Sem_Ch3.Add_Internal_Interface_Entities).

      if not Is_Predef_Op then
         Iface_Formal := First_Formal (Interface_Alias (Prim));
      end if;

      Formal := First_Formal (Target);
      while Present (Formal) loop
         Ftyp := Etype (Formal);

         --  Use the interface type as the type of the controlling formal (see
         --  comment above).

         if not Is_Controlling_Formal (Formal) then
            Ftyp := Etype (Formal);
            Expr := New_Copy_Tree (Expression (Parent (Formal)));

         --  For predefined primitives the controlling type of the thunk is
         --  the interface type passed by the caller (since they don't have
         --  available the Interface_Alias attribute; see comment above).

         elsif Is_Predef_Op then
            Ftyp := Iface;
            Expr := Empty;

         else
            Ftyp := Etype (Iface_Formal);
            Expr := Empty;

            --  Sanity check performed to ensure the proper controlling type
            --  when the thunk has exactly one controlling parameter and it
            --  comes first. In such case the GCC backend reuses the C++
            --  thunks machinery which perform a computation equivalent to
            --  the code generated by the expander; for other cases the GCC
            --  backend translates the expanded code unmodified. However, as
            --  a generalization, the check is performed for all controlling
            --  types.

            if Is_Access_Type (Ftyp) then
               pragma Assert (Base_Type (Designated_Type (Ftyp)) = Iface);
               null;
            else
               Ftyp := Base_Type (Ftyp);
               pragma Assert (Ftyp = Iface);
            end if;
         end if;

         Append_To (Formals,
           Make_Parameter_Specification (Loc,
             Defining_Identifier =>
               Make_Defining_Identifier (Sloc (Formal),
                 Chars => Chars (Formal)),
             In_Present => In_Present (Parent (Formal)),
             Out_Present => Out_Present (Parent (Formal)),
             Parameter_Type => New_Occurrence_Of (Ftyp, Loc),
             Expression => Expr));

         if not Is_Predef_Op then
            Next_Formal (Iface_Formal);
         end if;

         Next_Formal (Formal);
      end loop;

      Target_Formal := First_Formal (Target);
      Formal        := First (Formals);
      while Present (Formal) loop

         --  If the parent is a constrained discriminated type, then the
         --  primitive operation will have been defined on a first subtype.
         --  For proper matching with controlling type, use base type.

         if Ekind (Target_Formal) = E_In_Parameter
           and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
         then
            Ftyp :=
              Base_Type (Directly_Designated_Type (Etype (Target_Formal)));
         else
            Ftyp := Base_Type (Etype (Target_Formal));
         end if;

         --  For concurrent types, the relevant information is found in the
         --  Corresponding_Record_Type, rather than the type entity itself.

         if Is_Concurrent_Type (Ftyp) then
            Ftyp := Corresponding_Record_Type (Ftyp);
         end if;

         if Ekind (Target_Formal) = E_In_Parameter
           and then Ekind (Etype (Target_Formal)) = E_Anonymous_Access_Type
           and then Is_Controlling_Formal (Target_Formal)
         then
            --  Generate:
            --     type T is access all <<type of the target formal>>
            --     S : Storage_Offset := Storage_Offset!(Formal)
            --                            + Offset_To_Top (address!(Formal))

            Decl_2 :=
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'T'),
                Type_Definition =>
                  Make_Access_To_Object_Definition (Loc,
                    All_Present            => True,
                    Null_Exclusion_Present => False,
                    Constant_Present       => False,
                    Subtype_Indication     =>
                      New_Occurrence_Of (Ftyp, Loc)));

            New_Arg :=
              Unchecked_Convert_To (RTE (RE_Address),
                New_Occurrence_Of (Defining_Identifier (Formal), Loc));

            if not RTE_Available (RE_Offset_To_Top) then
               Offset_To_Top :=
                 Build_Offset_To_Top (Loc, New_Arg);
            else
               Offset_To_Top :=
                 Make_Function_Call (Loc,
                   Name => New_Occurrence_Of (RTE (RE_Offset_To_Top), Loc),
                   Parameter_Associations => New_List (New_Arg));
            end if;

            Decl_1 :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'S'),
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
                Expression          =>
                  Make_Op_Add (Loc,
                    Left_Opnd  =>
                      Unchecked_Convert_To
                        (RTE (RE_Storage_Offset),
                         New_Occurrence_Of
                           (Defining_Identifier (Formal), Loc)),
                     Right_Opnd =>
                       Offset_To_Top));

            Append_To (Decl, Decl_2);
            Append_To (Decl, Decl_1);

            --  Reference the new actual. Generate:
            --    T!(S)

            Append_To (Actuals,
              Unchecked_Convert_To
                (Defining_Identifier (Decl_2),
                 New_Occurrence_Of (Defining_Identifier (Decl_1), Loc)));

         elsif Is_Controlling_Formal (Target_Formal) then

            --  Generate:
            --     S1 : Storage_Offset := Storage_Offset!(Formal'Address)
            --                             + Offset_To_Top (Formal'Address)
            --     S2 : Addr_Ptr := Addr_Ptr!(S1)

            New_Arg :=
              Make_Attribute_Reference (Loc,
                Prefix =>
                  New_Occurrence_Of (Defining_Identifier (Formal), Loc),
                Attribute_Name =>
                  Name_Address);

            if not RTE_Available (RE_Offset_To_Top) then
               Offset_To_Top :=
                 Build_Offset_To_Top (Loc, New_Arg);
            else
               Offset_To_Top :=
                 Make_Function_Call (Loc,
                   Name => New_Occurrence_Of (RTE (RE_Offset_To_Top), Loc),
                   Parameter_Associations => New_List (New_Arg));
            end if;

            Decl_1 :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'S'),
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
                Expression          =>
                  Make_Op_Add (Loc,
                    Left_Opnd =>
                      Unchecked_Convert_To
                        (RTE (RE_Storage_Offset),
                         Make_Attribute_Reference (Loc,
                           Prefix =>
                             New_Occurrence_Of
                               (Defining_Identifier (Formal), Loc),
                           Attribute_Name => Name_Address)),
                    Right_Opnd =>
                      Offset_To_Top));

            Decl_2 :=
              Make_Object_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'S'),
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Addr_Ptr), Loc),
                Expression          =>
                  Unchecked_Convert_To
                    (RTE (RE_Addr_Ptr),
                     New_Occurrence_Of (Defining_Identifier (Decl_1), Loc)));

            Append_To (Decl, Decl_1);
            Append_To (Decl, Decl_2);

            --  Reference the new actual, generate:
            --    Target_Formal (S2.all)

            Append_To (Actuals,
              Unchecked_Convert_To (Ftyp,
                 Make_Explicit_Dereference (Loc,
                   New_Occurrence_Of (Defining_Identifier (Decl_2), Loc))));

         --  Ensure proper matching of access types. Required to avoid
         --  reporting spurious errors.

         elsif Is_Access_Type (Etype (Target_Formal)) then
            Append_To (Actuals,
              Unchecked_Convert_To (Base_Type (Etype (Target_Formal)),
                New_Occurrence_Of (Defining_Identifier (Formal), Loc)));

         --  No special management required for this actual

         else
            Append_To (Actuals,
               New_Occurrence_Of (Defining_Identifier (Formal), Loc));
         end if;

         Next_Formal (Target_Formal);
         Next (Formal);
      end loop;

      Thunk_Id := Make_Temporary (Loc, 'T');

      --  Note: any change to this symbol name needs to be coordinated
      --  with GNATcoverage, as that tool relies on it to identify
      --  thunks and exclude them from source coverage analysis.

      Mutate_Ekind (Thunk_Id, Ekind (Prim));
      Set_Is_Thunk (Thunk_Id);
      Set_Convention (Thunk_Id, Convention (Prim));
      Set_Needs_Debug_Info (Thunk_Id, Needs_Debug_Info (Target));
      Set_Thunk_Entity (Thunk_Id, Target);

      --  Procedure case

      if Ekind (Target) = E_Procedure then
         Thunk_Code :=
           Make_Subprogram_Body (Loc,
              Specification =>
                Make_Procedure_Specification (Loc,
                  Defining_Unit_Name       => Thunk_Id,
                  Parameter_Specifications => Formals),
              Declarations => Decl,
              Handled_Statement_Sequence =>
                Make_Handled_Sequence_Of_Statements (Loc,
                  Statements => New_List (
                    Make_Procedure_Call_Statement (Loc,
                      Name => New_Occurrence_Of (Target, Loc),
                      Parameter_Associations => Actuals))));

      --  Function case

      else pragma Assert (Ekind (Target) = E_Function);
         declare
            Result_Def : Node_Id;
            Call_Node  : Node_Id;

         begin
            Call_Node :=
              Make_Function_Call (Loc,
                Name                   => New_Occurrence_Of (Target, Loc),
                Parameter_Associations => Actuals);

            if not Is_Interface (Etype (Prim)) then
               Result_Def := New_Copy (Result_Definition (Parent (Target)));

            --  Thunk of function returning a class-wide interface object. No
            --  extra displacement needed since the displacement is generated
            --  in the return statement of Prim. Example:

            --    type Iface is interface ...
            --    function F (O : Iface) return Iface'Class;

            --    type T is new ... and Iface with ...
            --    function F (O : T) return Iface'Class;

            elsif Is_Class_Wide_Type (Etype (Prim)) then
               Result_Def := New_Occurrence_Of (Etype (Prim), Loc);

            --  Thunk of function returning an interface object. Displacement
            --  needed. Example:

            --    type Iface is interface ...
            --    function F (O : Iface) return Iface;

            --    type T is new ... and Iface with ...
            --    function F (O : T) return T;

            else
               Result_Def :=
                 New_Occurrence_Of (Class_Wide_Type (Etype (Prim)), Loc);

               --  Adding implicit conversion to force the displacement of
               --  the pointer to the object to reference the corresponding
               --  secondary dispatch table.

               Call_Node :=
                 Make_Type_Conversion (Loc,
                   Subtype_Mark =>
                     New_Occurrence_Of (Class_Wide_Type (Etype (Prim)), Loc),
                   Expression   => Relocate_Node (Call_Node));
            end if;

            Thunk_Code :=
              Make_Subprogram_Body (Loc,
                Specification              =>
                  Make_Function_Specification (Loc,
                    Defining_Unit_Name       => Thunk_Id,
                    Parameter_Specifications => Formals,
                    Result_Definition        => Result_Def),
                Declarations               => Decl,
                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements => New_List (
                      Make_Simple_Return_Statement (Loc, Call_Node))));
         end;
      end if;
   end Expand_Interface_Thunk;

   --------------------------
   -- Has_CPP_Constructors --
   --------------------------

   function Has_CPP_Constructors (Typ : Entity_Id) return Boolean is
      E : Entity_Id;

   begin
      --  Look for the constructor entities

      E := Next_Entity (Typ);
      while Present (E) loop
         if Ekind (E) = E_Function and then Is_Constructor (E) then
            return True;
         end if;

         Next_Entity (E);
      end loop;

      return False;
   end Has_CPP_Constructors;

   ------------
   -- Has_DT --
   ------------

   function Has_DT (Typ : Entity_Id) return Boolean is
   begin
      return not Is_Interface (Typ)
        and then not Restriction_Active (No_Dispatching_Calls);
   end Has_DT;

   ----------------------------------
   -- Is_Expanded_Dispatching_Call --
   ----------------------------------

   function Is_Expanded_Dispatching_Call (N : Node_Id) return Boolean is
   begin
      return Nkind (N) in N_Subprogram_Call
        and then Nkind (Name (N)) = N_Explicit_Dereference
        and then Is_Dispatch_Table_Entity (Etype (Name (N)));
   end Is_Expanded_Dispatching_Call;

   -------------------------------------
   -- Is_Predefined_Dispatching_Alias --
   -------------------------------------

   function Is_Predefined_Dispatching_Alias (Prim : Entity_Id) return Boolean
   is
   begin
      return not Is_Predefined_Dispatching_Operation (Prim)
        and then Present (Alias (Prim))
        and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim));
   end Is_Predefined_Dispatching_Alias;

   ----------------------------------------
   -- Make_Disp_Asynchronous_Select_Body --
   ----------------------------------------

   --  For interface types, generate:

   --     procedure _Disp_Asynchronous_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        B : out System.Storage_Elements.Dummy_Communication_Block;
   --        F : out Boolean)
   --     is
   --     begin
   --        F := False;
   --        C := Ada.Tags.POK_Function;
   --     end _Disp_Asynchronous_Select;

   --  For protected types, generate:

   --     procedure _Disp_Asynchronous_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        B : out System.Storage_Elements.Dummy_Communication_Block;
   --        F : out Boolean)
   --     is
   --        I   : Integer :=
   --                Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
   --        Bnn : System.Tasking.Protected_Objects.Operations.
   --                Communication_Block;
   --     begin
   --        System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
   --          (T._object'Access,
   --           System.Tasking.Protected_Objects.Protected_Entry_Index (I),
   --           P,
   --           System.Tasking.Asynchronous_Call,
   --           Bnn);
   --        B := System.Storage_Elements.Dummy_Communication_Block (Bnn);
   --     end _Disp_Asynchronous_Select;

   --  For task types, generate:

   --     procedure _Disp_Asynchronous_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        B : out System.Storage_Elements.Dummy_Communication_Block;
   --        F : out Boolean)
   --     is
   --        I   : Integer :=
   --                Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
   --     begin
   --        System.Tasking.Rendezvous.Task_Entry_Call
   --          (T._task_id,
   --           System.Tasking.Task_Entry_Index (I),
   --           P,
   --           System.Tasking.Asynchronous_Call,
   --           F);
   --     end _Disp_Asynchronous_Select;

   function Make_Disp_Asynchronous_Select_Body
     (Typ : Entity_Id) return Node_Id
   is
      Com_Block : Entity_Id;
      Conc_Typ  : Entity_Id           := Empty;
      Decls     : constant List_Id    := New_List;
      Loc       : constant Source_Ptr := Sloc (Typ);
      Obj_Ref   : Node_Id;
      Stmts     : constant List_Id    := New_List;
      Tag_Node  : Node_Id;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  Null body is generated for interface types

      if Is_Interface (Typ) then
         return
           Make_Subprogram_Body (Loc,
             Specification              =>
               Make_Disp_Asynchronous_Select_Spec (Typ),
             Declarations               => New_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 New_List (
                   Make_Assignment_Statement (Loc,
                     Name       => Make_Identifier (Loc, Name_uF),
                     Expression => New_Occurrence_Of (Standard_False, Loc)))));
      end if;

      if Is_Concurrent_Record_Type (Typ) then
         Conc_Typ := Corresponding_Concurrent_Type (Typ);

         --  Generate:
         --    I : Integer :=
         --          Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);

         --  where I will be used to capture the entry index of the primitive
         --  wrapper at position S.

         if Tagged_Type_Expansion then
            Tag_Node :=
              Unchecked_Convert_To (RTE (RE_Tag),
                New_Occurrence_Of
                  (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));
         else
            Tag_Node :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Typ, Loc),
                Attribute_Name => Name_Tag);
         end if;

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier =>
               Make_Defining_Identifier (Loc, Name_uI),
             Object_Definition   =>
               New_Occurrence_Of (Standard_Integer, Loc),
             Expression          =>
               Make_Function_Call (Loc,
                 Name                   =>
                   New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
                 Parameter_Associations =>
                   New_List (Tag_Node, Make_Identifier (Loc, Name_uS)))));

         if Ekind (Conc_Typ) = E_Protected_Type then

            --  Generate:
            --    Bnn : Communication_Block;

            Com_Block := Make_Temporary (Loc, 'B');
            Append_To (Decls,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Com_Block,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Communication_Block), Loc)));

            --  Build T._object'Access for calls below

            Obj_Ref :=
               Make_Attribute_Reference (Loc,
                 Attribute_Name => Name_Unchecked_Access,
                 Prefix         =>
                   Make_Selected_Component (Loc,
                     Prefix        => Make_Identifier (Loc, Name_uT),
                     Selector_Name => Make_Identifier (Loc, Name_uObject)));

            case Corresponding_Runtime_Package (Conc_Typ) is
               when System_Tasking_Protected_Objects_Entries =>

                  --  Generate:
                  --    Protected_Entry_Call
                  --      (T._object'Access,            --  Object
                  --       Protected_Entry_Index! (I),  --  E
                  --       P,                           --  Uninterpreted_Data
                  --       Asynchronous_Call,           --  Mode
                  --       Bnn);                        --  Communication_Block

                  --  where T is the protected object, I is the entry index, P
                  --  is the wrapped parameters and B is the name of the
                  --  communication block.

                  Append_To (Stmts,
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of (RTE (RE_Protected_Entry_Call), Loc),
                      Parameter_Associations =>
                        New_List (
                          Obj_Ref,

                          Unchecked_Convert_To ( --  entry index
                            RTE (RE_Protected_Entry_Index),
                            Make_Identifier (Loc, Name_uI)),

                          Make_Identifier (Loc, Name_uP), --  parameter block
                          New_Occurrence_Of               --  Asynchronous_Call
                            (RTE (RE_Asynchronous_Call), Loc),
                          New_Occurrence_Of               -- comm block
                            (Com_Block, Loc))));

               when others =>
                  raise Program_Error;
            end case;

            --  Generate:
            --    B := Dummy_Communication_Block (Bnn);

            Append_To (Stmts,
              Make_Assignment_Statement (Loc,
                Name => Make_Identifier (Loc, Name_uB),
                Expression =>
                  Unchecked_Convert_To
                    (RTE (RE_Dummy_Communication_Block),
                     New_Occurrence_Of (Com_Block, Loc))));

            --  Generate:
            --    F := False;

            Append_To (Stmts,
              Make_Assignment_Statement (Loc,
                Name       => Make_Identifier (Loc, Name_uF),
                Expression => New_Occurrence_Of (Standard_False, Loc)));

         else
            pragma Assert (Ekind (Conc_Typ) = E_Task_Type);

            --  Generate:
            --    Task_Entry_Call
            --      (T._task_id,             --  Acceptor
            --       Task_Entry_Index! (I),  --  E
            --       P,                      --  Uninterpreted_Data
            --       Asynchronous_Call,      --  Mode
            --       F);                     --  Rendezvous_Successful

            --  where T is the task object, I is the entry index, P is the
            --  wrapped parameters and F is the status flag.

            Append_To (Stmts,
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (RTE (RE_Task_Entry_Call), Loc),
                Parameter_Associations =>
                  New_List (
                    Make_Selected_Component (Loc,         -- T._task_id
                      Prefix        => Make_Identifier (Loc, Name_uT),
                      Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),

                    Unchecked_Convert_To ( --  entry index
                      RTE (RE_Task_Entry_Index),
                      Make_Identifier (Loc, Name_uI)),

                    Make_Identifier (Loc, Name_uP),       --  parameter block
                    New_Occurrence_Of                     --  Asynchronous_Call
                      (RTE (RE_Asynchronous_Call), Loc),
                    Make_Identifier (Loc, Name_uF))));    --  status flag
         end if;

      else
         --  Ensure that the statements list is non-empty

         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uF),
             Expression => New_Occurrence_Of (Standard_False, Loc)));
      end if;

      return
        Make_Subprogram_Body (Loc,
          Specification              =>
            Make_Disp_Asynchronous_Select_Spec (Typ),
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, Stmts));
   end Make_Disp_Asynchronous_Select_Body;

   ----------------------------------------
   -- Make_Disp_Asynchronous_Select_Spec --
   ----------------------------------------

   function Make_Disp_Asynchronous_Select_Spec
     (Typ : Entity_Id) return Node_Id
   is
      Loc    : constant Source_Ptr := Sloc (Typ);
      B_Id   : constant Entity_Id  := Make_Defining_Identifier (Loc, Name_uB);
      Def_Id : constant Entity_Id  :=
                 Make_Defining_Identifier (Loc,
                   Name_uDisp_Asynchronous_Select);
      Params : constant List_Id    := New_List;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  T : in out Typ;                     --  Object parameter
      --  S : Integer;                        --  Primitive operation slot
      --  P : Address;                        --  Wrapped parameters
      --  B : out Dummy_Communication_Block;  --  Communication block dummy
      --  F : out Boolean;                    --  Status flag

      --  The B parameter may be left uninitialized

      Set_Warnings_Off (B_Id);

      Append_List_To (Params, New_List (

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
          Parameter_Type      => New_Occurrence_Of (Typ, Loc),
          In_Present          => True,
          Out_Present         => True),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
          Parameter_Type      => New_Occurrence_Of (Standard_Integer, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
          Parameter_Type      => New_Occurrence_Of (RTE (RE_Address), Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => B_Id,
          Parameter_Type      =>
            New_Occurrence_Of (RTE (RE_Dummy_Communication_Block), Loc),
          Out_Present         => True),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
          Parameter_Type      => New_Occurrence_Of (Standard_Boolean, Loc),
          Out_Present         => True)));

      return
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       => Def_Id,
          Parameter_Specifications => Params);
   end Make_Disp_Asynchronous_Select_Spec;

   ---------------------------------------
   -- Make_Disp_Conditional_Select_Body --
   ---------------------------------------

   --  For interface types, generate:

   --     procedure _Disp_Conditional_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        C : out Ada.Tags.Prim_Op_Kind;
   --        F : out Boolean)
   --     is
   --     begin
   --        F := False;
   --        C := Ada.Tags.POK_Function;
   --     end _Disp_Conditional_Select;

   --  For protected types, generate:

   --     procedure _Disp_Conditional_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        C : out Ada.Tags.Prim_Op_Kind;
   --        F : out Boolean)
   --     is
   --        I   : Integer;
   --        Bnn : System.Tasking.Protected_Objects.Operations.
   --                Communication_Block;

   --     begin
   --        C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP, S));

   --        if C = Ada.Tags.POK_Procedure
   --          or else C = Ada.Tags.POK_Protected_Procedure
   --          or else C = Ada.Tags.POK_Task_Procedure
   --        then
   --           F := True;
   --           return;
   --        end if;

   --        I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
   --        System.Tasking.Protected_Objects.Operations.Protected_Entry_Call
   --          (T.object'Access,
   --           System.Tasking.Protected_Objects.Protected_Entry_Index (I),
   --           P,
   --           System.Tasking.Conditional_Call,
   --           Bnn);
   --        F := not Cancelled (Bnn);
   --     end _Disp_Conditional_Select;

   --  For task types, generate:

   --     procedure _Disp_Conditional_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        C : out Ada.Tags.Prim_Op_Kind;
   --        F : out Boolean)
   --     is
   --        I : Integer;

   --     begin
   --        I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP, S));
   --        System.Tasking.Rendezvous.Task_Entry_Call
   --          (T._task_id,
   --           System.Tasking.Task_Entry_Index (I),
   --           P,
   --           System.Tasking.Conditional_Call,
   --           F);
   --     end _Disp_Conditional_Select;

   function Make_Disp_Conditional_Select_Body
     (Typ : Entity_Id) return Node_Id
   is
      Loc      : constant Source_Ptr := Sloc (Typ);
      Blk_Nam  : Entity_Id;
      Conc_Typ : Entity_Id           := Empty;
      Decls    : constant List_Id    := New_List;
      Obj_Ref  : Node_Id;
      Stmts    : constant List_Id    := New_List;
      Tag_Node : Node_Id;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  Null body is generated for interface types

      if Is_Interface (Typ) then
         return
           Make_Subprogram_Body (Loc,
             Specification              =>
               Make_Disp_Conditional_Select_Spec (Typ),
             Declarations               => No_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 New_List (Make_Assignment_Statement (Loc,
                   Name       => Make_Identifier (Loc, Name_uF),
                   Expression => New_Occurrence_Of (Standard_False, Loc)))));
      end if;

      if Is_Concurrent_Record_Type (Typ) then
         Conc_Typ := Corresponding_Concurrent_Type (Typ);

         --  Generate:
         --    I : Integer;

         --  where I will be used to capture the entry index of the primitive
         --  wrapper at position S.

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
             Object_Definition   =>
               New_Occurrence_Of (Standard_Integer, Loc)));

         --  Generate:
         --    C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag! (<type>VP), S);

         --    if C = POK_Procedure
         --      or else C = POK_Protected_Procedure
         --      or else C = POK_Task_Procedure;
         --    then
         --       F := True;
         --       return;
         --    end if;

         Build_Common_Dispatching_Select_Statements (Typ, Stmts);

         --  Generate:
         --    Bnn : Communication_Block;

         --  where Bnn is the name of the communication block used in the
         --  call to Protected_Entry_Call.

         Blk_Nam := Make_Temporary (Loc, 'B');
         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Blk_Nam,
             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Communication_Block), Loc)));

         --  Generate:
         --    I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag! (<type>VP), S);

         --  I is the entry index and S is the dispatch table slot

         if Tagged_Type_Expansion then
            Tag_Node :=
              Unchecked_Convert_To (RTE (RE_Tag),
                New_Occurrence_Of
                  (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));

         else
            Tag_Node :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Typ, Loc),
                Attribute_Name => Name_Tag);
         end if;

         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uI),
             Expression =>
               Make_Function_Call (Loc,
                 Name                   =>
                   New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
                 Parameter_Associations => New_List (
                   Tag_Node,
                   Make_Identifier (Loc, Name_uS)))));

         if Ekind (Conc_Typ) = E_Protected_Type then

            Obj_Ref :=                                  -- T._object'Access
               Make_Attribute_Reference (Loc,
                 Attribute_Name => Name_Unchecked_Access,
                 Prefix         =>
                   Make_Selected_Component (Loc,
                     Prefix        => Make_Identifier (Loc, Name_uT),
                     Selector_Name => Make_Identifier (Loc, Name_uObject)));

            case Corresponding_Runtime_Package (Conc_Typ) is
               when System_Tasking_Protected_Objects_Entries =>
                  --  Generate:

                  --    Protected_Entry_Call
                  --      (T._object'Access,            --  Object
                  --       Protected_Entry_Index! (I),  --  E
                  --       P,                           --  Uninterpreted_Data
                  --       Conditional_Call,            --  Mode
                  --       Bnn);                        --  Block

                  --  where T is the protected object, I is the entry index, P
                  --  are the wrapped parameters and Bnn is the name of the
                  --  communication block.

                  Append_To (Stmts,
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of (RTE (RE_Protected_Entry_Call), Loc),
                      Parameter_Associations => New_List (
                          Obj_Ref,

                          Unchecked_Convert_To ( --  entry index
                            RTE (RE_Protected_Entry_Index),
                            Make_Identifier (Loc, Name_uI)),

                          Make_Identifier (Loc, Name_uP),  --  parameter block

                          New_Occurrence_Of                --  Conditional_Call
                            (RTE (RE_Conditional_Call), Loc),
                          New_Occurrence_Of                --  Bnn
                            (Blk_Nam, Loc))));

               when System_Tasking_Protected_Objects_Single_Entry =>

                  --    If we are compiling for a restricted run-time, the call
                  --    uses the simpler form.

                  Append_To (Stmts,
                    Make_Procedure_Call_Statement (Loc,
                      Name                   =>
                        New_Occurrence_Of
                          (RTE (RE_Protected_Single_Entry_Call), Loc),
                      Parameter_Associations => New_List (
                          Obj_Ref,

                          Make_Attribute_Reference (Loc,
                            Prefix         => Make_Identifier (Loc, Name_uP),
                            Attribute_Name => Name_Address),

                            New_Occurrence_Of
                             (RTE (RE_Conditional_Call), Loc))));
               when others =>
                  raise Program_Error;
            end case;

            --  Generate:
            --    F := not Cancelled (Bnn);

            --  where F is the success flag. The status of Cancelled is negated
            --  in order to match the behavior of the version for task types.

            Append_To (Stmts,
              Make_Assignment_Statement (Loc,
                Name       => Make_Identifier (Loc, Name_uF),
                Expression =>
                  Make_Op_Not (Loc,
                    Right_Opnd =>
                      Make_Function_Call (Loc,
                        Name                   =>
                          New_Occurrence_Of (RTE (RE_Cancelled), Loc),
                        Parameter_Associations => New_List (
                            New_Occurrence_Of (Blk_Nam, Loc))))));
         else
            pragma Assert (Ekind (Conc_Typ) = E_Task_Type);

            --  Generate:
            --    Task_Entry_Call
            --      (T._task_id,             --  Acceptor
            --       Task_Entry_Index! (I),  --  E
            --       P,                      --  Uninterpreted_Data
            --       Conditional_Call,       --  Mode
            --       F);                     --  Rendezvous_Successful

            --  where T is the task object, I is the entry index, P are the
            --  wrapped parameters and F is the status flag.

            Append_To (Stmts,
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (RTE (RE_Task_Entry_Call), Loc),
                Parameter_Associations => New_List (

                    Make_Selected_Component (Loc,         -- T._task_id
                      Prefix        => Make_Identifier (Loc, Name_uT),
                      Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),

                    Unchecked_Convert_To ( --  entry index
                      RTE (RE_Task_Entry_Index),
                      Make_Identifier (Loc, Name_uI)),

                    Make_Identifier (Loc, Name_uP),       --  parameter block
                    New_Occurrence_Of                      --  Conditional_Call
                      (RTE (RE_Conditional_Call), Loc),
                    Make_Identifier (Loc, Name_uF))));    --  status flag
         end if;

      else
         --  Initialize out parameters

         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uF),
             Expression => New_Occurrence_Of (Standard_False, Loc)));
         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uC),
             Expression => New_Occurrence_Of (RTE (RE_POK_Function), Loc)));
      end if;

      return
        Make_Subprogram_Body (Loc,
          Specification              =>
            Make_Disp_Conditional_Select_Spec (Typ),
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, Stmts));
   end Make_Disp_Conditional_Select_Body;

   ---------------------------------------
   -- Make_Disp_Conditional_Select_Spec --
   ---------------------------------------

   function Make_Disp_Conditional_Select_Spec
     (Typ : Entity_Id) return Node_Id
   is
      Loc    : constant Source_Ptr := Sloc (Typ);
      Def_Id : constant Node_Id    :=
                 Make_Defining_Identifier (Loc,
                   Name_uDisp_Conditional_Select);
      Params : constant List_Id    := New_List;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  T : in out Typ;        --  Object parameter
      --  S : Integer;           --  Primitive operation slot
      --  P : Address;           --  Wrapped parameters
      --  C : out Prim_Op_Kind;  --  Call kind
      --  F : out Boolean;       --  Status flag

      Append_List_To (Params, New_List (

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
          Parameter_Type      => New_Occurrence_Of (Typ, Loc),
          In_Present          => True,
          Out_Present         => True),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
          Parameter_Type      => New_Occurrence_Of (Standard_Integer, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
          Parameter_Type      => New_Occurrence_Of (RTE (RE_Address), Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
          Parameter_Type      =>
            New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
          Out_Present         => True),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
          Parameter_Type      => New_Occurrence_Of (Standard_Boolean, Loc),
          Out_Present         => True)));

      return
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       => Def_Id,
          Parameter_Specifications => Params);
   end Make_Disp_Conditional_Select_Spec;

   -------------------------------------
   -- Make_Disp_Get_Prim_Op_Kind_Body --
   -------------------------------------

   function Make_Disp_Get_Prim_Op_Kind_Body (Typ : Entity_Id) return Node_Id is
      Loc      : constant Source_Ptr := Sloc (Typ);
      Tag_Node : Node_Id;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      if Is_Interface (Typ) then
         return
           Make_Subprogram_Body (Loc,
             Specification              =>
               Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
             Declarations               => New_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 New_List (Make_Null_Statement (Loc))));
      end if;

      --  Generate:
      --    C := get_prim_op_kind (tag! (<type>VP), S);

      --  where C is the out parameter capturing the call kind and S is the
      --  dispatch table slot number.

      if Tagged_Type_Expansion then
         Tag_Node :=
           Unchecked_Convert_To (RTE (RE_Tag),
             New_Occurrence_Of
              (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));

      else
         Tag_Node :=
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Typ, Loc),
             Attribute_Name => Name_Tag);
      end if;

      return
        Make_Subprogram_Body (Loc,
          Specification              =>
            Make_Disp_Get_Prim_Op_Kind_Spec (Typ),
          Declarations               => New_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc,
              New_List (
                Make_Assignment_Statement (Loc,
                  Name       => Make_Identifier (Loc, Name_uC),
                  Expression =>
                    Make_Function_Call (Loc,
                      Name =>
                        New_Occurrence_Of (RTE (RE_Get_Prim_Op_Kind), Loc),
                      Parameter_Associations => New_List (
                        Tag_Node,
                        Make_Identifier (Loc, Name_uS)))))));
   end Make_Disp_Get_Prim_Op_Kind_Body;

   -------------------------------------
   -- Make_Disp_Get_Prim_Op_Kind_Spec --
   -------------------------------------

   function Make_Disp_Get_Prim_Op_Kind_Spec
     (Typ : Entity_Id) return Node_Id
   is
      Loc    : constant Source_Ptr := Sloc (Typ);
      Def_Id : constant Node_Id    :=
                 Make_Defining_Identifier (Loc, Name_uDisp_Get_Prim_Op_Kind);
      Params : constant List_Id    := New_List;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  T : in out Typ;       --  Object parameter
      --  S : Integer;          --  Primitive operation slot
      --  C : out Prim_Op_Kind; --  Call kind

      Append_List_To (Params, New_List (

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
          Parameter_Type      => New_Occurrence_Of (Typ, Loc),
          In_Present          => True,
          Out_Present         => True),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
          Parameter_Type      => New_Occurrence_Of (Standard_Integer, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
          Parameter_Type      =>
            New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
          Out_Present         => True)));

      return
        Make_Procedure_Specification (Loc,
           Defining_Unit_Name       => Def_Id,
           Parameter_Specifications => Params);
   end Make_Disp_Get_Prim_Op_Kind_Spec;

   --------------------------------
   -- Make_Disp_Get_Task_Id_Body --
   --------------------------------

   function Make_Disp_Get_Task_Id_Body
     (Typ : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Typ);
      Ret : Node_Id;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      if Is_Concurrent_Record_Type (Typ)
        and then Ekind (Corresponding_Concurrent_Type (Typ)) = E_Task_Type
      then
         --  Generate:
         --    return To_Address (_T._task_id);

         Ret :=
           Make_Simple_Return_Statement (Loc,
             Expression =>
               Unchecked_Convert_To
                 (RTE (RE_Address),
                  Make_Selected_Component (Loc,
                    Prefix        => Make_Identifier (Loc, Name_uT),
                    Selector_Name => Make_Identifier (Loc, Name_uTask_Id))));

      --  A null body is constructed for non-task types

      else
         --  Generate:
         --    return Null_Address;

         Ret :=
           Make_Simple_Return_Statement (Loc,
             Expression => New_Occurrence_Of (RTE (RE_Null_Address), Loc));
      end if;

      return
        Make_Subprogram_Body (Loc,
          Specification              => Make_Disp_Get_Task_Id_Spec (Typ),
          Declarations               => New_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, New_List (Ret)));
   end Make_Disp_Get_Task_Id_Body;

   --------------------------------
   -- Make_Disp_Get_Task_Id_Spec --
   --------------------------------

   function Make_Disp_Get_Task_Id_Spec
     (Typ : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Typ);

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      return
        Make_Function_Specification (Loc,
          Defining_Unit_Name       =>
            Make_Defining_Identifier (Loc, Name_uDisp_Get_Task_Id),
          Parameter_Specifications => New_List (
            Make_Parameter_Specification (Loc,
              Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
              Parameter_Type      => New_Occurrence_Of (Typ, Loc))),
          Result_Definition        =>
            New_Occurrence_Of (RTE (RE_Address), Loc));
   end Make_Disp_Get_Task_Id_Spec;

   ----------------------------
   -- Make_Disp_Requeue_Body --
   ----------------------------

   function Make_Disp_Requeue_Body
     (Typ : Entity_Id) return Node_Id
   is
      Loc      : constant Source_Ptr := Sloc (Typ);
      Conc_Typ : Entity_Id           := Empty;
      Stmts    : constant List_Id    := New_List;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  Null body is generated for interface types and non-concurrent
      --  tagged types.

      if Is_Interface (Typ)
        or else not Is_Concurrent_Record_Type (Typ)
      then
         return
           Make_Subprogram_Body (Loc,
             Specification              => Make_Disp_Requeue_Spec (Typ),
             Declarations               => No_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 New_List (Make_Null_Statement (Loc))));
      end if;

      Conc_Typ := Corresponding_Concurrent_Type (Typ);

      if Ekind (Conc_Typ) = E_Protected_Type then

         --  Generate statements:
         --    if F then
         --       System.Tasking.Protected_Objects.Operations.
         --         Requeue_Protected_Entry
         --           (Protection_Entries_Access (P),
         --            O._object'Unchecked_Access,
         --            Protected_Entry_Index (I),
         --            A);
         --    else
         --       System.Tasking.Protected_Objects.Operations.
         --         Requeue_Task_To_Protected_Entry
         --           (O._object'Unchecked_Access,
         --            Protected_Entry_Index (I),
         --            A);
         --    end if;

         if Restriction_Active (No_Entry_Queue) then
            Append_To (Stmts, Make_Null_Statement (Loc));
         else
            Append_To (Stmts,
              Make_If_Statement (Loc,
                Condition       => Make_Identifier (Loc, Name_uF),

                Then_Statements =>
                  New_List (

                     --  Call to Requeue_Protected_Entry

                    Make_Procedure_Call_Statement (Loc,
                      Name =>
                        New_Occurrence_Of
                          (RTE (RE_Requeue_Protected_Entry), Loc),
                      Parameter_Associations =>
                        New_List (

                          Unchecked_Convert_To ( -- PEA (P)
                            RTE (RE_Protection_Entries_Access),
                            Make_Identifier (Loc, Name_uP)),

                          Make_Attribute_Reference (Loc,      -- O._object'Acc
                            Attribute_Name =>
                              Name_Unchecked_Access,
                            Prefix         =>
                              Make_Selected_Component (Loc,
                                Prefix        =>
                                  Make_Identifier (Loc, Name_uO),
                                Selector_Name =>
                                  Make_Identifier (Loc, Name_uObject))),

                          Unchecked_Convert_To ( -- entry index
                            RTE (RE_Protected_Entry_Index),
                            Make_Identifier (Loc, Name_uI)),

                          Make_Identifier (Loc, Name_uA)))),   -- abort status

                Else_Statements =>
                  New_List (

                     --  Call to Requeue_Task_To_Protected_Entry

                    Make_Procedure_Call_Statement (Loc,
                      Name =>
                        New_Occurrence_Of
                          (RTE (RE_Requeue_Task_To_Protected_Entry), Loc),
                      Parameter_Associations =>
                        New_List (

                          Make_Attribute_Reference (Loc,     -- O._object'Acc
                            Attribute_Name => Name_Unchecked_Access,
                            Prefix         =>
                              Make_Selected_Component (Loc,
                                Prefix        =>
                                  Make_Identifier (Loc, Name_uO),
                                Selector_Name =>
                                  Make_Identifier (Loc, Name_uObject))),

                          Unchecked_Convert_To ( -- entry index
                            RTE (RE_Protected_Entry_Index),
                            Make_Identifier (Loc, Name_uI)),

                          Make_Identifier (Loc, Name_uA)))))); -- abort status
         end if;

      else
         pragma Assert (Is_Task_Type (Conc_Typ));

         --  Generate:
         --    if F then
         --       System.Tasking.Rendezvous.Requeue_Protected_To_Task_Entry
         --         (Protection_Entries_Access (P),
         --          O._task_id,
         --          Task_Entry_Index (I),
         --          A);
         --    else
         --       System.Tasking.Rendezvous.Requeue_Task_Entry
         --         (O._task_id,
         --          Task_Entry_Index (I),
         --          A);
         --    end if;

         Append_To (Stmts,
           Make_If_Statement (Loc,
             Condition       => Make_Identifier (Loc, Name_uF),

             Then_Statements => New_List (

               --  Call to Requeue_Protected_To_Task_Entry

               Make_Procedure_Call_Statement (Loc,
                 Name =>
                   New_Occurrence_Of
                     (RTE (RE_Requeue_Protected_To_Task_Entry), Loc),

                 Parameter_Associations => New_List (

                   Unchecked_Convert_To ( -- PEA (P)
                     RTE (RE_Protection_Entries_Access),
                     Make_Identifier (Loc, Name_uP)),

                   Make_Selected_Component (Loc,         -- O._task_id
                     Prefix        => Make_Identifier (Loc, Name_uO),
                     Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),

                   Unchecked_Convert_To ( -- entry index
                     RTE (RE_Task_Entry_Index),
                     Make_Identifier (Loc, Name_uI)),

                   Make_Identifier (Loc, Name_uA)))),    -- abort status

             Else_Statements => New_List (

               --  Call to Requeue_Task_Entry

               Make_Procedure_Call_Statement (Loc,
                 Name                   =>
                   New_Occurrence_Of (RTE (RE_Requeue_Task_Entry), Loc),

                 Parameter_Associations => New_List (

                   Make_Selected_Component (Loc,         -- O._task_id
                     Prefix        => Make_Identifier (Loc, Name_uO),
                     Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),

                   Unchecked_Convert_To ( -- entry index
                     RTE (RE_Task_Entry_Index),
                     Make_Identifier (Loc, Name_uI)),

                   Make_Identifier (Loc, Name_uA))))));  -- abort status
      end if;

      --  Even though no declarations are needed in both cases, we allocate
      --  a list for entities added by Freeze.

      return
        Make_Subprogram_Body (Loc,
          Specification              => Make_Disp_Requeue_Spec (Typ),
          Declarations               => New_List,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, Stmts));
   end Make_Disp_Requeue_Body;

   ----------------------------
   -- Make_Disp_Requeue_Spec --
   ----------------------------

   function Make_Disp_Requeue_Spec
     (Typ : Entity_Id) return Node_Id
   is
      Loc : constant Source_Ptr := Sloc (Typ);

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  O : in out Typ;   -  Object parameter
      --  F : Boolean;      -  Protected (True) / task (False) flag
      --  P : Address;      -  Protection_Entries_Access value
      --  I : Entry_Index   -  Index of entry call
      --  A : Boolean       -  Abort flag

      --  Note that the Protection_Entries_Access value is represented as a
      --  System.Address in order to avoid dragging in the tasking runtime
      --  when compiling sources without tasking constructs.

      return
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name =>
            Make_Defining_Identifier (Loc, Name_uDisp_Requeue),

          Parameter_Specifications => New_List (

              Make_Parameter_Specification (Loc,             --  O
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uO),
                Parameter_Type      =>
                  New_Occurrence_Of (Typ, Loc),
                In_Present          => True,
                Out_Present         => True),

              Make_Parameter_Specification (Loc,             --  F
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uF),
                Parameter_Type      =>
                  New_Occurrence_Of (Standard_Boolean, Loc)),

              Make_Parameter_Specification (Loc,             --  P
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uP),
                Parameter_Type      =>
                  New_Occurrence_Of (RTE (RE_Address), Loc)),

              Make_Parameter_Specification (Loc,             --  I
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uI),
                Parameter_Type      =>
                  New_Occurrence_Of (Standard_Integer, Loc)),

              Make_Parameter_Specification (Loc,             --  A
                Defining_Identifier =>
                  Make_Defining_Identifier (Loc, Name_uA),
                Parameter_Type      =>
                  New_Occurrence_Of (Standard_Boolean, Loc))));
   end Make_Disp_Requeue_Spec;

   ---------------------------------
   -- Make_Disp_Timed_Select_Body --
   ---------------------------------

   --  For interface types, generate:

   --     procedure _Disp_Timed_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        D : Duration;
   --        M : Integer;
   --        C : out Ada.Tags.Prim_Op_Kind;
   --        F : out Boolean)
   --     is
   --     begin
   --        F := False;
   --        C := Ada.Tags.POK_Function;
   --     end _Disp_Timed_Select;

   --  For protected types, generate:

   --     procedure _Disp_Timed_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        D : Duration;
   --        M : Integer;
   --        C : out Ada.Tags.Prim_Op_Kind;
   --        F : out Boolean)
   --     is
   --        I : Integer;

   --     begin
   --        C := Ada.Tags.Get_Prim_Op_Kind (Ada.Tags.Tag (<Typ>VP), S);

   --        if C = Ada.Tags.POK_Procedure
   --          or else C = Ada.Tags.POK_Protected_Procedure
   --          or else C = Ada.Tags.POK_Task_Procedure
   --        then
   --           F := True;
   --           return;
   --        end if;

   --        I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
   --        System.Tasking.Protected_Objects.Operations.
   --          Timed_Protected_Entry_Call
   --            (T._object'Access,
   --             System.Tasking.Protected_Objects.Protected_Entry_Index (I),
   --             P,
   --             D,
   --             M,
   --             F);
   --     end _Disp_Timed_Select;

   --  For task types, generate:

   --     procedure _Disp_Timed_Select
   --       (T : in out <Typ>;
   --        S : Integer;
   --        P : System.Address;
   --        D : Duration;
   --        M : Integer;
   --        C : out Ada.Tags.Prim_Op_Kind;
   --        F : out Boolean)
   --     is
   --        I : Integer;

   --     begin
   --        I := Ada.Tags.Get_Entry_Index (Ada.Tags.Tag (<Typ>VP), S);
   --        System.Tasking.Rendezvous.Timed_Task_Entry_Call
   --          (T._task_id,
   --           System.Tasking.Task_Entry_Index (I),
   --           P,
   --           D,
   --           M,
   --           F);
   --     end _Disp_Time_Select;

   function Make_Disp_Timed_Select_Body
     (Typ : Entity_Id) return Node_Id
   is
      Loc      : constant Source_Ptr := Sloc (Typ);
      Conc_Typ : Entity_Id           := Empty;
      Decls    : constant List_Id    := New_List;
      Obj_Ref  : Node_Id;
      Stmts    : constant List_Id    := New_List;
      Tag_Node : Node_Id;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  Null body is generated for interface types

      if Is_Interface (Typ) then
         return
           Make_Subprogram_Body (Loc,
             Specification              => Make_Disp_Timed_Select_Spec (Typ),
             Declarations               => New_List,
             Handled_Statement_Sequence =>
               Make_Handled_Sequence_Of_Statements (Loc,
                 New_List (
                   Make_Assignment_Statement (Loc,
                     Name       => Make_Identifier (Loc, Name_uF),
                     Expression => New_Occurrence_Of (Standard_False, Loc)))));
      end if;

      if Is_Concurrent_Record_Type (Typ) then
         Conc_Typ := Corresponding_Concurrent_Type (Typ);

         --  Generate:
         --    I : Integer;

         --  where I will be used to capture the entry index of the primitive
         --  wrapper at position S.

         Append_To (Decls,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
             Object_Definition   =>
               New_Occurrence_Of (Standard_Integer, Loc)));

         --  Generate:
         --    C := Get_Prim_Op_Kind (tag! (<type>VP), S);

         --    if C = POK_Procedure
         --      or else C = POK_Protected_Procedure
         --      or else C = POK_Task_Procedure;
         --    then
         --       F := True;
         --       return;
         --    end if;

         Build_Common_Dispatching_Select_Statements (Typ, Stmts);

         --  Generate:
         --    I := Get_Entry_Index (tag! (<type>VP), S);

         --  I is the entry index and S is the dispatch table slot

         if Tagged_Type_Expansion then
            Tag_Node :=
              Unchecked_Convert_To (RTE (RE_Tag),
                New_Occurrence_Of
                  (Node (First_Elmt (Access_Disp_Table (Typ))), Loc));

         else
            Tag_Node :=
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (Typ, Loc),
                Attribute_Name => Name_Tag);
         end if;

         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uI),
             Expression =>
               Make_Function_Call (Loc,
                 Name => New_Occurrence_Of (RTE (RE_Get_Entry_Index), Loc),
                 Parameter_Associations => New_List (
                   Tag_Node,
                   Make_Identifier (Loc, Name_uS)))));

         --  Protected case

         if Ekind (Conc_Typ) = E_Protected_Type then

            --  Build T._object'Access

            Obj_Ref :=
               Make_Attribute_Reference (Loc,
                  Attribute_Name => Name_Unchecked_Access,
                  Prefix         =>
                    Make_Selected_Component (Loc,
                      Prefix        => Make_Identifier (Loc, Name_uT),
                      Selector_Name => Make_Identifier (Loc, Name_uObject)));

            --  Normal case, No_Entry_Queue restriction not active. In this
            --  case we generate:

            --   Timed_Protected_Entry_Call
            --     (T._object'access,
            --      Protected_Entry_Index! (I),
            --      P, D, M, F);

            --  where T is the protected object, I is the entry index, P are
            --  the wrapped parameters, D is the delay amount, M is the delay
            --  mode and F is the status flag.

            --  Historically, there was also an implementation for single
            --  entry protected types (in s-tposen). However, it was removed
            --  by also testing for no No_Select_Statements restriction in
            --  Exp_Utils.Corresponding_Runtime_Package. This simplified the
            --  implementation of s-tposen.adb and provided consistency between
            --  all versions of System.Tasking.Protected_Objects.Single_Entry
            --  (s-tposen*.adb).

            case Corresponding_Runtime_Package (Conc_Typ) is
               when System_Tasking_Protected_Objects_Entries =>
                  Append_To (Stmts,
                    Make_Procedure_Call_Statement (Loc,
                      Name =>
                        New_Occurrence_Of
                          (RTE (RE_Timed_Protected_Entry_Call), Loc),
                      Parameter_Associations => New_List (
                        Obj_Ref,

                        Unchecked_Convert_To ( --  entry index
                         RTE (RE_Protected_Entry_Index),
                          Make_Identifier (Loc, Name_uI)),

                        Make_Identifier (Loc, Name_uP),    --  parameter block
                        Make_Identifier (Loc, Name_uD),    --  delay
                        Make_Identifier (Loc, Name_uM),    --  delay mode
                        Make_Identifier (Loc, Name_uF)))); --  status flag

               when others =>
                  raise Program_Error;
            end case;

         --  Task case

         else
            pragma Assert (Ekind (Conc_Typ) = E_Task_Type);

            --  Generate:
            --    Timed_Task_Entry_Call (
            --      T._task_id,
            --      Task_Entry_Index! (I),
            --      P,
            --      D,
            --      M,
            --      F);

            --  where T is the task object, I is the entry index, P are the
            --  wrapped parameters, D is the delay amount, M is the delay
            --  mode and F is the status flag.

            Append_To (Stmts,
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (RTE (RE_Timed_Task_Entry_Call), Loc),

                Parameter_Associations => New_List (
                  Make_Selected_Component (Loc,         --  T._task_id
                    Prefix        => Make_Identifier (Loc, Name_uT),
                    Selector_Name => Make_Identifier (Loc, Name_uTask_Id)),

                  Unchecked_Convert_To ( --  entry index
                    RTE (RE_Task_Entry_Index),
                    Make_Identifier (Loc, Name_uI)),

                  Make_Identifier (Loc, Name_uP),       --  parameter block
                  Make_Identifier (Loc, Name_uD),       --  delay
                  Make_Identifier (Loc, Name_uM),       --  delay mode
                  Make_Identifier (Loc, Name_uF))));    --  status flag
         end if;

      else
         --  Initialize out parameters

         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uF),
             Expression => New_Occurrence_Of (Standard_False, Loc)));
         Append_To (Stmts,
           Make_Assignment_Statement (Loc,
             Name       => Make_Identifier (Loc, Name_uC),
             Expression => New_Occurrence_Of (RTE (RE_POK_Function), Loc)));
      end if;

      return
        Make_Subprogram_Body (Loc,
          Specification              => Make_Disp_Timed_Select_Spec (Typ),
          Declarations               => Decls,
          Handled_Statement_Sequence =>
            Make_Handled_Sequence_Of_Statements (Loc, Stmts));
   end Make_Disp_Timed_Select_Body;

   ---------------------------------
   -- Make_Disp_Timed_Select_Spec --
   ---------------------------------

   function Make_Disp_Timed_Select_Spec
     (Typ : Entity_Id) return Node_Id
   is
      Loc    : constant Source_Ptr := Sloc (Typ);
      Def_Id : constant Node_Id    :=
                 Make_Defining_Identifier (Loc,
                   Name_uDisp_Timed_Select);
      Params : constant List_Id    := New_List;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  T : in out Typ;        --  Object parameter
      --  S : Integer;           --  Primitive operation slot
      --  P : Address;           --  Wrapped parameters
      --  D : Duration;          --  Delay
      --  M : Integer;           --  Delay Mode
      --  C : out Prim_Op_Kind;  --  Call kind
      --  F : out Boolean;       --  Status flag

      Append_List_To (Params, New_List (

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uT),
          Parameter_Type      => New_Occurrence_Of (Typ, Loc),
          In_Present          => True,
          Out_Present         => True),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uS),
          Parameter_Type      => New_Occurrence_Of (Standard_Integer, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uP),
          Parameter_Type      => New_Occurrence_Of (RTE (RE_Address), Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uD),
          Parameter_Type      => New_Occurrence_Of (Standard_Duration, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uM),
          Parameter_Type      => New_Occurrence_Of (Standard_Integer, Loc)),

        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uC),
          Parameter_Type      =>
            New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc),
          Out_Present         => True)));

      Append_To (Params,
        Make_Parameter_Specification (Loc,
          Defining_Identifier => Make_Defining_Identifier (Loc, Name_uF),
          Parameter_Type      => New_Occurrence_Of (Standard_Boolean, Loc),
          Out_Present         => True));

      return
        Make_Procedure_Specification (Loc,
          Defining_Unit_Name       => Def_Id,
          Parameter_Specifications => Params);
   end Make_Disp_Timed_Select_Spec;

   -------------
   -- Make_DT --
   -------------

   --  The frontend supports two models for expanding dispatch tables
   --  associated with library-level defined tagged types: statically and
   --  non-statically allocated dispatch tables. In the former case the object
   --  containing the dispatch table is constant and it is initialized by means
   --  of a positional aggregate. In the latter case, the object containing
   --  the dispatch table is a variable which is initialized by means of
   --  assignments.

   --  In case of locally defined tagged types, the object containing the
   --  object containing the dispatch table is always a variable (instead of a
   --  constant). This is currently required to give support to late overriding
   --  of primitives. For example:

   --     procedure Example is
   --        package Pkg is
   --           type T1 is tagged null record;
   --           procedure Prim (O : T1);
   --        end Pkg;

   --        type T2 is new Pkg.T1 with null record;
   --        procedure Prim (X : T2) is    -- late overriding
   --        begin
   --           ...
   --     ...
   --     end;

   --  WARNING: This routine manages Ghost regions. Return statements must be
   --  replaced by gotos which jump to the end of the routine and restore the
   --  Ghost mode.

   function Make_DT (Typ : Entity_Id; N : Node_Id := Empty) return List_Id is
      Loc : constant Source_Ptr := Sloc (Typ);

      Max_Predef_Prims : constant Int :=
                           UI_To_Int
                             (Intval
                               (Expression
                                 (Parent (RTE (RE_Max_Predef_Prims)))));

      DT_Decl : constant Elist_Id := New_Elmt_List;
      DT_Aggr : constant Elist_Id := New_Elmt_List;
      --  Entities marked with attribute Is_Dispatch_Table_Entity

      Dummy_Object : Entity_Id := Empty;
      --  Extra nonexistent object of type Typ internally used to compute the
      --  offset to the components that reference secondary dispatch tables.
      --  Used to compute the offset of components located at fixed position.

      procedure Check_Premature_Freezing
        (Subp        : Entity_Id;
         Tagged_Type : Entity_Id;
         Typ         : Entity_Id);
      --  Verify that all untagged types in the profile of a subprogram are
      --  frozen at the point the subprogram is frozen. This enforces the rule
      --  on RM 13.14 (14) as modified by AI05-019. At the point a subprogram
      --  is frozen, enough must be known about it to build the activation
      --  record for it, which requires at least that the size of all
      --  parameters be known. Controlling arguments are by-reference,
      --  and therefore the rule only applies to untagged types. Typical
      --  violation of the rule involves an object declaration that freezes a
      --  tagged type, when one of its primitive operations has a type in its
      --  profile whose full view has not been analyzed yet. More complex cases
      --  involve composite types that have one private unfrozen subcomponent.
      --  Move this check to sem???

      procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0);
      --  Export the dispatch table DT of tagged type Typ. Required to generate
      --  forward references and statically allocate the table. For primary
      --  dispatch tables Index is 0; for secondary dispatch tables the value
      --  of index must match the Suffix_Index value assigned to the table by
      --  Make_Tags when generating its unique external name, and it is used to
      --  retrieve from the Dispatch_Table_Wrappers list associated with Typ
      --  the external name generated by Import_DT.

      procedure Make_Secondary_DT
        (Typ              : Entity_Id;
         Iface            : Entity_Id;
         Iface_Comp       : Node_Id;
         Suffix_Index     : Int;
         Num_Iface_Prims  : Nat;
         Iface_DT_Ptr     : Entity_Id;
         Predef_Prims_Ptr : Entity_Id;
         Build_Thunks     : Boolean;
         Result           : List_Id);
      --  Ada 2005 (AI-251): Expand the declarations for a Secondary Dispatch
      --  Table of Typ associated with Iface. Each abstract interface of Typ
      --  has two secondary dispatch tables: one containing pointers to thunks
      --  and another containing pointers to the primitives covering the
      --  interface primitives. The former secondary table is generated when
      --  Build_Thunks is True, and provides common support for dispatching
      --  calls through interface types; the latter secondary table is
      --  generated when Build_Thunks is False, and provides support for
      --  Generic Dispatching Constructors that dispatch calls through
      --  interface types. When constructing this latter table the value of
      --  Suffix_Index is -1 to indicate that there is no need to export such
      --  table when building statically allocated dispatch tables; a positive
      --  value of Suffix_Index must match the Suffix_Index value assigned to
      --  this secondary dispatch table by Make_Tags when its unique external
      --  name was generated.

      function Number_Of_Predefined_Prims (Typ : Entity_Id) return Nat;
      --  Returns the number of predefined primitives of Typ

      ------------------------------
      -- Check_Premature_Freezing --
      ------------------------------

      procedure Check_Premature_Freezing
        (Subp        : Entity_Id;
         Tagged_Type : Entity_Id;
         Typ         : Entity_Id)
      is
         Comp : Entity_Id;

         function Is_Actual_For_Formal_Incomplete_Type
           (T : Entity_Id) return Boolean;
         --  In Ada 2012, if a nested generic has an incomplete formal type,
         --  the actual may be (and usually is) a private type whose completion
         --  appears later. It is safe to build the dispatch table in this
         --  case, gigi will have full views available.

         ------------------------------------------
         -- Is_Actual_For_Formal_Incomplete_Type --
         ------------------------------------------

         function Is_Actual_For_Formal_Incomplete_Type
           (T : Entity_Id) return Boolean
         is
            Gen_Par : Entity_Id;
            F       : Node_Id;

         begin
            if not Is_Generic_Instance (Current_Scope)
              or else not Used_As_Generic_Actual (T)
            then
               return False;
            else
               Gen_Par := Generic_Parent (Parent (Current_Scope));
            end if;

            F :=
              First
                (Generic_Formal_Declarations
                   (Unit_Declaration_Node (Gen_Par)));
            while Present (F) loop
               if Ekind (Defining_Identifier (F)) = E_Incomplete_Type then
                  return True;
               end if;

               Next (F);
            end loop;

            return False;
         end Is_Actual_For_Formal_Incomplete_Type;

      --  Start of processing for Check_Premature_Freezing

      begin
         --  Note that if the type is a (subtype of) a generic actual, the
         --  actual will have been frozen by the instantiation.

         if Present (N)
           and then Is_Private_Type (Typ)
           and then No (Full_View (Typ))
           and then not Has_Private_Declaration (Typ)
           and then not Is_Generic_Type (Typ)
           and then not Is_Tagged_Type (Typ)
           and then not Is_Frozen (Typ)
           and then not Is_Generic_Actual_Type (Typ)
         then
            Error_Msg_Sloc := Sloc (Subp);
            Error_Msg_NE
              ("declaration must appear after completion of type &", N, Typ);
            Error_Msg_NE
              ("\which is an untagged type in the profile of "
               & "primitive operation & declared#", N, Subp);

         else
            Comp := Private_Component (Typ);

            if not Is_Tagged_Type (Typ)
              and then Present (Comp)
              and then not Is_Frozen (Comp)
              and then not Has_Private_Declaration (Comp)
              and then not Is_Actual_For_Formal_Incomplete_Type (Comp)
            then
               Error_Msg_Sloc := Sloc (Subp);
               Error_Msg_Node_2 := Subp;
               Error_Msg_Name_1 := Chars (Tagged_Type);
               Error_Msg_NE
                 ("declaration must appear after completion of type &",
                  N, Comp);
               Error_Msg_NE
                 ("\which is a component of untagged type& in the profile "
                  & "of primitive & of type % that is frozen by the "
                  & "declaration", N, Typ);
            end if;
         end if;
      end Check_Premature_Freezing;

      ---------------
      -- Export_DT --
      ---------------

      procedure Export_DT (Typ : Entity_Id; DT : Entity_Id; Index : Nat := 0)
      is
         Count : Nat;
         Elmt  : Elmt_Id;

      begin
         Set_Is_Statically_Allocated (DT);
         Set_Is_True_Constant (DT);
         Set_Is_Exported (DT);

         Count := 0;
         Elmt  := First_Elmt (Dispatch_Table_Wrappers (Typ));
         while Count /= Index loop
            Next_Elmt (Elmt);
            Count := Count + 1;
         end loop;

         --  Related_Type (Node (Elmt)) should be equal to Typ here, but we
         --  can't assert that, because it is sometimes false in illegal
         --  programs. We can't check Serious_Errors_Detected, because the
         --  errors have not yet been detected.

         Get_External_Name (Node (Elmt));
         Set_Interface_Name (DT,
           Make_String_Literal (Loc,
             Strval => String_From_Name_Buffer));

         --  Ensure proper Sprint output of this implicit importation

         Set_Is_Internal (DT);
         Set_Is_Public (DT);
      end Export_DT;

      -----------------------
      -- Make_Secondary_DT --
      -----------------------

      procedure Make_Secondary_DT
        (Typ              : Entity_Id;
         Iface            : Entity_Id;
         Iface_Comp       : Node_Id;
         Suffix_Index     : Int;
         Num_Iface_Prims  : Nat;
         Iface_DT_Ptr     : Entity_Id;
         Predef_Prims_Ptr : Entity_Id;
         Build_Thunks     : Boolean;
         Result           : List_Id)
      is
         Loc                : constant Source_Ptr := Sloc (Typ);
         Exporting_Table    : constant Boolean :=
                                Building_Static_DT (Typ)
                                  and then Suffix_Index > 0;
         Iface_DT           : constant Entity_Id := Make_Temporary (Loc, 'T');
         Predef_Prims       : constant Entity_Id := Make_Temporary (Loc, 'R');
         DT_Constr_List     : List_Id;
         DT_Aggr_List       : List_Id;
         Empty_DT           : Boolean := False;
         Nb_Prim            : Nat;
         New_Node           : Node_Id;
         OSD                : Entity_Id;
         OSD_Aggr_List      : List_Id;
         Prim               : Entity_Id;
         Prim_Elmt          : Elmt_Id;
         Prim_Ops_Aggr_List : List_Id;

      begin
         --  Handle cases in which we do not generate statically allocated
         --  dispatch tables.

         if not Building_Static_DT (Typ) then
            Mutate_Ekind (Predef_Prims, E_Variable);
            Mutate_Ekind (Iface_DT, E_Variable);

         --  Statically allocated dispatch tables and related entities are
         --  constants.

         else
            Mutate_Ekind (Predef_Prims, E_Constant);
            Set_Is_Statically_Allocated (Predef_Prims);
            Set_Is_True_Constant (Predef_Prims);

            Mutate_Ekind (Iface_DT, E_Constant);
            Set_Is_Statically_Allocated (Iface_DT);
            Set_Is_True_Constant (Iface_DT);
         end if;

         --  Calculate the number of slots of the dispatch table. If the number
         --  of primitives of Typ is 0 we reserve a dummy single entry for its
         --  DT because at run time the pointer to this dummy entry will be
         --  used as the tag.

         if Num_Iface_Prims = 0 then
            Empty_DT := True;
            Nb_Prim  := 1;
         else
            Nb_Prim  := Num_Iface_Prims;
         end if;

         --  Generate:

         --   Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
         --                    (predef-prim-op-thunk-1'address,
         --                     predef-prim-op-thunk-2'address,
         --                     ...
         --                     predef-prim-op-thunk-n'address);

         --  Create the thunks associated with the predefined primitives and
         --  save their entity to fill the aggregate.

         declare
            Nb_P_Prims : constant Nat := Number_Of_Predefined_Prims (Typ);
            Prim_Table : array (Nat range 1 .. Nb_P_Prims) of Entity_Id;
            Decl       : Node_Id;
            Thunk_Id   : Entity_Id;
            Thunk_Code : Node_Id;

         begin
            Prim_Ops_Aggr_List := New_List;
            Prim_Table := (others => Empty);

            if Building_Static_DT (Typ) then
               Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  if Is_Predefined_Dispatching_Operation (Prim)
                    and then not Is_Abstract_Subprogram (Prim)
                    and then not Is_Eliminated (Prim)
                    and then not Generate_SCIL
                    and then not Present (Prim_Table
                                           (UI_To_Int (DT_Position (Prim))))
                  then
                     if not Build_Thunks then
                        Prim_Table (UI_To_Int (DT_Position (Prim))) :=
                          Alias (Prim);

                     else
                        Expand_Interface_Thunk
                          (Prim, Thunk_Id, Thunk_Code, Iface);

                        if Present (Thunk_Id) then
                           Append_To (Result, Thunk_Code);
                           Prim_Table (UI_To_Int (DT_Position (Prim))) :=
                             Thunk_Id;
                        end if;
                     end if;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;
            end if;

            for J in Prim_Table'Range loop
               if Present (Prim_Table (J)) then
                  New_Node :=
                    Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                      Make_Attribute_Reference (Loc,
                        Prefix => New_Occurrence_Of (Prim_Table (J), Loc),
                        Attribute_Name => Name_Unrestricted_Access));
               else
                  New_Node := Make_Null (Loc);
               end if;

               Append_To (Prim_Ops_Aggr_List, New_Node);
            end loop;

            New_Node :=
              Make_Aggregate (Loc, Expressions => Prim_Ops_Aggr_List);

            --  Remember aggregates initializing dispatch tables

            Append_Elmt (New_Node, DT_Aggr);

            Decl :=
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'S'),
                Subtype_Indication  =>
                  New_Occurrence_Of (RTE (RE_Address_Array), Loc));

            Append_To (Result, Decl);

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Predef_Prims,
                Constant_Present    => Building_Static_DT (Typ),
                Aliased_Present     => True,
                Object_Definition   => New_Occurrence_Of
                                         (Defining_Identifier (Decl), Loc),
                Expression => New_Node));
         end;

         --  Generate

         --   OSD : Ada.Tags.Object_Specific_Data (Nb_Prims) :=
         --          (OSD_Table => (1 => <value>,
         --                           ...
         --                         N => <value>));
         --   for OSD'Alignment use Address'Alignment;

         --   Iface_DT : Dispatch_Table (Nb_Prims) :=
         --               ([ Signature   => <sig-value> ],
         --                Tag_Kind      => <tag_kind-value>,
         --                Predef_Prims  => Predef_Prims'Address,
         --                Offset_To_Top => 0,
         --                OSD           => OSD'Address,
         --                Prims_Ptr     => (prim-op-1'address,
         --                                  prim-op-2'address,
         --                                  ...
         --                                  prim-op-n'address));

         --  Stage 3: Initialize the discriminant and the record components

         DT_Constr_List := New_List;
         DT_Aggr_List   := New_List;

         --  Nb_Prim

         Append_To (DT_Constr_List, Make_Integer_Literal (Loc, Nb_Prim));
         Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, Nb_Prim));

         --  Signature

         if RTE_Record_Component_Available (RE_Signature) then
            Append_To (DT_Aggr_List,
              New_Occurrence_Of (RTE (RE_Secondary_DT), Loc));
         end if;

         --  Tag_Kind

         if RTE_Record_Component_Available (RE_Tag_Kind) then
            Append_To (DT_Aggr_List, Tagged_Kind (Typ));
         end if;

         --  Predef_Prims

         Append_To (DT_Aggr_List,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Predef_Prims, Loc),
             Attribute_Name => Name_Address));

         --  Interface component located at variable offset; the value of
         --  Offset_To_Top will be set by the init subprogram.

         if No (Dummy_Object)
           or else Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
         then
            Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));

         --  Interface component located at fixed offset

         else
            Append_To (DT_Aggr_List,
              Make_Op_Minus (Loc,
                Make_Attribute_Reference (Loc,
                  Prefix         =>
                    Make_Selected_Component (Loc,
                      Prefix        =>
                        New_Occurrence_Of (Dummy_Object, Loc),
                      Selector_Name =>
                        New_Occurrence_Of (Iface_Comp, Loc)),
                  Attribute_Name => Name_Position)));
         end if;

         --  Generate the Object Specific Data table required to dispatch calls
         --  through synchronized interfaces.

         if Empty_DT
           or else Is_Abstract_Type (Typ)
           or else Is_Controlled (Typ)
           or else Restriction_Active (No_Dispatching_Calls)
           or else not Is_Limited_Type (Typ)
           or else not Has_Interfaces (Typ)
           or else not Build_Thunks
           or else not RTE_Record_Component_Available (RE_OSD_Table)
         then
            --  No OSD table required

            Append_To (DT_Aggr_List,
              New_Occurrence_Of (RTE (RE_Null_Address), Loc));

         else
            OSD_Aggr_List := New_List;

            declare
               Prim_Table : array (Nat range 1 .. Nb_Prim) of Entity_Id;
               Prim       : Entity_Id;
               Prim_Alias : Entity_Id;
               Prim_Elmt  : Elmt_Id;
               E          : Entity_Id;
               Count      : Nat := 0;
               Pos        : Nat;

            begin
               Prim_Table := (others => Empty);
               Prim_Alias := Empty;

               Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  if Present (Interface_Alias (Prim))
                    and then Find_Dispatching_Type
                               (Interface_Alias (Prim)) = Iface
                  then
                     Prim_Alias := Interface_Alias (Prim);
                     E   := Ultimate_Alias (Prim);
                     Pos := UI_To_Int (DT_Position (Prim_Alias));

                     if Present (Prim_Table (Pos)) then
                        pragma Assert (Prim_Table (Pos) = E);
                        null;

                     else
                        Prim_Table (Pos) := E;

                        Append_To (OSD_Aggr_List,
                          Make_Component_Association (Loc,
                            Choices    => New_List (
                              Make_Integer_Literal (Loc,
                                DT_Position (Prim_Alias))),
                            Expression =>
                              Make_Integer_Literal (Loc,
                                DT_Position (Alias (Prim)))));

                        Count := Count + 1;
                     end if;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;
               pragma Assert (Count = Nb_Prim);
            end;

            OSD := Make_Temporary (Loc, 'I');

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => OSD,
                Constant_Present    => True,
                Object_Definition   =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (RTE (RE_Object_Specific_Data), Loc),
                    Constraint   =>
                      Make_Index_Or_Discriminant_Constraint (Loc,
                        Constraints => New_List (
                          Make_Integer_Literal (Loc, Nb_Prim)))),

                Expression          =>
                  Make_Aggregate (Loc,
                    Component_Associations => New_List (
                      Make_Component_Association (Loc,
                        Choices    => New_List (
                          New_Occurrence_Of
                            (RTE_Record_Component (RE_OSD_Num_Prims), Loc)),
                        Expression =>
                          Make_Integer_Literal (Loc, Nb_Prim)),

                      Make_Component_Association (Loc,
                        Choices    => New_List (
                          New_Occurrence_Of
                            (RTE_Record_Component (RE_OSD_Table), Loc)),
                        Expression => Make_Aggregate (Loc,
                          Component_Associations => OSD_Aggr_List))))));

            Append_To (Result,
              Make_Attribute_Definition_Clause (Loc,
                Name       => New_Occurrence_Of (OSD, Loc),
                Chars      => Name_Alignment,
                Expression =>
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                      New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
                    Attribute_Name => Name_Alignment)));

            --  In secondary dispatch tables the Typeinfo component contains
            --  the address of the Object Specific Data (see a-tags.ads).

            Append_To (DT_Aggr_List,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (OSD, Loc),
                Attribute_Name => Name_Address));
         end if;

         --  Initialize the table of primitive operations

         Prim_Ops_Aggr_List := New_List;

         if Empty_DT then
            Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));

         elsif Is_Abstract_Type (Typ)
           or else not Building_Static_DT (Typ)
         then
            for J in 1 .. Nb_Prim loop
               Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
            end loop;

         else
            declare
               CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
               E            : Entity_Id;
               Prim_Pos     : Nat;
               Prim_Table   : array (Nat range 1 .. Nb_Prim) of Entity_Id;
               Thunk_Code   : Node_Id;
               Thunk_Id     : Entity_Id;

            begin
               Prim_Table := (others => Empty);

               Prim_Elmt  := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim     := Node (Prim_Elmt);
                  E        := Ultimate_Alias (Prim);
                  Prim_Pos := UI_To_Int (DT_Position (E));

                  --  Do not reference predefined primitives because they are
                  --  located in a separate dispatch table; skip abstract and
                  --  eliminated primitives; skip primitives located in the C++
                  --  part of the dispatch table because their slot is set by
                  --  the IC routine.

                  if not Is_Predefined_Dispatching_Operation (Prim)
                    and then Present (Interface_Alias (Prim))
                    and then not Is_Abstract_Subprogram (Alias (Prim))
                    and then not Is_Eliminated (Alias (Prim))
                    and then (not Is_CPP_Class (Root_Type (Typ))
                               or else Prim_Pos > CPP_Nb_Prims)
                    and then Find_Dispatching_Type
                               (Interface_Alias (Prim)) = Iface

                     --  Generate the code of the thunk only if the abstract
                     --  interface type is not an immediate ancestor of
                     --  Tagged_Type. Otherwise the DT associated with the
                     --  interface is the primary DT.

                    and then not Is_Ancestor (Iface, Typ,
                                              Use_Full_View => True)
                  then
                     if not Build_Thunks then
                        Prim_Pos :=
                          UI_To_Int (DT_Position (Interface_Alias (Prim)));
                        Prim_Table (Prim_Pos) := Alias (Prim);

                     else
                        Expand_Interface_Thunk
                          (Prim, Thunk_Id, Thunk_Code, Iface);

                        if Present (Thunk_Id) then
                           Prim_Pos :=
                             UI_To_Int (DT_Position (Interface_Alias (Prim)));

                           Prim_Table (Prim_Pos) := Thunk_Id;
                           Append_To (Result, Thunk_Code);
                        end if;
                     end if;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;

               for J in Prim_Table'Range loop
                  if Present (Prim_Table (J)) then
                     New_Node :=
                       Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                         Make_Attribute_Reference (Loc,
                           Prefix => New_Occurrence_Of (Prim_Table (J), Loc),
                           Attribute_Name => Name_Unrestricted_Access));

                  else
                     New_Node := Make_Null (Loc);
                  end if;

                  Append_To (Prim_Ops_Aggr_List, New_Node);
               end loop;
            end;
         end if;

         New_Node :=
           Make_Aggregate (Loc,
             Expressions => Prim_Ops_Aggr_List);

         Append_To (DT_Aggr_List, New_Node);

         --  Remember aggregates initializing dispatch tables

         Append_Elmt (New_Node, DT_Aggr);

         --  Note: Secondary dispatch tables are declared constant only if
         --  we can compute their offset field by means of the extra dummy
         --  object; otherwise they cannot be declared constant and the
         --  Offset_To_Top component is initialized by the IP routine.

         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Iface_DT,
             Aliased_Present     => True,
             Constant_Present    => Building_Static_Secondary_DT (Typ),

             Object_Definition   =>
               Make_Subtype_Indication (Loc,
                 Subtype_Mark => New_Occurrence_Of
                                   (RTE (RE_Dispatch_Table_Wrapper), Loc),
                 Constraint   => Make_Index_Or_Discriminant_Constraint (Loc,
                                   Constraints => DT_Constr_List)),

             Expression          =>
               Make_Aggregate (Loc,
                 Expressions => DT_Aggr_List)));

         if Exporting_Table then
            Export_DT (Typ, Iface_DT, Suffix_Index);

         --  Generate code to create the pointer to the dispatch table

         --    Iface_DT_Ptr : Tag := Tag!(DT.Prims_Ptr'Address);

         --  Note: This declaration is not added here if the table is exported
         --  because in such case Make_Tags has already added this declaration.

         else
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Iface_DT_Ptr,
                Constant_Present    => True,

                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Interface_Tag), Loc),

                Expression          =>
                  Unchecked_Convert_To (RTE (RE_Interface_Tag),
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        Make_Selected_Component (Loc,
                          Prefix        => New_Occurrence_Of (Iface_DT, Loc),
                          Selector_Name =>
                            New_Occurrence_Of
                              (RTE_Record_Component (RE_Prims_Ptr), Loc)),
                      Attribute_Name => Name_Address))));
         end if;

         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Predef_Prims_Ptr,
             Constant_Present    => True,

             Object_Definition   =>
               New_Occurrence_Of (RTE (RE_Address), Loc),

             Expression          =>
               Make_Attribute_Reference (Loc,
                 Prefix         =>
                   Make_Selected_Component (Loc,
                     Prefix        => New_Occurrence_Of (Iface_DT, Loc),
                     Selector_Name =>
                       New_Occurrence_Of
                         (RTE_Record_Component (RE_Predef_Prims), Loc)),
                 Attribute_Name => Name_Address)));

         --  Remember entities containing dispatch tables

         Append_Elmt (Predef_Prims, DT_Decl);
         Append_Elmt (Iface_DT, DT_Decl);
      end Make_Secondary_DT;

      --------------------------------
      -- Number_Of_Predefined_Prims --
      --------------------------------

      function Number_Of_Predefined_Prims (Typ : Entity_Id) return Nat is
         Nb_Predef_Prims : Nat := 0;

      begin
         if not Generate_SCIL then
            declare
               Prim      : Entity_Id;
               Prim_Elmt : Elmt_Id;
               Pos       : Nat;

            begin
               Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  if Is_Predefined_Dispatching_Operation (Prim)
                    and then not Is_Abstract_Subprogram (Prim)
                  then
                     Pos := UI_To_Int (DT_Position (Prim));

                     if Pos > Nb_Predef_Prims then
                        Nb_Predef_Prims := Pos;
                     end if;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;
            end;
         end if;

         pragma Assert (Nb_Predef_Prims <= Max_Predef_Prims);
         return Nb_Predef_Prims;
      end Number_Of_Predefined_Prims;

      --  Local variables

      Elab_Code : constant List_Id := New_List;
      Result    : constant List_Id := New_List;
      Tname     : constant Name_Id := Chars (Typ);

      --  When pragmas Discard_Names and No_Tagged_Streams simultaneously apply
      --  we initialize the Expanded_Name and the External_Tag of this tagged
      --  type with an empty string. This is useful to avoid exposing entity
      --  names at binary level. It can be done when both pragmas apply because
      --    (1) Discard_Names allows initializing Expanded_Name with an
      --        implementation defined value (Ada RM Section C.5 (7/2)).
      --    (2) External_Tag (combined with Internal_Tag) is used for object
      --        streaming and No_Tagged_Streams inhibits the generation of
      --        streams.

      Discard_Names : constant Boolean :=
                        Present (No_Tagged_Streams_Pragma (Typ))
                          and then
        (Global_Discard_Names or else Einfo.Entities.Discard_Names (Typ));

      --  The following name entries are used by Make_DT to generate a number
      --  of entities related to a tagged type. These entities may be generated
      --  in a scope other than that of the tagged type declaration, and if
      --  the entities for two tagged types with the same name happen to be
      --  generated in the same scope, we have to take care to use different
      --  names. This is achieved by means of a unique serial number appended
      --  to each generated entity name.

      Name_DT           : constant Name_Id :=
                            New_External_Name (Tname, 'T', Suffix_Index => -1);
      Name_Exname       : constant Name_Id :=
                            New_External_Name (Tname, 'E', Suffix_Index => -1);
      Name_HT_Link      : constant Name_Id :=
                            New_External_Name (Tname, 'H', Suffix_Index => -1);
      Name_Predef_Prims : constant Name_Id :=
                            New_External_Name (Tname, 'R', Suffix_Index => -1);
      Name_SSD          : constant Name_Id :=
                            New_External_Name (Tname, 'S', Suffix_Index => -1);
      Name_TSD          : constant Name_Id :=
                            New_External_Name (Tname, 'B', Suffix_Index => -1);

      Saved_GM  : constant Ghost_Mode_Type := Ghost_Mode;
      Saved_IGR : constant Node_Id         := Ignored_Ghost_Region;
      --  Save the Ghost-related attributes to restore on exit

      AI                 : Elmt_Id;
      AI_Tag_Elmt        : Elmt_Id;
      AI_Tag_Comp        : Elmt_Id;
      DT                 : Entity_Id;
      DT_Aggr_List       : List_Id;
      DT_Constr_List     : List_Id;
      DT_Ptr             : Entity_Id;
      Exname             : Entity_Id;
      HT_Link            : Entity_Id;
      ITable             : Node_Id;
      I_Depth            : Nat;
      Iface_Table_Node   : Node_Id;
      Name_ITable        : Name_Id;
      Nb_Prim            : Nat := 0;
      New_Node           : Node_Id;
      Num_Ifaces         : Nat := 0;
      Parent_Typ         : Entity_Id;
      Predef_Prims       : Entity_Id;
      Prim               : Entity_Id;
      Prim_Elmt          : Elmt_Id;
      Prim_Ops_Aggr_List : List_Id;
      SSD                : Entity_Id;
      Suffix_Index       : Int;
      Typ_Comps          : Elist_Id;
      Typ_Ifaces         : Elist_Id;
      TSD                : Entity_Id;
      TSD_Aggr_List      : List_Id;
      TSD_Tags_List      : List_Id;

   --  Start of processing for Make_DT

   begin
      pragma Assert (Is_Frozen (Typ));

      --  The tagged type being processed may be subject to pragma Ghost. Set
      --  the mode now to ensure that any nodes generated during dispatch table
      --  creation are properly marked as Ghost.

      Set_Ghost_Mode (Typ);

      --  Handle cases in which there is no need to build the dispatch table

      if Has_Dispatch_Table (Typ)
        or else No (Access_Disp_Table (Typ))
        or else Is_CPP_Class (Typ)
      then
         goto Leave;

      elsif No_Run_Time_Mode then
         Error_Msg_CRT ("tagged types", Typ);
         goto Leave;

      elsif not RTE_Available (RE_Tag) then
         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier =>
               Node (First_Elmt (Access_Disp_Table (Typ))),
             Object_Definition   => New_Occurrence_Of (RTE (RE_Tag), Loc),
             Constant_Present    => True,
             Expression =>
               Unchecked_Convert_To (RTE (RE_Tag),
                 New_Occurrence_Of (RTE (RE_Null_Address), Loc))));

         Analyze_List (Result, Suppress => All_Checks);
         Error_Msg_CRT ("tagged types", Typ);
         goto Leave;
      end if;

      --  Ensure that the value of Max_Predef_Prims defined in a-tags is
      --  correct. Valid values are 10 under configurable runtime or 16
      --  with full runtime.

      if RTE_Available (RE_Interface_Data) then
         if Max_Predef_Prims /= 16 then
            Error_Msg_N ("run-time library configuration error", Typ);
            goto Leave;
         end if;
      else
         if Max_Predef_Prims /= 10 then
            Error_Msg_N ("run-time library configuration error", Typ);
            Error_Msg_CRT ("tagged types", Typ);
            goto Leave;
         end if;
      end if;

      DT           := Make_Defining_Identifier (Loc, Name_DT);
      Exname       := Make_Defining_Identifier (Loc, Name_Exname);
      HT_Link      := Make_Defining_Identifier (Loc, Name_HT_Link);
      Predef_Prims := Make_Defining_Identifier (Loc, Name_Predef_Prims);
      SSD          := Make_Defining_Identifier (Loc, Name_SSD);
      TSD          := Make_Defining_Identifier (Loc, Name_TSD);

      --  Initialize Parent_Typ handling private types

      Parent_Typ := Etype (Typ);

      if Present (Full_View (Parent_Typ)) then
         Parent_Typ := Full_View (Parent_Typ);
      end if;

      --  Ensure that all the primitives are frozen. This is only required when
      --  building static dispatch tables --- the primitives must be frozen to
      --  be referenced (otherwise we have problems with the backend). It is
      --  not a requirement with nonstatic dispatch tables because in this case
      --  we generate now an empty dispatch table; the extra code required to
      --  register the primitives in the slots will be generated later --- when
      --  each primitive is frozen (see Freeze_Subprogram).

      if Building_Static_DT (Typ) then
         declare
            Saved_FLLTT : constant Boolean :=
                            Freezing_Library_Level_Tagged_Type;

            Formal    : Entity_Id;
            Frnodes   : List_Id;
            Prim      : Entity_Id;
            Prim_Elmt : Elmt_Id;

         begin
            Freezing_Library_Level_Tagged_Type := True;

            Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
            while Present (Prim_Elmt) loop
               Prim    := Node (Prim_Elmt);
               Frnodes := Freeze_Entity (Prim, Typ);

               --  We disable this check for abstract subprograms, given that
               --  they cannot be called directly and thus the state of their
               --  untagged formals is of no concern. The RM is unclear in any
               --  case concerning the need for this check, and this topic may
               --  go back to the ARG.

               if not Is_Abstract_Subprogram (Prim)  then
                  Formal := First_Formal (Prim);
                  while Present (Formal) loop
                     Check_Premature_Freezing (Prim, Typ, Etype (Formal));
                     Next_Formal (Formal);
                  end loop;

                  Check_Premature_Freezing (Prim, Typ, Etype (Prim));
               end if;

               if Present (Frnodes) then
                  Append_List_To (Result, Frnodes);
               end if;

               Next_Elmt (Prim_Elmt);
            end loop;

            Freezing_Library_Level_Tagged_Type := Saved_FLLTT;
         end;
      end if;

      if not Is_Interface (Typ) and then Has_Interfaces (Typ) then
         declare
            Cannot_Have_Null_Disc : Boolean := False;
            Dummy_Object_Typ      : constant Entity_Id := Typ;
            Name_Dummy_Object     : constant Name_Id :=
                                      New_External_Name (Tname,
                                        'P', Suffix_Index => -1);
         begin
            Dummy_Object := Make_Defining_Identifier (Loc, Name_Dummy_Object);

            --  Define the extra object imported and constant to avoid linker
            --  errors (since this object is never declared). Required because
            --  we implement RM 13.3(19) for exported and imported (variable)
            --  objects by making them volatile.

            Set_Is_Imported      (Dummy_Object);
            Mutate_Ekind         (Dummy_Object, E_Constant);
            Set_Is_True_Constant (Dummy_Object);
            Set_Related_Type     (Dummy_Object, Typ);

            --  The scope must be set now to call Get_External_Name

            Set_Scope (Dummy_Object, Current_Scope);

            Get_External_Name (Dummy_Object);
            Set_Interface_Name (Dummy_Object,
              Make_String_Literal (Loc, Strval => String_From_Name_Buffer));

            --  Ensure proper Sprint output of this implicit importation

            Set_Is_Internal (Dummy_Object);

            if not Has_Discriminants (Dummy_Object_Typ) then
               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Dummy_Object,
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of
                                           (Dummy_Object_Typ, Loc)));
            else
               declare
                  Constr_List  : constant List_Id := New_List;
                  Discrim      : Node_Id;

               begin
                  Discrim := First_Discriminant (Dummy_Object_Typ);
                  while Present (Discrim) loop
                     if Is_Discrete_Type (Etype (Discrim)) then
                        Append_To (Constr_List,
                          Make_Attribute_Reference (Loc,
                            Prefix         =>
                              New_Occurrence_Of (Etype (Discrim), Loc),
                            Attribute_Name => Name_First));

                     else
                        pragma Assert (Is_Access_Type (Etype (Discrim)));
                        Cannot_Have_Null_Disc :=
                          Cannot_Have_Null_Disc
                            or else Can_Never_Be_Null (Etype (Discrim));
                        Append_To (Constr_List, Make_Null (Loc));
                     end if;

                     Next_Discriminant (Discrim);
                  end loop;

                  Append_To (Result,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Dummy_Object,
                      Constant_Present    => True,
                      Object_Definition   =>
                        Make_Subtype_Indication (Loc,
                          Subtype_Mark =>
                            New_Occurrence_Of (Dummy_Object_Typ, Loc),
                          Constraint   =>
                            Make_Index_Or_Discriminant_Constraint (Loc,
                              Constraints => Constr_List))));
               end;
            end if;

            --  Given that the dummy object will not be declared at run time,
            --  analyze its declaration with expansion disabled and warnings
            --  and error messages ignored.

            Expander_Mode_Save_And_Set (False);
            Ignore_Errors_Enable := Ignore_Errors_Enable + 1;
            Analyze (Last (Result), Suppress => All_Checks);
            Ignore_Errors_Enable := Ignore_Errors_Enable - 1;
            Expander_Mode_Restore;
         end;
      end if;

      --  Ada 2005 (AI-251): Build the secondary dispatch tables

      if Has_Interfaces (Typ) then
         Collect_Interface_Components (Typ, Typ_Comps);

         --  Each secondary dispatch table is assigned an unique positive
         --  suffix index; such value also corresponds with the location of
         --  its entity in the Dispatch_Table_Wrappers list (see Make_Tags).

         --  Note: This value must be kept sync with the Suffix_Index values
         --  generated by Make_Tags

         Suffix_Index := 1;
         AI_Tag_Elmt  :=
           Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));

         AI_Tag_Comp := First_Elmt (Typ_Comps);
         while Present (AI_Tag_Comp) loop
            pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'P'));

            --  Build the secondary table containing pointers to thunks

            Make_Secondary_DT
             (Typ              => Typ,
              Iface            =>
                Base_Type (Related_Type (Node (AI_Tag_Comp))),
              Iface_Comp       => Node (AI_Tag_Comp),
              Suffix_Index     => Suffix_Index,
              Num_Iface_Prims  =>
                UI_To_Int (DT_Entry_Count (Node (AI_Tag_Comp))),
              Iface_DT_Ptr     => Node (AI_Tag_Elmt),
              Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
              Build_Thunks     => True,
              Result           => Result);

            --  Skip secondary dispatch table referencing thunks to predefined
            --  primitives.

            Next_Elmt (AI_Tag_Elmt);
            pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Y'));

            --  Secondary dispatch table referencing user-defined primitives
            --  covered by this interface.

            Next_Elmt (AI_Tag_Elmt);
            pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'D'));

            --  Build the secondary table containing pointers to primitives
            --  (used to give support to Generic Dispatching Constructors).

            Make_Secondary_DT
              (Typ              => Typ,
               Iface            => Base_Type
                                     (Related_Type (Node (AI_Tag_Comp))),
               Iface_Comp       => Node (AI_Tag_Comp),
               Suffix_Index     => -1,
               Num_Iface_Prims  => UI_To_Int
                                     (DT_Entry_Count (Node (AI_Tag_Comp))),
               Iface_DT_Ptr     => Node (AI_Tag_Elmt),
               Predef_Prims_Ptr => Node (Next_Elmt (AI_Tag_Elmt)),
               Build_Thunks     => False,
               Result           => Result);

            --  Skip secondary dispatch table referencing predefined primitives

            Next_Elmt (AI_Tag_Elmt);
            pragma Assert (Has_Suffix (Node (AI_Tag_Elmt), 'Z'));

            Suffix_Index := Suffix_Index + 1;
            Next_Elmt (AI_Tag_Elmt);
            Next_Elmt (AI_Tag_Comp);
         end loop;
      end if;

      --  Get the _tag entity and number of primitives of its dispatch table

      DT_Ptr  := Node (First_Elmt (Access_Disp_Table (Typ)));
      Nb_Prim := UI_To_Int (DT_Entry_Count (First_Tag_Component (Typ)));

      if Generate_SCIL then
         Nb_Prim := 0;
      end if;

      Set_Is_Statically_Allocated (DT,  Is_Library_Level_Tagged_Type (Typ));
      Set_Is_Statically_Allocated (SSD, Is_Library_Level_Tagged_Type (Typ));
      Set_Is_Statically_Allocated (TSD, Is_Library_Level_Tagged_Type (Typ));
      Set_Is_Statically_Allocated (Predef_Prims,
        Is_Library_Level_Tagged_Type (Typ));

      --  In case of locally defined tagged type we declare the object
      --  containing the dispatch table by means of a variable. Its
      --  initialization is done later by means of an assignment. This is
      --  required to generate its External_Tag.

      if not Building_Static_DT (Typ) then

         --  Generate:
         --    DT     : No_Dispatch_Table_Wrapper;
         --    DT_Ptr : Tag := !Tag (DT.NDT_Prims_Ptr'Address);

         if not Has_DT (Typ) then
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT,
                Aliased_Present     => True,
                Constant_Present    => False,
                Object_Definition   =>
                  New_Occurrence_Of
                    (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT_Ptr,
                Object_Definition   => New_Occurrence_Of (RTE (RE_Tag), Loc),
                Constant_Present    => True,
                Expression =>
                  Unchecked_Convert_To (RTE (RE_Tag),
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        Make_Selected_Component (Loc,
                          Prefix        => New_Occurrence_Of (DT, Loc),
                          Selector_Name =>
                            New_Occurrence_Of
                              (RTE_Record_Component (RE_NDT_Prims_Ptr), Loc)),
                      Attribute_Name => Name_Address))));

            Set_Is_Statically_Allocated (DT_Ptr,
              Is_Library_Level_Tagged_Type (Typ));

            --  Generate the SCIL node for the previous object declaration
            --  because it has a tag initialization.

            if Generate_SCIL then
               New_Node :=
                 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
               Set_SCIL_Entity (New_Node, Typ);
               Set_SCIL_Node (Last (Result), New_Node);

               goto Leave_SCIL;

               --  Gnat2scil has its own implementation of dispatch tables,
               --  different than what is being implemented here. Generating
               --  further dispatch table initialization code would just
               --  cause gnat2scil to generate useless Scil which CodePeer
               --  would waste time and space analyzing, so we skip it.
            end if;

         --  Generate:
         --    DT : Dispatch_Table_Wrapper (Nb_Prim);
         --    DT_Ptr : Tag := !Tag (DT.Prims_Ptr'Address);

         else
            --  If the tagged type has no primitives we add a dummy slot
            --  whose address will be the tag of this type.

            if Nb_Prim = 0 then
               DT_Constr_List :=
                 New_List (Make_Integer_Literal (Loc, 1));
            else
               DT_Constr_List :=
                 New_List (Make_Integer_Literal (Loc, Nb_Prim));
            end if;

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT,
                Aliased_Present     => True,
                Constant_Present    => False,
                Object_Definition   =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (RTE (RE_Dispatch_Table_Wrapper), Loc),
                    Constraint   =>
                      Make_Index_Or_Discriminant_Constraint (Loc,
                        Constraints => DT_Constr_List))));

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT_Ptr,
                Object_Definition   => New_Occurrence_Of (RTE (RE_Tag), Loc),
                Constant_Present    => True,
                Expression =>
                  Unchecked_Convert_To (RTE (RE_Tag),
                    Make_Attribute_Reference (Loc,
                      Prefix         =>
                        Make_Selected_Component (Loc,
                          Prefix        => New_Occurrence_Of (DT, Loc),
                          Selector_Name =>
                            New_Occurrence_Of
                              (RTE_Record_Component (RE_Prims_Ptr), Loc)),
                      Attribute_Name => Name_Address))));

            Set_Is_Statically_Allocated (DT_Ptr,
              Is_Library_Level_Tagged_Type (Typ));

            --  Generate the SCIL node for the previous object declaration
            --  because it has a tag initialization.

            if Generate_SCIL then
               New_Node :=
                 Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
               Set_SCIL_Entity (New_Node, Typ);
               Set_SCIL_Node (Last (Result), New_Node);

               goto Leave_SCIL;

               --  Gnat2scil has its own implementation of dispatch tables,
               --  different than what is being implemented here. Generating
               --  further dispatch table initialization code would just
               --  cause gnat2scil to generate useless Scil which CodePeer
               --  would waste time and space analyzing, so we skip it.
            end if;

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier =>
                  Node (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))),
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_Address), Loc),
                Expression          =>
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                      Make_Selected_Component (Loc,
                        Prefix        => New_Occurrence_Of (DT, Loc),
                        Selector_Name =>
                          New_Occurrence_Of
                            (RTE_Record_Component (RE_Predef_Prims), Loc)),
                    Attribute_Name => Name_Address)));
         end if;
      end if;

      --  Generate: Expanded_Name : constant String := "";

      if Discard_Names then
         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Exname,
             Constant_Present    => True,
             Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
             Expression =>
               Make_String_Literal (Loc, "")));

      --  Generate: Exname : constant String := full_qualified_name (typ);
      --  The type itself may be an anonymous parent type, so use the first
      --  subtype to have a user-recognizable name.

      else
         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Exname,
             Constant_Present    => True,
             Object_Definition   => New_Occurrence_Of (Standard_String, Loc),
             Expression =>
               Make_String_Literal (Loc,
                 Fully_Qualified_Name_String (First_Subtype (Typ)))));
      end if;

      Set_Is_Statically_Allocated (Exname);
      Set_Is_True_Constant (Exname);

      --  Declare the object used by Ada.Tags.Register_Tag

      if RTE_Available (RE_Register_Tag) then
         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier => HT_Link,
             Object_Definition   => New_Occurrence_Of (RTE (RE_Tag), Loc),
             Expression          => New_Occurrence_Of (RTE (RE_No_Tag), Loc)));
      end if;

      --  Generate code to create the storage for the type specific data object
      --  with enough space to store the tags of the ancestors plus the tags
      --  of all the implemented interfaces (as described in a-tags.adb).

      --   TSD : Type_Specific_Data (I_Depth) :=
      --           (Idepth             => I_Depth,
      --            Access_Level       => Type_Access_Level (Typ),
      --            Alignment          => Typ'Alignment,
      --            Expanded_Name      => Cstring_Ptr!(Exname'Address))
      --            External_Tag       => Cstring_Ptr!(Exname'Address))
      --            HT_Link            => HT_Link'Address,
      --            Transportable      => <<boolean-value>>,
      --            Is_Abstract        => <<boolean-value>>,
      --            Needs_Finalization => <<boolean-value>>,
      --            [ Size_Func         => Size_Prim'Access, ]
      --            [ Interfaces_Table  => <<access-value>>, ]
      --            [ SSD               => SSD_Table'Address ]
      --            Tags_Table         => (0 => null,
      --                                   1 => Parent'Tag
      --                                   ...);

      TSD_Aggr_List := New_List;

      --  Idepth: Count ancestors to compute the inheritance depth. For private
      --  extensions, always go to the full view in order to compute the real
      --  inheritance depth.

      declare
         Current_Typ : Entity_Id;
         Parent_Typ  : Entity_Id;

      begin
         I_Depth     := 0;
         Current_Typ := Typ;
         loop
            Parent_Typ := Etype (Current_Typ);

            if Is_Private_Type (Parent_Typ) then
               Parent_Typ := Full_View (Base_Type (Parent_Typ));
            end if;

            exit when Parent_Typ = Current_Typ;

            I_Depth := I_Depth + 1;
            Current_Typ := Parent_Typ;
         end loop;
      end;

      Append_To (TSD_Aggr_List,
        Make_Integer_Literal (Loc, I_Depth));

      --  Access_Level

      Append_To (TSD_Aggr_List,
        Make_Integer_Literal (Loc, Type_Access_Level (Typ)));

      --  Alignment

      --  For CPP types we cannot rely on the value of 'Alignment provided
      --  by the backend to initialize this TSD field.

      if Convention (Typ) = Convention_CPP
        or else Is_CPP_Class (Root_Type (Typ))
      then
         Append_To (TSD_Aggr_List,
           Make_Integer_Literal (Loc, 0));
      else
         Append_To (TSD_Aggr_List,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Typ, Loc),
             Attribute_Name => Name_Alignment));
      end if;

      --  Expanded_Name

      Append_To (TSD_Aggr_List,
        Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
          Make_Attribute_Reference (Loc,
            Prefix         => New_Occurrence_Of (Exname, Loc),
            Attribute_Name => Name_Address)));

      --  External_Tag of a local tagged type

      --     <typ>A : constant String :=
      --                "Internal tag at 16#tag-addr#: <full-name-of-typ>";

      --  The reason we generate this strange name is that we do not want to
      --  enter local tagged types in the global hash table used to compute
      --  the Internal_Tag attribute for two reasons:

      --    1. It is hard to avoid a tasking race condition for entering the
      --    entry into the hash table.

      --    2. It would cause a storage leak, unless we rig up considerable
      --    mechanism to remove the entry from the hash table on exit.

      --  So what we do is to generate the above external tag name, where the
      --  hex address is the address of the local dispatch table (i.e. exactly
      --  the value we want if Internal_Tag is computed from this string).

      --  Of course this value will only be valid if the tagged type is still
      --  in scope, but it clearly must be erroneous to compute the internal
      --  tag of a tagged type that is out of scope.

      --  We don't do this processing if an explicit external tag has been
      --  specified. That's an odd case for which we have already issued a
      --  warning, where we will not be able to compute the internal tag.

      if not Discard_Names
        and then not Is_Library_Level_Entity (Typ)
        and then not Has_External_Tag_Rep_Clause (Typ)
      then
         declare
            Exname    : constant Entity_Id :=
                          Make_Defining_Identifier (Loc,
                            Chars => New_External_Name (Tname, 'A'));
            Full_Name : constant String_Id :=
                            Fully_Qualified_Name_String (First_Subtype (Typ));
            Str1_Id   : String_Id;
            Str2_Id   : String_Id;

         begin
            --  Generate:
            --    Str1 = "Internal tag at 16#";

            Start_String;
            Store_String_Chars ("Internal tag at 16#");
            Str1_Id := End_String;

            --  Generate:
            --    Str2 = "#: <type-full-name>";

            Start_String;
            Store_String_Chars ("#: ");
            Store_String_Chars (Full_Name);
            Str2_Id := End_String;

            --  Generate:
            --    Exname : constant String :=
            --               Str1 & Address_Image (Tag) & Str2;

            if RTE_Available (RE_Address_Image) then
               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Exname,
                   Constant_Present    => True,
                   Object_Definition   => New_Occurrence_Of
                                            (Standard_String, Loc),
                   Expression =>
                     Make_Op_Concat (Loc,
                       Left_Opnd  => Make_String_Literal (Loc, Str1_Id),
                       Right_Opnd =>
                         Make_Op_Concat (Loc,
                           Left_Opnd  =>
                             Make_Function_Call (Loc,
                               Name =>
                                 New_Occurrence_Of
                                   (RTE (RE_Address_Image), Loc),
                               Parameter_Associations => New_List (
                                 Unchecked_Convert_To (RTE (RE_Address),
                                   New_Occurrence_Of (DT_Ptr, Loc)))),
                           Right_Opnd =>
                             Make_String_Literal (Loc, Str2_Id)))));

            --  Generate:
            --    Exname : constant String := Str1 & Str2;

            else
               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Exname,
                   Constant_Present    => True,
                   Object_Definition   =>
                     New_Occurrence_Of (Standard_String, Loc),
                   Expression          =>
                     Make_Op_Concat (Loc,
                       Left_Opnd  => Make_String_Literal (Loc, Str1_Id),
                       Right_Opnd => Make_String_Literal (Loc, Str2_Id))));
            end if;

            New_Node :=
              Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
                Make_Attribute_Reference (Loc,
                  Prefix         => New_Occurrence_Of (Exname, Loc),
                  Attribute_Name => Name_Address));
         end;

      --  External tag of a library-level tagged type: Check for a definition
      --  of External_Tag. The clause is considered only if it applies to this
      --  specific tagged type, as opposed to one of its ancestors.
      --  If the type is an unconstrained type extension, we are building the
      --  dispatch table of its anonymous base type, so the external tag, if
      --  any was specified, must be retrieved from the first subtype. Go to
      --  the full view in case the clause is in the private part.

      else
         declare
            Def : constant Node_Id := Get_Attribute_Definition_Clause
                                        (Underlying_Type (First_Subtype (Typ)),
                                         Attribute_External_Tag);

            Old_Val : String_Id;
            New_Val : String_Id;
            E       : Entity_Id;

         begin
            if not Present (Def)
              or else Entity (Name (Def)) /= First_Subtype (Typ)
            then
               New_Node :=
                 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
                   Make_Attribute_Reference (Loc,
                     Prefix         => New_Occurrence_Of (Exname, Loc),
                     Attribute_Name => Name_Address));
            else
               Old_Val := Strval (Expr_Value_S (Expression (Def)));

               --  For the rep clause "for <typ>'external_tag use y" generate:

               --     <typ>A : constant string := y;
               --
               --  <typ>A'Address is used to set the External_Tag component
               --  of the TSD

               --  Create a new nul terminated string if it is not already

               if String_Length (Old_Val) > 0
                 and then
                  Get_String_Char (Old_Val, String_Length (Old_Val)) = 0
               then
                  New_Val := Old_Val;
               else
                  Start_String (Old_Val);
                  Store_String_Char (Get_Char_Code (ASCII.NUL));
                  New_Val := End_String;
               end if;

               E := Make_Defining_Identifier (Loc,
                      New_External_Name (Chars (Typ), 'A'));

               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => E,
                   Constant_Present    => True,
                   Object_Definition   =>
                     New_Occurrence_Of (Standard_String, Loc),
                   Expression          =>
                     Make_String_Literal (Loc, New_Val)));

               New_Node :=
                 Unchecked_Convert_To (RTE (RE_Cstring_Ptr),
                   Make_Attribute_Reference (Loc,
                     Prefix         => New_Occurrence_Of (E, Loc),
                     Attribute_Name => Name_Address));
            end if;
         end;
      end if;

      Append_To (TSD_Aggr_List, New_Node);

      --  HT_Link

      if RTE_Available (RE_Register_Tag) then
         Append_To (TSD_Aggr_List,
           Unchecked_Convert_To (RTE (RE_Tag_Ptr),
             Make_Attribute_Reference (Loc,
               Prefix         => New_Occurrence_Of (HT_Link, Loc),
               Attribute_Name => Name_Address)));

      elsif RTE_Record_Component_Available (RE_HT_Link) then
         Append_To (TSD_Aggr_List,
           Unchecked_Convert_To (RTE (RE_Tag_Ptr),
             New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
      end if;

      --  Transportable: Set for types that can be used in remote calls
      --  with respect to E.4(18) legality rules.

      declare
         Transportable : Entity_Id;

      begin
         Transportable :=
           Boolean_Literals
             (Is_Pure (Typ)
                or else Is_Shared_Passive (Typ)
                or else
                  ((Is_Remote_Types (Typ)
                     or else Is_Remote_Call_Interface (Typ))
                   and then Original_View_In_Visible_Part (Typ))
                or else not Comes_From_Source (Typ));

         Append_To (TSD_Aggr_List,
            New_Occurrence_Of (Transportable, Loc));
      end;

      --  Is_Abstract (Ada 2012: AI05-0173). This functionality is not
      --  available in the HIE runtime.

      if RTE_Record_Component_Available (RE_Is_Abstract) then
         declare
            Is_Abstract : Entity_Id;
         begin
            Is_Abstract := Boolean_Literals (Is_Abstract_Type (Typ));
            Append_To (TSD_Aggr_List,
              New_Occurrence_Of (Is_Abstract, Loc));
         end;
      end if;

      --  Needs_Finalization: Set if the type is controlled or has controlled
      --  components.

      declare
         Needs_Fin : Entity_Id;
      begin
         Needs_Fin := Boolean_Literals (Needs_Finalization (Typ));
         Append_To (TSD_Aggr_List, New_Occurrence_Of (Needs_Fin, Loc));
      end;

      --  Size_Func

      if RTE_Record_Component_Available (RE_Size_Func) then

         --  Initialize this field to Null_Address if we are not building
         --  static dispatch tables static or if the size function is not
         --  available. In the former case we cannot initialize this field
         --  until the function is frozen and registered in the dispatch
         --  table (see Register_Primitive).

         if not Building_Static_DT (Typ) or else not Has_DT (Typ) then
            Append_To (TSD_Aggr_List,
              Unchecked_Convert_To (RTE (RE_Size_Ptr),
                New_Occurrence_Of (RTE (RE_Null_Address), Loc)));

         else
            declare
               Prim_Elmt : Elmt_Id;
               Prim      : Entity_Id;
               Size_Comp : Node_Id := Empty;

            begin
               Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  if Chars (Prim) = Name_uSize then
                     Prim := Ultimate_Alias (Prim);

                     if Is_Abstract_Subprogram (Prim) then
                        Size_Comp :=
                          Unchecked_Convert_To (RTE (RE_Size_Ptr),
                            New_Occurrence_Of (RTE (RE_Null_Address), Loc));
                     else
                        Size_Comp :=
                          Unchecked_Convert_To (RTE (RE_Size_Ptr),
                            Make_Attribute_Reference (Loc,
                              Prefix         => New_Occurrence_Of (Prim, Loc),
                              Attribute_Name => Name_Unrestricted_Access));
                     end if;

                     exit;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;

               pragma Assert (Present (Size_Comp));
               Append_To (TSD_Aggr_List, Size_Comp);
            end;
         end if;
      end if;

      --  Interfaces_Table (required for AI-405)

      if RTE_Record_Component_Available (RE_Interfaces_Table) then

         --  Count the number of interface types implemented by Typ

         Collect_Interfaces (Typ, Typ_Ifaces);

         AI := First_Elmt (Typ_Ifaces);
         while Present (AI) loop
            Num_Ifaces := Num_Ifaces + 1;
            Next_Elmt (AI);
         end loop;

         if Num_Ifaces = 0 then
            Iface_Table_Node := Make_Null (Loc);

         --  Generate the Interface_Table object

         else
            declare
               TSD_Ifaces_List  : constant List_Id := New_List;
               Elmt             : Elmt_Id;
               Offset_To_Top    : Node_Id;
               Sec_DT_Tag       : Node_Id;

               Dummy_Object_Ifaces_List      : Elist_Id := No_Elist;
               Dummy_Object_Ifaces_Comp_List : Elist_Id := No_Elist;
               Dummy_Object_Ifaces_Tag_List  : Elist_Id := No_Elist;
               --  Interfaces information of the dummy object

            begin
               --  Collect interfaces information if we need to compute the
               --  offset to the top using the dummy object.

               if Present (Dummy_Object) then
                  Collect_Interfaces_Info (Typ,
                    Ifaces_List     => Dummy_Object_Ifaces_List,
                    Components_List => Dummy_Object_Ifaces_Comp_List,
                    Tags_List       => Dummy_Object_Ifaces_Tag_List);
               end if;

               AI := First_Elmt (Typ_Ifaces);
               while Present (AI) loop
                  if Is_Ancestor (Node (AI), Typ, Use_Full_View => True) then
                     Sec_DT_Tag := New_Occurrence_Of (DT_Ptr, Loc);

                  else
                     Elmt :=
                       Next_Elmt
                        (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
                     pragma Assert (Has_Thunks (Node (Elmt)));

                     while Is_Tag (Node (Elmt))
                       and then not
                         Is_Ancestor (Node (AI), Related_Type (Node (Elmt)),
                                      Use_Full_View => True)
                     loop
                        pragma Assert (Has_Thunks (Node (Elmt)));
                        Next_Elmt (Elmt);
                        pragma Assert (Has_Thunks (Node (Elmt)));
                        Next_Elmt (Elmt);
                        pragma Assert (not Has_Thunks (Node (Elmt)));
                        Next_Elmt (Elmt);
                        pragma Assert (not Has_Thunks (Node (Elmt)));
                        Next_Elmt (Elmt);
                     end loop;

                     pragma Assert (Ekind (Node (Elmt)) = E_Constant
                       and then not
                         Has_Thunks (Node (Next_Elmt (Next_Elmt (Elmt)))));

                     Sec_DT_Tag :=
                       New_Occurrence_Of
                         (Node (Next_Elmt (Next_Elmt (Elmt))), Loc);
                  end if;

                  --  Use the dummy object to compute Offset_To_Top of
                  --  components located at fixed position.

                  if Present (Dummy_Object) then
                     declare
                        Iface            : constant Node_Id := Node (AI);
                        Iface_Comp       : Node_Id := Empty;
                        Iface_Comp_Elmt  : Elmt_Id;
                        Iface_Elmt       : Elmt_Id;

                     begin
                        Iface_Elmt :=
                          First_Elmt (Dummy_Object_Ifaces_List);
                        Iface_Comp_Elmt :=
                          First_Elmt (Dummy_Object_Ifaces_Comp_List);

                        while Present (Iface_Elmt) loop
                           if Node (Iface_Elmt) = Iface then
                              Iface_Comp := Node (Iface_Comp_Elmt);
                              exit;
                           end if;

                           Next_Elmt (Iface_Elmt);
                           Next_Elmt (Iface_Comp_Elmt);
                        end loop;

                        pragma Assert (Present (Iface_Comp));

                        if not
                          Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
                        then
                           Offset_To_Top :=
                             Make_Op_Minus (Loc,
                               Make_Attribute_Reference (Loc,
                                 Prefix         =>
                                   Make_Selected_Component (Loc,
                                     Prefix        =>
                                       New_Occurrence_Of (Dummy_Object, Loc),
                                     Selector_Name =>
                                       New_Occurrence_Of (Iface_Comp, Loc)),
                                 Attribute_Name => Name_Position));
                        else
                           Offset_To_Top := Make_Integer_Literal (Loc, 0);
                        end if;
                     end;
                  else
                     Offset_To_Top := Make_Integer_Literal (Loc, 0);
                  end if;

                  Append_To (TSD_Ifaces_List,
                    Make_Aggregate (Loc,
                      Expressions => New_List (

                        --  Iface_Tag

                        Unchecked_Convert_To (RTE (RE_Tag),
                          New_Occurrence_Of
                            (Node (First_Elmt (Access_Disp_Table (Node (AI)))),
                             Loc)),

                        --  Static_Offset_To_Top

                        New_Occurrence_Of (Standard_True, Loc),

                        --  Offset_To_Top_Value

                        Offset_To_Top,

                        --  Offset_To_Top_Func

                        Make_Null (Loc),

                        --  Secondary_DT

                        Unchecked_Convert_To (RTE (RE_Tag), Sec_DT_Tag))));

                  Next_Elmt (AI);
               end loop;

               Name_ITable := New_External_Name (Tname, 'I');
               ITable      := Make_Defining_Identifier (Loc, Name_ITable);
               Set_Is_Statically_Allocated (ITable,
                 Is_Library_Level_Tagged_Type (Typ));

               --  The table of interfaces is constant if we are building a
               --  static dispatch table; otherwise is not constant because
               --  its slots are filled at run time by the IP routine.

               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => ITable,
                   Aliased_Present     => True,
                   Constant_Present    => Building_Static_Secondary_DT (Typ),
                   Object_Definition   =>
                     Make_Subtype_Indication (Loc,
                       Subtype_Mark =>
                         New_Occurrence_Of (RTE (RE_Interface_Data), Loc),
                       Constraint   =>
                         Make_Index_Or_Discriminant_Constraint (Loc,
                           Constraints => New_List (
                             Make_Integer_Literal (Loc, Num_Ifaces)))),

                   Expression           =>
                     Make_Aggregate (Loc,
                       Expressions => New_List (
                         Make_Integer_Literal (Loc, Num_Ifaces),
                         Make_Aggregate (Loc, TSD_Ifaces_List)))));

               Iface_Table_Node :=
                 Make_Attribute_Reference (Loc,
                   Prefix         => New_Occurrence_Of (ITable, Loc),
                   Attribute_Name => Name_Unchecked_Access);
            end;
         end if;

         Append_To (TSD_Aggr_List, Iface_Table_Node);
      end if;

      --  Generate the Select Specific Data table for synchronized types that
      --  implement synchronized interfaces. The size of the table is
      --  constrained by the number of non-predefined primitive operations.

      if RTE_Record_Component_Available (RE_SSD) then
         if Ada_Version >= Ada_2005
           and then Has_DT (Typ)
           and then Is_Concurrent_Record_Type (Typ)
           and then Has_Interfaces (Typ)
           and then Nb_Prim > 0
           and then not Is_Abstract_Type (Typ)
           and then not Is_Controlled (Typ)
           and then not Restriction_Active (No_Dispatching_Calls)
           and then not Restriction_Active (No_Select_Statements)
         then
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => SSD,
                Aliased_Present     => True,
                Object_Definition   =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark => New_Occurrence_Of (
                      RTE (RE_Select_Specific_Data), Loc),
                    Constraint   =>
                      Make_Index_Or_Discriminant_Constraint (Loc,
                        Constraints => New_List (
                          Make_Integer_Literal (Loc, Nb_Prim))))));

            Append_To (Result,
              Make_Attribute_Definition_Clause (Loc,
                Name       => New_Occurrence_Of (SSD, Loc),
                Chars      => Name_Alignment,
                Expression =>
                  Make_Attribute_Reference (Loc,
                    Prefix         =>
                      New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
                    Attribute_Name => Name_Alignment)));

            --  This table is initialized by Make_Select_Specific_Data_Table,
            --  which calls Set_Entry_Index and Set_Prim_Op_Kind.

            Append_To (TSD_Aggr_List,
              Make_Attribute_Reference (Loc,
                Prefix         => New_Occurrence_Of (SSD, Loc),
                Attribute_Name => Name_Unchecked_Access));
         else
            Append_To (TSD_Aggr_List, Make_Null (Loc));
         end if;
      end if;

      --  Initialize the table of ancestor tags. In case of interface types
      --  this table is not needed.

      TSD_Tags_List := New_List;

      --  If we are not statically allocating the dispatch table then we must
      --  fill position 0 with null because we still have not generated the
      --  tag of Typ.

      if not Building_Static_DT (Typ)
        or else Is_Interface (Typ)
      then
         Append_To (TSD_Tags_List,
           Unchecked_Convert_To (RTE (RE_Tag),
             New_Occurrence_Of (RTE (RE_Null_Address), Loc)));

      --  Otherwise we can safely reference the tag

      else
         Append_To (TSD_Tags_List,
           New_Occurrence_Of (DT_Ptr, Loc));
      end if;

      --  Fill the rest of the table with the tags of the ancestors

      declare
         Current_Typ : Entity_Id;
         Parent_Typ  : Entity_Id;
         Pos         : Nat;

      begin
         Pos := 1;
         Current_Typ := Typ;

         loop
            Parent_Typ := Etype (Current_Typ);

            if Is_Private_Type (Parent_Typ) then
               Parent_Typ := Full_View (Base_Type (Parent_Typ));
            end if;

            exit when Parent_Typ = Current_Typ;

            if Is_CPP_Class (Parent_Typ) then

               --  The tags defined in the C++ side will be inherited when
               --  the object is constructed (Exp_Ch3.Build_Init_Procedure)

               Append_To (TSD_Tags_List,
                 Unchecked_Convert_To (RTE (RE_Tag),
                   New_Occurrence_Of (RTE (RE_Null_Address), Loc)));
            else
               Append_To (TSD_Tags_List,
                 New_Occurrence_Of
                   (Node (First_Elmt (Access_Disp_Table (Parent_Typ))),
                    Loc));
            end if;

            Pos := Pos + 1;
            Current_Typ := Parent_Typ;
         end loop;

         pragma Assert (Pos = I_Depth + 1);
      end;

      Append_To (TSD_Aggr_List,
        Make_Aggregate (Loc,
          Expressions => TSD_Tags_List));

      --  Build the TSD object

      Append_To (Result,
        Make_Object_Declaration (Loc,
          Defining_Identifier => TSD,
          Aliased_Present     => True,
          Constant_Present    => Building_Static_DT (Typ),
          Object_Definition   =>
            Make_Subtype_Indication (Loc,
              Subtype_Mark => New_Occurrence_Of (
                RTE (RE_Type_Specific_Data), Loc),
              Constraint =>
                Make_Index_Or_Discriminant_Constraint (Loc,
                  Constraints => New_List (
                    Make_Integer_Literal (Loc, I_Depth)))),

          Expression => Make_Aggregate (Loc,
            Expressions => TSD_Aggr_List)));

      Set_Is_True_Constant (TSD, Building_Static_DT (Typ));

      --  Initialize or declare the dispatch table object

      if not Has_DT (Typ) then
         DT_Constr_List := New_List;
         DT_Aggr_List   := New_List;

         --  Typeinfo

         New_Node :=
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (TSD, Loc),
             Attribute_Name => Name_Address);

         Append_To (DT_Constr_List, New_Node);
         Append_To (DT_Aggr_List,   New_Copy (New_Node));
         Append_To (DT_Aggr_List,   Make_Integer_Literal (Loc, 0));

         --  In case of locally defined tagged types we have already declared
         --  and uninitialized object for the dispatch table, which is now
         --  initialized by means of the following assignment:

         --    DT := (TSD'Address, 0);

         if not Building_Static_DT (Typ) then
            Append_To (Result,
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (DT, Loc),
                Expression => Make_Aggregate (Loc, DT_Aggr_List)));

         --  In case of library level tagged types we declare and export now
         --  the constant object containing the dummy dispatch table. There
         --  is no need to declare the tag here because it has been previously
         --  declared by Make_Tags

         --   DT : aliased constant No_Dispatch_Table :=
         --          (NDT_TSD       => TSD'Address;
         --           NDT_Prims_Ptr => 0);

         else
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT,
                Aliased_Present     => True,
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of (RTE (RE_No_Dispatch_Table_Wrapper), Loc),
                Expression          => Make_Aggregate (Loc, DT_Aggr_List)));

            Export_DT (Typ, DT);
         end if;

      --  Common case: Typ has a dispatch table

      --  Generate:

      --   Predef_Prims : Address_Array (1 .. Default_Prim_Ops_Count) :=
      --                    (predef-prim-op-1'address,
      --                     predef-prim-op-2'address,
      --                     ...
      --                     predef-prim-op-n'address);

      --   DT : Dispatch_Table (Nb_Prims) :=
      --          (Signature => <sig-value>,
      --           Tag_Kind  => <tag_kind-value>,
      --           Predef_Prims => Predef_Prims'First'Address,
      --           Offset_To_Top => 0,
      --           TSD           => TSD'Address;
      --           Prims_Ptr     => (prim-op-1'address,
      --                             prim-op-2'address,
      --                             ...
      --                             prim-op-n'address));
      --   for DT'Alignment use Address'Alignment

      else
         declare
            Nb_P_Prims : constant Nat := Number_Of_Predefined_Prims (Typ);
            Prim_Table : array (Nat range 1 .. Nb_P_Prims) of Entity_Id;
            Decl       : Node_Id;
            E          : Entity_Id;

         begin
            Prim_Ops_Aggr_List := New_List;
            Prim_Table := (others => Empty);

            if Building_Static_DT (Typ) then
               Prim_Elmt  := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  if Is_Predefined_Dispatching_Operation (Prim)
                    and then not Is_Abstract_Subprogram (Prim)
                    and then not Is_Eliminated (Prim)
                    and then not Generate_SCIL
                    and then not Present (Prim_Table
                                           (UI_To_Int (DT_Position (Prim))))
                  then
                     E := Ultimate_Alias (Prim);
                     pragma Assert (not Is_Abstract_Subprogram (E));
                     Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;
            end if;

            for J in Prim_Table'Range loop
               if Present (Prim_Table (J)) then
                  New_Node :=
                    Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                      Make_Attribute_Reference (Loc,
                        Prefix         =>
                          New_Occurrence_Of (Prim_Table (J), Loc),
                        Attribute_Name => Name_Unrestricted_Access));
               else
                  New_Node := Make_Null (Loc);
               end if;

               Append_To (Prim_Ops_Aggr_List, New_Node);
            end loop;

            New_Node :=
              Make_Aggregate (Loc,
                Expressions => Prim_Ops_Aggr_List);

            Decl :=
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => Make_Temporary (Loc, 'S'),
                Subtype_Indication  =>
                  New_Occurrence_Of (RTE (RE_Address_Array), Loc));

            Append_To (Result, Decl);

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => Predef_Prims,
                Aliased_Present     => True,
                Constant_Present    => Building_Static_DT (Typ),
                Object_Definition   =>
                  New_Occurrence_Of (Defining_Identifier (Decl), Loc),
                Expression => New_Node));

            --  Remember aggregates initializing dispatch tables

            Append_Elmt (New_Node, DT_Aggr);
         end;

         --  Stage 1: Initialize the discriminant and the record components

         DT_Constr_List := New_List;
         DT_Aggr_List   := New_List;

         --  Num_Prims. If the tagged type has no primitives we add a dummy
         --  slot whose address will be the tag of this type.

         if Nb_Prim = 0 then
            New_Node := Make_Integer_Literal (Loc, 1);
         else
            New_Node := Make_Integer_Literal (Loc, Nb_Prim);
         end if;

         Append_To (DT_Constr_List, New_Node);
         Append_To (DT_Aggr_List,   New_Copy (New_Node));

         --  Signature

         if RTE_Record_Component_Available (RE_Signature) then
            Append_To (DT_Aggr_List,
              New_Occurrence_Of (RTE (RE_Primary_DT), Loc));
         end if;

         --  Tag_Kind

         if RTE_Record_Component_Available (RE_Tag_Kind) then
            Append_To (DT_Aggr_List, Tagged_Kind (Typ));
         end if;

         --  Predef_Prims

         Append_To (DT_Aggr_List,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (Predef_Prims, Loc),
             Attribute_Name => Name_Address));

         --  Offset_To_Top

         Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));

         --  Typeinfo

         Append_To (DT_Aggr_List,
           Make_Attribute_Reference (Loc,
             Prefix         => New_Occurrence_Of (TSD, Loc),
             Attribute_Name => Name_Address));

         --  Stage 2: Initialize the table of user-defined primitive operations

         Prim_Ops_Aggr_List := New_List;

         if Nb_Prim = 0 then
            Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));

         elsif not Building_Static_DT (Typ) then
            for J in 1 .. Nb_Prim loop
               Append_To (Prim_Ops_Aggr_List, Make_Null (Loc));
            end loop;

         else
            declare
               CPP_Nb_Prims : constant Nat := CPP_Num_Prims (Typ);
               E            : Entity_Id;
               Prim         : Entity_Id;
               Prim_Elmt    : Elmt_Id;
               Prim_Pos     : Nat;
               Prim_Table   : array (Nat range 1 .. Nb_Prim) of Entity_Id;

            begin
               Prim_Table := (others => Empty);

               Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
               while Present (Prim_Elmt) loop
                  Prim := Node (Prim_Elmt);

                  --  Retrieve the ultimate alias of the primitive for proper
                  --  handling of renamings and eliminated primitives.

                  E := Ultimate_Alias (Prim);

                  --  If the alias is not a primitive operation then Prim does
                  --  not rename another primitive, but rather an operation
                  --  declared elsewhere (e.g. in another scope) and therefore
                  --  Prim is a new primitive.

                  if No (Find_Dispatching_Type (E)) then
                     E := Prim;
                  end if;

                  Prim_Pos := UI_To_Int (DT_Position (E));

                  --  Skip predefined primitives because they are located in a
                  --  separate dispatch table.

                  if not Is_Predefined_Dispatching_Operation (Prim)
                    and then not Is_Predefined_Dispatching_Operation (E)

                    --  Skip entities with attribute Interface_Alias because
                    --  those are only required to build secondary dispatch
                    --  tables.

                    and then not Present (Interface_Alias (Prim))

                    --  Skip abstract and eliminated primitives

                    and then not Is_Abstract_Subprogram (E)
                    and then not Is_Eliminated (E)

                    --  For derivations of CPP types skip primitives located in
                    --  the C++ part of the dispatch table because their slots
                    --  are initialized by the IC routine.

                    and then (not Is_CPP_Class (Root_Type (Typ))
                               or else Prim_Pos > CPP_Nb_Prims)

                    --  Skip ignored Ghost subprograms as those will be removed
                    --  from the executable.

                    and then not Is_Ignored_Ghost_Entity (E)
                  then
                     pragma Assert
                       (UI_To_Int (DT_Position (Prim)) <= Nb_Prim);

                     Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
                  end if;

                  Next_Elmt (Prim_Elmt);
               end loop;

               for J in Prim_Table'Range loop
                  if Present (Prim_Table (J)) then
                     New_Node :=
                       Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                         Make_Attribute_Reference (Loc,
                           Prefix         =>
                             New_Occurrence_Of (Prim_Table (J), Loc),
                           Attribute_Name => Name_Unrestricted_Access));
                  else
                     New_Node := Make_Null (Loc);
                  end if;

                  Append_To (Prim_Ops_Aggr_List, New_Node);
               end loop;
            end;
         end if;

         New_Node :=
           Make_Aggregate (Loc,
             Expressions => Prim_Ops_Aggr_List);

         Append_To (DT_Aggr_List, New_Node);

         --  Remember aggregates initializing dispatch tables

         Append_Elmt (New_Node, DT_Aggr);

         --  In case of locally defined tagged types we have already declared
         --  and uninitialized object for the dispatch table, which is now
         --  initialized by means of an assignment.

         if not Building_Static_DT (Typ) then
            Append_To (Result,
              Make_Assignment_Statement (Loc,
                Name       => New_Occurrence_Of (DT, Loc),
                Expression => Make_Aggregate (Loc, DT_Aggr_List)));

         --  In case of library level tagged types we declare now and export
         --  the constant object containing the dispatch table.

         else
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT,
                Aliased_Present     => True,
                Constant_Present    => True,
                Object_Definition   =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark => New_Occurrence_Of
                                      (RTE (RE_Dispatch_Table_Wrapper), Loc),
                    Constraint   => Make_Index_Or_Discriminant_Constraint (Loc,
                                      Constraints => DT_Constr_List)),
                Expression          => Make_Aggregate (Loc, DT_Aggr_List)));

            Export_DT (Typ, DT);
         end if;
      end if;

      --  Initialize the table of ancestor tags if not building static
      --  dispatch table

      if not Building_Static_DT (Typ)
        and then not Is_Interface (Typ)
        and then not Is_CPP_Class (Typ)
      then
         Append_To (Result,
           Make_Assignment_Statement (Loc,
             Name       =>
               Make_Indexed_Component (Loc,
                 Prefix      =>
                   Make_Selected_Component (Loc,
                     Prefix        => New_Occurrence_Of (TSD, Loc),
                     Selector_Name =>
                       New_Occurrence_Of
                         (RTE_Record_Component (RE_Tags_Table), Loc)),
                 Expressions =>
                    New_List (Make_Integer_Literal (Loc, 0))),

             Expression =>
               New_Occurrence_Of
                 (Node (First_Elmt (Access_Disp_Table (Typ))), Loc)));
      end if;

      --  Inherit the dispatch tables of the parent. There is no need to
      --  inherit anything from the parent when building static dispatch tables
      --  because the whole dispatch table (including inherited primitives) has
      --  been already built.

      if Building_Static_DT (Typ) then
         null;

      --  If the ancestor is a CPP_Class type we inherit the dispatch tables
      --  in the init proc, and we don't need to fill them in here.

      elsif Is_CPP_Class (Parent_Typ) then
         null;

      --  Otherwise we fill in the dispatch tables here

      else
         if Typ /= Parent_Typ
           and then not Is_Interface (Typ)
           and then not Restriction_Active (No_Dispatching_Calls)
         then
            --  Inherit the dispatch table

            if not Is_Interface (Typ)
              and then not Is_Interface (Parent_Typ)
              and then not Is_CPP_Class (Parent_Typ)
            then
               declare
                  Nb_Prims : constant Int :=
                               UI_To_Int (DT_Entry_Count
                                 (First_Tag_Component (Parent_Typ)));

               begin
                  Append_To (Elab_Code,
                    Build_Inherit_Predefined_Prims (Loc,
                      Old_Tag_Node =>
                        New_Occurrence_Of
                          (Node
                            (Next_Elmt
                              (First_Elmt
                                (Access_Disp_Table (Parent_Typ)))), Loc),
                      New_Tag_Node =>
                        New_Occurrence_Of
                          (Node
                            (Next_Elmt
                              (First_Elmt
                                (Access_Disp_Table (Typ)))), Loc),
                      Num_Predef_Prims =>
                        Number_Of_Predefined_Prims (Parent_Typ)));

                  if Nb_Prims /= 0 then
                     Append_To (Elab_Code,
                       Build_Inherit_Prims (Loc,
                         Typ          => Typ,
                         Old_Tag_Node =>
                           New_Occurrence_Of
                             (Node
                               (First_Elmt
                                 (Access_Disp_Table (Parent_Typ))), Loc),
                         New_Tag_Node => New_Occurrence_Of (DT_Ptr, Loc),
                         Num_Prims    => Nb_Prims));
                  end if;
               end;
            end if;

            --  Inherit the secondary dispatch tables of the ancestor

            if not Is_CPP_Class (Parent_Typ) then
               declare
                  Sec_DT_Ancestor : Elmt_Id :=
                                      Next_Elmt
                                        (Next_Elmt
                                           (First_Elmt
                                              (Access_Disp_Table
                                                 (Parent_Typ))));
                  Sec_DT_Typ      : Elmt_Id :=
                                      Next_Elmt
                                        (Next_Elmt
                                           (First_Elmt
                                              (Access_Disp_Table (Typ))));

                  procedure Copy_Secondary_DTs (Typ : Entity_Id);
                  --  Local procedure required to climb through the ancestors
                  --  and copy the contents of all their secondary dispatch
                  --  tables.

                  ------------------------
                  -- Copy_Secondary_DTs --
                  ------------------------

                  procedure Copy_Secondary_DTs (Typ : Entity_Id) is
                     E     : Entity_Id;
                     Iface : Elmt_Id;

                  begin
                     --  Climb to the ancestor (if any) handling private types

                     if Present (Full_View (Etype (Typ))) then
                        if Full_View (Etype (Typ)) /= Typ then
                           Copy_Secondary_DTs (Full_View (Etype (Typ)));
                        end if;

                     elsif Etype (Typ) /= Typ then
                        Copy_Secondary_DTs (Etype (Typ));
                     end if;

                     if Present (Interfaces (Typ))
                       and then not Is_Empty_Elmt_List (Interfaces (Typ))
                     then
                        Iface := First_Elmt (Interfaces (Typ));
                        E     := First_Entity (Typ);
                        while Present (E)
                          and then Present (Node (Sec_DT_Ancestor))
                          and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
                        loop
                           if Is_Tag (E) and then Chars (E) /= Name_uTag then
                              declare
                                 Num_Prims : constant Int :=
                                               UI_To_Int (DT_Entry_Count (E));

                              begin
                                 if not Is_Interface (Etype (Typ)) then

                                    --  Inherit first secondary dispatch table

                                    Append_To (Elab_Code,
                                      Build_Inherit_Predefined_Prims (Loc,
                                        Old_Tag_Node =>
                                          Unchecked_Convert_To (RTE (RE_Tag),
                                            New_Occurrence_Of
                                              (Node
                                                (Next_Elmt (Sec_DT_Ancestor)),
                                               Loc)),
                                        New_Tag_Node =>
                                          Unchecked_Convert_To (RTE (RE_Tag),
                                            New_Occurrence_Of
                                              (Node (Next_Elmt (Sec_DT_Typ)),
                                               Loc)),
                                        Num_Predef_Prims =>
                                          Number_Of_Predefined_Prims
                                            (Parent_Typ)));

                                    if Num_Prims /= 0 then
                                       Append_To (Elab_Code,
                                         Build_Inherit_Prims (Loc,
                                           Typ          => Node (Iface),
                                           Old_Tag_Node =>
                                             Unchecked_Convert_To
                                               (RTE (RE_Tag),
                                                New_Occurrence_Of
                                                  (Node (Sec_DT_Ancestor),
                                                   Loc)),
                                           New_Tag_Node =>
                                             Unchecked_Convert_To
                                              (RTE (RE_Tag),
                                               New_Occurrence_Of
                                                 (Node (Sec_DT_Typ), Loc)),
                                           Num_Prims    => Num_Prims));
                                    end if;
                                 end if;

                                 Next_Elmt (Sec_DT_Ancestor);
                                 Next_Elmt (Sec_DT_Typ);

                                 --  Skip the secondary dispatch table of
                                 --  predefined primitives

                                 Next_Elmt (Sec_DT_Ancestor);
                                 Next_Elmt (Sec_DT_Typ);

                                 if not Is_Interface (Etype (Typ)) then

                                    --  Inherit second secondary dispatch table

                                    Append_To (Elab_Code,
                                      Build_Inherit_Predefined_Prims (Loc,
                                        Old_Tag_Node =>
                                          Unchecked_Convert_To (RTE (RE_Tag),
                                             New_Occurrence_Of
                                               (Node
                                                 (Next_Elmt (Sec_DT_Ancestor)),
                                                Loc)),
                                        New_Tag_Node =>
                                          Unchecked_Convert_To (RTE (RE_Tag),
                                            New_Occurrence_Of
                                              (Node (Next_Elmt (Sec_DT_Typ)),
                                               Loc)),
                                        Num_Predef_Prims =>
                                          Number_Of_Predefined_Prims
                                            (Parent_Typ)));

                                    if Num_Prims /= 0 then
                                       Append_To (Elab_Code,
                                         Build_Inherit_Prims (Loc,
                                           Typ          => Node (Iface),
                                           Old_Tag_Node =>
                                             Unchecked_Convert_To
                                               (RTE (RE_Tag),
                                                New_Occurrence_Of
                                                  (Node (Sec_DT_Ancestor),
                                                   Loc)),
                                           New_Tag_Node =>
                                             Unchecked_Convert_To
                                              (RTE (RE_Tag),
                                               New_Occurrence_Of
                                                 (Node (Sec_DT_Typ), Loc)),
                                           Num_Prims    => Num_Prims));
                                    end if;
                                 end if;
                              end;

                              Next_Elmt (Sec_DT_Ancestor);
                              Next_Elmt (Sec_DT_Typ);

                              --  Skip the secondary dispatch table of
                              --  predefined primitives

                              Next_Elmt (Sec_DT_Ancestor);
                              Next_Elmt (Sec_DT_Typ);

                              Next_Elmt (Iface);
                           end if;

                           Next_Entity (E);
                        end loop;
                     end if;
                  end Copy_Secondary_DTs;

               begin
                  if Present (Node (Sec_DT_Ancestor))
                    and then Ekind (Node (Sec_DT_Ancestor)) = E_Constant
                  then
                     --  Handle private types

                     if Present (Full_View (Typ)) then
                        Copy_Secondary_DTs (Full_View (Typ));
                     else
                        Copy_Secondary_DTs (Typ);
                     end if;
                  end if;
               end;
            end if;
         end if;
      end if;

      --  Generate code to check if the external tag of this type is the same
      --  as the external tag of some other declaration.

      --     Check_TSD (TSD'Unrestricted_Access);

      --  This check is a consequence of AI05-0113-1/06, so it officially
      --  applies to Ada 2005 (and Ada 2012). It might be argued that it is
      --  a desirable check to add in Ada 95 mode, but we hesitate to make
      --  this change, as it would be incompatible, and could conceivably
      --  cause a problem in existing Ada 95 code.

      --  We check for No_Run_Time_Mode here, because we do not want to pick
      --  up the RE_Check_TSD entity and call it in No_Run_Time mode.

      --  We cannot perform this check if the generation of its expanded name
      --  was discarded.

      if not No_Run_Time_Mode
        and then not Discard_Names
        and then Ada_Version >= Ada_2005
        and then RTE_Available (RE_Check_TSD)
        and then not Duplicated_Tag_Checks_Suppressed (Typ)
      then
         Append_To (Elab_Code,
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Check_TSD), Loc),
             Parameter_Associations => New_List (
               Make_Attribute_Reference (Loc,
                 Prefix         => New_Occurrence_Of (TSD, Loc),
                 Attribute_Name => Name_Unchecked_Access))));
      end if;

      --  Generate code to register the Tag in the External_Tag hash table for
      --  the pure Ada type only.

      --        Register_Tag (Dt_Ptr);

      --  Skip this action in the following cases:
      --    1) if Register_Tag is not available.
      --    2) in No_Run_Time mode.
      --    3) if Typ is not defined at the library level (this is required
      --       to avoid adding concurrency control to the hash table used
      --       by the run-time to register the tags).

      if not No_Run_Time_Mode
        and then Is_Library_Level_Entity (Typ)
        and then RTE_Available (RE_Register_Tag)
      then
         Append_To (Elab_Code,
           Make_Procedure_Call_Statement (Loc,
             Name                   =>
               New_Occurrence_Of (RTE (RE_Register_Tag), Loc),
             Parameter_Associations =>
               New_List (New_Occurrence_Of (DT_Ptr, Loc))));
      end if;

      if not Is_Empty_List (Elab_Code) then
         Append_List_To (Result, Elab_Code);
      end if;

      --  Populate the two auxiliary tables used for dispatching asynchronous,
      --  conditional and timed selects for synchronized types that implement
      --  a limited interface. Skip this step in Ravenscar profile or when
      --  general dispatching is forbidden.

      if Ada_Version >= Ada_2005
        and then Is_Concurrent_Record_Type (Typ)
        and then Has_Interfaces (Typ)
        and then not Restriction_Active (No_Dispatching_Calls)
        and then not Restriction_Active (No_Select_Statements)
      then
         Append_List_To (Result,
           Make_Select_Specific_Data_Table (Typ));
      end if;

      --  Remember entities containing dispatch tables

      Append_Elmt (Predef_Prims, DT_Decl);
      Append_Elmt (DT, DT_Decl);

      Analyze_List (Result, Suppress => All_Checks);

      --  Mark entities containing dispatch tables. Required by the backend to
      --  handle them properly.

      if Has_DT (Typ) then
         declare
            Elmt : Elmt_Id;

         begin
            --  Object declarations

            Elmt := First_Elmt (DT_Decl);
            while Present (Elmt) loop
               Set_Is_Dispatch_Table_Entity (Node (Elmt));
               pragma Assert (Ekind (Etype (Node (Elmt))) = E_Array_Subtype
                 or else Ekind (Etype (Node (Elmt))) = E_Record_Subtype);
               Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
               Next_Elmt (Elmt);
            end loop;

            --  Aggregates initializing dispatch tables

            Elmt := First_Elmt (DT_Aggr);
            while Present (Elmt) loop
               Set_Is_Dispatch_Table_Entity (Etype (Node (Elmt)));
               Next_Elmt (Elmt);
            end loop;
         end;
      end if;

   <<Leave_SCIL>>

      Set_Has_Dispatch_Table (Typ);

      --  Register the tagged type in the call graph nodes table

      Register_CG_Node (Typ);

   <<Leave>>
      Restore_Ghost_Region (Saved_GM, Saved_IGR);

      return Result;
   end Make_DT;

   -------------------------------------
   -- Make_Select_Specific_Data_Table --
   -------------------------------------

   function Make_Select_Specific_Data_Table
     (Typ : Entity_Id) return List_Id
   is
      Assignments : constant List_Id    := New_List;
      Loc         : constant Source_Ptr := Sloc (Typ);

      Conc_Typ  : Entity_Id;
      Decls     : List_Id := No_List;
      Prim      : Entity_Id;
      Prim_Als  : Entity_Id;
      Prim_Elmt : Elmt_Id;
      Prim_Pos  : Uint;
      Nb_Prim   : Nat := 0;

      type Examined_Array is array (Int range <>) of Boolean;

      function Find_Entry_Index (E : Entity_Id) return Uint;
      --  Given an entry, find its index in the visible declarations of the
      --  corresponding concurrent type of Typ.

      ----------------------
      -- Find_Entry_Index --
      ----------------------

      function Find_Entry_Index (E : Entity_Id) return Uint is
         Index     : Uint := Uint_0;
         Subp_Decl : Node_Id;

      begin
         Subp_Decl := First (Decls);
         while Present (Subp_Decl) loop
            if Nkind (Subp_Decl) = N_Entry_Declaration then
               Index := Index + 1;

               if Defining_Identifier (Subp_Decl) = E then
                  exit;
               end if;

            end if;

            Next (Subp_Decl);
         end loop;

         return Index;
      end Find_Entry_Index;

      --  Local variables

      Tag_Node : Node_Id;

   --  Start of processing for Make_Select_Specific_Data_Table

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      if Present (Corresponding_Concurrent_Type (Typ)) then
         Conc_Typ := Corresponding_Concurrent_Type (Typ);

         if Present (Full_View (Conc_Typ)) then
            Conc_Typ := Full_View (Conc_Typ);
         end if;

         if Ekind (Conc_Typ) = E_Protected_Type then
            Decls := Visible_Declarations (Protected_Definition (
                       Parent (Conc_Typ)));
         else
            pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
            Decls := Visible_Declarations (Task_Definition (
                       Parent (Conc_Typ)));
         end if;
      end if;

      --  Count the non-predefined primitive operations

      Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
      while Present (Prim_Elmt) loop
         Prim := Node (Prim_Elmt);

         if not (Is_Predefined_Dispatching_Operation (Prim)
                   or else Is_Predefined_Dispatching_Alias (Prim))
         then
            Nb_Prim := Nb_Prim + 1;
         end if;

         Next_Elmt (Prim_Elmt);
      end loop;

      declare
         Examined : Examined_Array (1 .. Nb_Prim) := (others => False);

      begin
         Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
         while Present (Prim_Elmt) loop
            Prim := Node (Prim_Elmt);

            --  Look for primitive overriding an abstract interface subprogram

            if Present (Interface_Alias (Prim))
              and then not
                Is_Ancestor
                  (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
                   Use_Full_View => True)
              and then not Examined (UI_To_Int (DT_Position (Alias (Prim))))
            then
               Prim_Pos := DT_Position (Alias (Prim));
               pragma Assert (UI_To_Int (Prim_Pos) <= Nb_Prim);
               Examined (UI_To_Int (Prim_Pos)) := True;

               --  Set the primitive operation kind regardless of subprogram
               --  type. Generate:
               --    Ada.Tags.Set_Prim_Op_Kind (DT_Ptr, <position>, <kind>);

               if Tagged_Type_Expansion then
                  Tag_Node :=
                    New_Occurrence_Of
                     (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);

               else
                  Tag_Node :=
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Typ, Loc),
                      Attribute_Name => Name_Tag);
               end if;

               Append_To (Assignments,
                 Make_Procedure_Call_Statement (Loc,
                   Name => New_Occurrence_Of (RTE (RE_Set_Prim_Op_Kind), Loc),
                   Parameter_Associations => New_List (
                     Tag_Node,
                     Make_Integer_Literal (Loc, Prim_Pos),
                     Prim_Op_Kind (Alias (Prim), Typ))));

               --  Retrieve the root of the alias chain

               Prim_Als := Ultimate_Alias (Prim);

               --  In the case of an entry wrapper, set the entry index

               if Ekind (Prim) = E_Procedure
                 and then Is_Primitive_Wrapper (Prim_Als)
                 and then Ekind (Wrapped_Entity (Prim_Als)) = E_Entry
               then
                  --  Generate:
                  --    Ada.Tags.Set_Entry_Index
                  --      (DT_Ptr, <position>, <index>);

                  if Tagged_Type_Expansion then
                     Tag_Node :=
                       New_Occurrence_Of
                         (Node (First_Elmt (Access_Disp_Table (Typ))), Loc);
                  else
                     Tag_Node :=
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Typ, Loc),
                         Attribute_Name => Name_Tag);
                  end if;

                  Append_To (Assignments,
                    Make_Procedure_Call_Statement (Loc,
                      Name =>
                        New_Occurrence_Of (RTE (RE_Set_Entry_Index), Loc),
                      Parameter_Associations => New_List (
                        Tag_Node,
                        Make_Integer_Literal (Loc, Prim_Pos),
                        Make_Integer_Literal (Loc,
                          Find_Entry_Index (Wrapped_Entity (Prim_Als))))));
               end if;
            end if;

            Next_Elmt (Prim_Elmt);
         end loop;
      end;

      return Assignments;
   end Make_Select_Specific_Data_Table;

   ---------------
   -- Make_Tags --
   ---------------

   function Make_Tags (Typ : Entity_Id) return List_Id is
      Loc    : constant Source_Ptr := Sloc (Typ);
      Result : constant List_Id    := New_List;

      procedure Import_DT
        (Tag_Typ         : Entity_Id;
         DT              : Entity_Id;
         Is_Secondary_DT : Boolean);
      --  Import the dispatch table DT of tagged type Tag_Typ. Required to
      --  generate forward references and statically allocate the table. For
      --  primary dispatch tables that require no dispatch table generate:

      --     DT : static aliased constant Non_Dispatch_Table_Wrapper;
      --     pragma Import (Ada, DT);

      --  Otherwise generate:

      --     DT : static aliased constant Dispatch_Table_Wrapper (Nb_Prim);
      --     pragma Import (Ada, DT);

      ---------------
      -- Import_DT --
      ---------------

      procedure Import_DT
        (Tag_Typ         : Entity_Id;
         DT              : Entity_Id;
         Is_Secondary_DT : Boolean)
      is
         DT_Constr_List : List_Id;
         Nb_Prim        : Nat;

      begin
         Set_Is_Imported  (DT);
         Mutate_Ekind     (DT, E_Constant);
         Set_Related_Type (DT, Typ);

         --  The scope must be set now to call Get_External_Name

         Set_Scope (DT, Current_Scope);

         Get_External_Name (DT);
         Set_Interface_Name (DT,
           Make_String_Literal (Loc, Strval => String_From_Name_Buffer));

         --  Ensure proper Sprint output of this implicit importation

         Set_Is_Internal (DT);

         --  Save this entity to allow Make_DT to generate its exportation

         Append_Elmt (DT, Dispatch_Table_Wrappers (Typ));

         --  No dispatch table required

         if not Is_Secondary_DT and then not Has_DT (Tag_Typ) then
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT,
                Aliased_Present     => True,
                Constant_Present    => True,
                Object_Definition   =>
                  New_Occurrence_Of
                    (RTE (RE_No_Dispatch_Table_Wrapper), Loc)));

         else
            --  Calculate the number of primitives of the dispatch table and
            --  the size of the Type_Specific_Data record.

            Nb_Prim :=
              UI_To_Int (DT_Entry_Count (First_Tag_Component (Tag_Typ)));

            --  If the tagged type has no primitives we add a dummy slot whose
            --  address will be the tag of this type.

            if Nb_Prim = 0 then
               DT_Constr_List :=
                 New_List (Make_Integer_Literal (Loc, 1));
            else
               DT_Constr_List :=
                 New_List (Make_Integer_Literal (Loc, Nb_Prim));
            end if;

            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT,
                Aliased_Present     => True,
                Constant_Present    => True,
                Object_Definition   =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (RTE (RE_Dispatch_Table_Wrapper), Loc),
                    Constraint => Make_Index_Or_Discriminant_Constraint (Loc,
                                    Constraints => DT_Constr_List))));
         end if;
      end Import_DT;

      --  Local variables

      Tname            : constant Name_Id := Chars (Typ);
      AI_Tag_Comp      : Elmt_Id;
      DT               : Node_Id := Empty;
      DT_Ptr           : Node_Id;
      Predef_Prims_Ptr : Node_Id;
      Iface_DT         : Node_Id := Empty;
      Iface_DT_Ptr     : Node_Id;
      New_Node         : Node_Id;
      Suffix_Index     : Int;
      Typ_Name         : Name_Id;
      Typ_Comps        : Elist_Id;

   --  Start of processing for Make_Tags

   begin
      pragma Assert (No (Access_Disp_Table (Typ)));
      Set_Access_Disp_Table (Typ, New_Elmt_List);

      --  If the elaboration of this tagged type needs a boolean flag then
      --  define now its entity. It is initialized to True to indicate that
      --  elaboration is still pending; set to False by the IP routine.

      --      TypFxx : boolean := True;

      if Elab_Flag_Needed (Typ) then
         Set_Access_Disp_Table_Elab_Flag (Typ,
           Make_Defining_Identifier (Loc,
             Chars => New_External_Name (Tname, 'F')));

         Append_To (Result,
           Make_Object_Declaration (Loc,
             Defining_Identifier => Access_Disp_Table_Elab_Flag (Typ),
             Object_Definition   => New_Occurrence_Of (Standard_Boolean, Loc),
             Expression          => New_Occurrence_Of (Standard_True, Loc)));
      end if;

      --  1) Generate the primary tag entities

      --  Primary dispatch table containing user-defined primitives

      DT_Ptr := Make_Defining_Identifier (Loc, New_External_Name (Tname, 'P'));
      Set_Etype   (DT_Ptr, RTE (RE_Tag));
      Append_Elmt (DT_Ptr, Access_Disp_Table (Typ));

      --  Minimum decoration

      Mutate_Ekind     (DT_Ptr, E_Variable);
      Set_Related_Type (DT_Ptr, Typ);

      --  Notify back end that the types are associated with a dispatch table

      Set_Is_Dispatch_Table_Entity (RTE (RE_Prim_Ptr));
      Set_Is_Dispatch_Table_Entity (RTE (RE_Predef_Prims_Table_Ptr));

      --  For CPP types there is no need to build the dispatch tables since
      --  they are imported from the C++ side. If the CPP type has an IP then
      --  we declare now the variable that will store the copy of the C++ tag.
      --  If the CPP type is an interface, we need the variable as well because
      --  it becomes the pointer to the corresponding secondary table.

      if Is_CPP_Class (Typ) then
         if Has_CPP_Constructors (Typ) or else Is_Interface (Typ) then
            Append_To (Result,
              Make_Object_Declaration (Loc,
                Defining_Identifier => DT_Ptr,
                Object_Definition   => New_Occurrence_Of (RTE (RE_Tag), Loc),
                Expression =>
                  Unchecked_Convert_To (RTE (RE_Tag),
                    New_Occurrence_Of (RTE (RE_Null_Address), Loc))));

            Set_Is_Statically_Allocated (DT_Ptr,
              Is_Library_Level_Tagged_Type (Typ));
         end if;

      --  Ada types

      else
         --  Primary dispatch table containing predefined primitives

         Predef_Prims_Ptr :=
           Make_Defining_Identifier (Loc,
             Chars => New_External_Name (Tname, 'Y'));
         Set_Etype   (Predef_Prims_Ptr, RTE (RE_Address));
         Append_Elmt (Predef_Prims_Ptr, Access_Disp_Table (Typ));

         --  Import the forward declaration of the Dispatch Table wrapper
         --  record (Make_DT will take care of exporting it).

         if Building_Static_DT (Typ) then
            Set_Dispatch_Table_Wrappers (Typ, New_Elmt_List);

            DT :=
              Make_Defining_Identifier (Loc,
                Chars => New_External_Name (Tname, 'T'));

            Import_DT (Typ, DT, Is_Secondary_DT => False);

            if Has_DT (Typ) then
               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => DT_Ptr,
                   Constant_Present    => True,
                   Object_Definition   =>
                     New_Occurrence_Of (RTE (RE_Tag), Loc),
                   Expression          =>
                     Unchecked_Convert_To (RTE (RE_Tag),
                       Make_Attribute_Reference (Loc,
                         Prefix         =>
                           Make_Selected_Component (Loc,
                             Prefix        => New_Occurrence_Of (DT, Loc),
                             Selector_Name =>
                               New_Occurrence_Of
                                 (RTE_Record_Component (RE_Prims_Ptr), Loc)),
                         Attribute_Name => Name_Address))));

               --  Generate the SCIL node for the previous object declaration
               --  because it has a tag initialization.

               if Generate_SCIL then
                  New_Node :=
                    Make_SCIL_Dispatch_Table_Tag_Init (Sloc (Last (Result)));
                  Set_SCIL_Entity (New_Node, Typ);
                  Set_SCIL_Node (Last (Result), New_Node);
               end if;

               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Predef_Prims_Ptr,
                   Constant_Present    => True,
                   Object_Definition   =>
                     New_Occurrence_Of (RTE (RE_Address), Loc),
                   Expression          =>
                     Make_Attribute_Reference (Loc,
                       Prefix         =>
                         Make_Selected_Component (Loc,
                           Prefix        => New_Occurrence_Of (DT, Loc),
                           Selector_Name =>
                             New_Occurrence_Of
                               (RTE_Record_Component (RE_Predef_Prims), Loc)),
                       Attribute_Name => Name_Address)));

            --  No dispatch table required

            else
               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => DT_Ptr,
                   Constant_Present    => True,
                   Object_Definition   =>
                     New_Occurrence_Of (RTE (RE_Tag), Loc),
                   Expression          =>
                     Unchecked_Convert_To (RTE (RE_Tag),
                       Make_Attribute_Reference (Loc,
                         Prefix         =>
                           Make_Selected_Component (Loc,
                             Prefix => New_Occurrence_Of (DT, Loc),
                             Selector_Name =>
                               New_Occurrence_Of
                                 (RTE_Record_Component (RE_NDT_Prims_Ptr),
                                  Loc)),
                         Attribute_Name => Name_Address))));
            end if;

            Set_Is_True_Constant (DT_Ptr);
            Set_Is_Statically_Allocated (DT_Ptr);
         end if;
      end if;

      --  2) Generate the secondary tag entities

      --  Collect the components associated with secondary dispatch tables

      if Has_Interfaces (Typ) then
         Collect_Interface_Components (Typ, Typ_Comps);

         --  For each interface type we build a unique external name associated
         --  with its secondary dispatch table. This name is used to declare an
         --  object that references this secondary dispatch table, whose value
         --  will be used for the elaboration of Typ objects, and also for the
         --  elaboration of objects of types derived from Typ that do not
         --  override the primitives of this interface type.

         Suffix_Index := 1;

         --  Note: The value of Suffix_Index must be in sync with the values of
         --  Suffix_Index in secondary dispatch tables generated by Make_DT.

         if Is_CPP_Class (Typ) then
            AI_Tag_Comp := First_Elmt (Typ_Comps);
            while Present (AI_Tag_Comp) loop
               Get_Secondary_DT_External_Name
                 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
               Typ_Name := Name_Find;

               --  Declare variables to store copy of the C++ secondary tags

               Iface_DT_Ptr :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Typ_Name, 'P'));
               Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
               Mutate_Ekind (Iface_DT_Ptr, E_Variable);
               Set_Is_Tag (Iface_DT_Ptr);

               Set_Has_Thunks (Iface_DT_Ptr);
               Set_Related_Type
                 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
               Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));

               Append_To (Result,
                 Make_Object_Declaration (Loc,
                   Defining_Identifier => Iface_DT_Ptr,
                   Object_Definition   => New_Occurrence_Of
                                            (RTE (RE_Interface_Tag), Loc),
                   Expression =>
                     Unchecked_Convert_To (RTE (RE_Interface_Tag),
                       New_Occurrence_Of (RTE (RE_Null_Address), Loc))));

               Set_Is_Statically_Allocated (Iface_DT_Ptr,
                 Is_Library_Level_Tagged_Type (Typ));

               Next_Elmt (AI_Tag_Comp);
            end loop;

         --  This is not a CPP_Class type

         else
            AI_Tag_Comp := First_Elmt (Typ_Comps);
            while Present (AI_Tag_Comp) loop
               Get_Secondary_DT_External_Name
                 (Typ, Related_Type (Node (AI_Tag_Comp)), Suffix_Index);
               Typ_Name := Name_Find;

               if Building_Static_DT (Typ) then
                  Iface_DT :=
                    Make_Defining_Identifier (Loc,
                      Chars => New_External_Name (Typ_Name, 'T'));
                  Import_DT
                    (Tag_Typ => Related_Type (Node (AI_Tag_Comp)),
                     DT      => Iface_DT,
                     Is_Secondary_DT => True);
               end if;

               --  Secondary dispatch table referencing thunks to user-defined
               --  primitives covered by this interface.

               Iface_DT_Ptr :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Typ_Name, 'P'));
               Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
               Mutate_Ekind (Iface_DT_Ptr, E_Constant);
               Set_Is_Tag (Iface_DT_Ptr);
               Set_Has_Thunks (Iface_DT_Ptr);
               Set_Is_Statically_Allocated (Iface_DT_Ptr,
                 Is_Library_Level_Tagged_Type (Typ));
               Set_Is_True_Constant (Iface_DT_Ptr);
               Set_Related_Type
                 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
               Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));

               if Building_Static_DT (Typ) then
                  Append_To (Result,
                    Make_Object_Declaration (Loc,
                      Defining_Identifier => Iface_DT_Ptr,
                      Constant_Present    => True,
                      Object_Definition   => New_Occurrence_Of
                                               (RTE (RE_Interface_Tag), Loc),
                      Expression          =>
                        Unchecked_Convert_To (RTE (RE_Interface_Tag),
                          Make_Attribute_Reference (Loc,
                            Prefix         =>
                              Make_Selected_Component (Loc,
                                Prefix        =>
                                  New_Occurrence_Of (Iface_DT, Loc),
                                Selector_Name =>
                                  New_Occurrence_Of
                                    (RTE_Record_Component (RE_Prims_Ptr),
                                     Loc)),
                            Attribute_Name => Name_Address))));
               end if;

               --  Secondary dispatch table referencing thunks to predefined
               --  primitives.

               Iface_DT_Ptr :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Typ_Name, 'Y'));
               Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
               Mutate_Ekind (Iface_DT_Ptr, E_Constant);
               Set_Is_Tag (Iface_DT_Ptr);
               Set_Has_Thunks (Iface_DT_Ptr);
               Set_Is_Statically_Allocated (Iface_DT_Ptr,
                 Is_Library_Level_Tagged_Type (Typ));
               Set_Is_True_Constant (Iface_DT_Ptr);
               Set_Related_Type
                 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
               Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));

               --  Secondary dispatch table referencing user-defined primitives
               --  covered by this interface.

               Iface_DT_Ptr :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Typ_Name, 'D'));
               Set_Etype (Iface_DT_Ptr, RTE (RE_Interface_Tag));
               Mutate_Ekind (Iface_DT_Ptr, E_Constant);
               Set_Is_Tag (Iface_DT_Ptr);
               Set_Is_Statically_Allocated (Iface_DT_Ptr,
                 Is_Library_Level_Tagged_Type (Typ));
               Set_Is_True_Constant (Iface_DT_Ptr);
               Set_Related_Type
                 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
               Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));

               --  Secondary dispatch table referencing predefined primitives

               Iface_DT_Ptr :=
                 Make_Defining_Identifier (Loc,
                   Chars => New_External_Name (Typ_Name, 'Z'));
               Set_Etype (Iface_DT_Ptr, RTE (RE_Address));
               Mutate_Ekind (Iface_DT_Ptr, E_Constant);
               Set_Is_Tag (Iface_DT_Ptr);
               Set_Is_Statically_Allocated (Iface_DT_Ptr,
                 Is_Library_Level_Tagged_Type (Typ));
               Set_Is_True_Constant (Iface_DT_Ptr);
               Set_Related_Type
                 (Iface_DT_Ptr, Related_Type (Node (AI_Tag_Comp)));
               Append_Elmt (Iface_DT_Ptr, Access_Disp_Table (Typ));

               Next_Elmt (AI_Tag_Comp);
            end loop;
         end if;
      end if;

      --  3) At the end of Access_Disp_Table, if the type has user-defined
      --     primitives, we add the entity of an access type declaration that
      --     is used by Build_Get_Prim_Op_Address to expand dispatching calls
      --     through the primary dispatch table.

      if DT_Entry_Count (First_Tag_Component (Typ)) = 0 then
         Analyze_List (Result);

      --     Generate:
      --       subtype Typ_DT is Address_Array (1 .. Nb_Prims);
      --       type Typ_DT_Acc is access Typ_DT;

      else
         declare
            Name_DT_Prims     : constant Name_Id :=
                                  New_External_Name (Tname, 'G');
            Name_DT_Prims_Acc : constant Name_Id :=
                                  New_External_Name (Tname, 'H');
            DT_Prims          : constant Entity_Id :=
                                  Make_Defining_Identifier (Loc,
                                    Name_DT_Prims);
            DT_Prims_Acc      : constant Entity_Id :=
                                  Make_Defining_Identifier (Loc,
                                    Name_DT_Prims_Acc);
         begin
            Append_To (Result,
              Make_Subtype_Declaration (Loc,
                Defining_Identifier => DT_Prims,
                Subtype_Indication  =>
                  Make_Subtype_Indication (Loc,
                    Subtype_Mark =>
                      New_Occurrence_Of (RTE (RE_Address_Array), Loc),
                    Constraint   =>
                      Make_Index_Or_Discriminant_Constraint (Loc, New_List (
                        Make_Range (Loc,
                          Low_Bound  => Make_Integer_Literal (Loc, 1),
                          High_Bound =>
                            Make_Integer_Literal (Loc,
                              DT_Entry_Count
                                (First_Tag_Component (Typ)))))))));

            Append_To (Result,
              Make_Full_Type_Declaration (Loc,
                Defining_Identifier => DT_Prims_Acc,
                Type_Definition     =>
                   Make_Access_To_Object_Definition (Loc,
                     Subtype_Indication =>
                       New_Occurrence_Of (DT_Prims, Loc))));

            Append_Elmt (DT_Prims_Acc, Access_Disp_Table (Typ));

            --  Analyze the resulting list and suppress the generation of the
            --  Init_Proc associated with the above array declaration because
            --  this type is never used in object declarations. It is only used
            --  to simplify the expansion associated with dispatching calls.

            Analyze_List (Result);
            Set_Suppress_Initialization (Base_Type (DT_Prims));

            --  Disable backend optimizations based on assumptions about the
            --  aliasing status of objects designated by the access to the
            --  dispatch table. Required to handle dispatch tables imported
            --  from C++.

            Set_No_Strict_Aliasing (Base_Type (DT_Prims_Acc));

            --  Add the freezing nodes of these declarations; required to avoid
            --  generating these freezing nodes in wrong scopes (for example in
            --  the IC routine of a derivation of Typ).

            --  What is an "IC routine"? Is "init_proc" meant here???

            Append_List_To (Result, Freeze_Entity (DT_Prims, Typ));
            Append_List_To (Result, Freeze_Entity (DT_Prims_Acc, Typ));

            --  Mark entity of dispatch table. Required by the back end to
            --  handle them properly.

            Set_Is_Dispatch_Table_Entity (DT_Prims);
         end;
      end if;

      --  Mark entities of dispatch table. Required by the back end to handle
      --  them properly.

      if Present (DT) then
         Set_Is_Dispatch_Table_Entity (DT);
         Set_Is_Dispatch_Table_Entity (Etype (DT));
      end if;

      if Present (Iface_DT) then
         Set_Is_Dispatch_Table_Entity (Iface_DT);
         Set_Is_Dispatch_Table_Entity (Etype (Iface_DT));
      end if;

      if Is_CPP_Class (Root_Type (Typ)) then
         Mutate_Ekind (DT_Ptr, E_Variable);
      else
         Mutate_Ekind (DT_Ptr, E_Constant);
      end if;

      Set_Is_Tag       (DT_Ptr);
      Set_Related_Type (DT_Ptr, Typ);

      return Result;
   end Make_Tags;

   ---------------
   -- New_Value --
   ---------------

   function New_Value (From : Node_Id) return Node_Id is
      Res : constant Node_Id := Duplicate_Subexpr (From);
   begin
      if Is_Access_Type (Etype (From)) then
         return Make_Explicit_Dereference (Sloc (From), Prefix => Res);
      else
         return Res;
      end if;
   end New_Value;

   ------------------
   -- Prim_Op_Kind --
   ------------------

   function Prim_Op_Kind
     (Prim : Entity_Id;
      Typ  : Entity_Id) return Node_Id
   is
      Full_Typ : Entity_Id := Typ;
      Loc      : constant Source_Ptr := Sloc (Prim);
      Prim_Op  : Entity_Id;

   begin
      --  Retrieve the original primitive operation

      Prim_Op := Ultimate_Alias (Prim);

      if Ekind (Typ) = E_Record_Type
        and then Present (Corresponding_Concurrent_Type (Typ))
      then
         Full_Typ := Corresponding_Concurrent_Type (Typ);
      end if;

      --  When a private tagged type is completed by a concurrent type,
      --  retrieve the full view.

      if Is_Private_Type (Full_Typ) then
         Full_Typ := Full_View (Full_Typ);
      end if;

      if Ekind (Prim_Op) = E_Function then

         --  Protected function

         if Ekind (Full_Typ) = E_Protected_Type then
            return New_Occurrence_Of (RTE (RE_POK_Protected_Function), Loc);

         --  Task function

         elsif Ekind (Full_Typ) = E_Task_Type then
            return New_Occurrence_Of (RTE (RE_POK_Task_Function), Loc);

         --  Regular function

         else
            return New_Occurrence_Of (RTE (RE_POK_Function), Loc);
         end if;

      else
         pragma Assert (Ekind (Prim_Op) = E_Procedure);

         if Ekind (Full_Typ) = E_Protected_Type then

            --  Protected entry

            if Is_Primitive_Wrapper (Prim_Op)
              and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
            then
               return New_Occurrence_Of (RTE (RE_POK_Protected_Entry), Loc);

            --  Protected procedure

            else
               return
                 New_Occurrence_Of (RTE (RE_POK_Protected_Procedure), Loc);
            end if;

         elsif Ekind (Full_Typ) = E_Task_Type then

            --  Task entry

            if Is_Primitive_Wrapper (Prim_Op)
              and then Ekind (Wrapped_Entity (Prim_Op)) = E_Entry
            then
               return New_Occurrence_Of (RTE (RE_POK_Task_Entry), Loc);

            --  Task "procedure". These are the internally Expander-generated
            --  procedures (task body for instance).

            else
               return New_Occurrence_Of (RTE (RE_POK_Task_Procedure), Loc);
            end if;

         --  Regular procedure

         else
            return New_Occurrence_Of (RTE (RE_POK_Procedure), Loc);
         end if;
      end if;
   end Prim_Op_Kind;

   ------------------------
   -- Register_Primitive --
   ------------------------

   function Register_Primitive
     (Loc     : Source_Ptr;
      Prim    : Entity_Id) return List_Id
   is
      DT_Ptr        : Entity_Id;
      Iface_Prim    : Entity_Id;
      Iface_Typ     : Entity_Id;
      Iface_DT_Ptr  : Entity_Id;
      Iface_DT_Elmt : Elmt_Id;
      L             : constant List_Id := New_List;
      Pos           : Uint;
      Tag           : Entity_Id;
      Tag_Typ       : Entity_Id;
      Thunk_Id      : Entity_Id;
      Thunk_Code    : Node_Id;

   begin
      pragma Assert (not Restriction_Active (No_Dispatching_Calls));

      --  Do not register in the dispatch table eliminated primitives

      if not RTE_Available (RE_Tag)
        or else Is_Eliminated (Ultimate_Alias (Prim))
        or else Generate_SCIL
      then
         return L;
      end if;

      if not Present (Interface_Alias (Prim)) then
         Tag_Typ := Scope (DTC_Entity (Prim));
         Pos := DT_Position (Prim);
         Tag := First_Tag_Component (Tag_Typ);

         if Is_Predefined_Dispatching_Operation (Prim)
           or else Is_Predefined_Dispatching_Alias (Prim)
         then
            DT_Ptr :=
              Node (Next_Elmt (First_Elmt (Access_Disp_Table (Tag_Typ))));

            Append_To (L,
              Build_Set_Predefined_Prim_Op_Address (Loc,
                Tag_Node     => New_Occurrence_Of (DT_Ptr, Loc),
                Position     => Pos,
                Address_Node =>
                  Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                    Make_Attribute_Reference (Loc,
                      Prefix         => New_Occurrence_Of (Prim, Loc),
                      Attribute_Name => Name_Unrestricted_Access))));

            --  Register copy of the pointer to the 'size primitive in the TSD

            if Chars (Prim) = Name_uSize
              and then RTE_Record_Component_Available (RE_Size_Func)
            then
               DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
               Append_To (L,
                 Build_Set_Size_Function (Loc,
                   Tag_Node  => New_Occurrence_Of (DT_Ptr, Loc),
                   Size_Func => Prim));
            end if;

         else
            pragma Assert (Pos /= Uint_0 and then Pos <= DT_Entry_Count (Tag));

            --  Skip registration of primitives located in the C++ part of the
            --  dispatch table. Their slot is set by the IC routine.

            if not Is_CPP_Class (Root_Type (Tag_Typ))
              or else Pos > CPP_Num_Prims (Tag_Typ)
            then
               DT_Ptr := Node (First_Elmt (Access_Disp_Table (Tag_Typ)));
               Append_To (L,
                 Build_Set_Prim_Op_Address (Loc,
                   Typ          => Tag_Typ,
                   Tag_Node     => New_Occurrence_Of (DT_Ptr, Loc),
                   Position     => Pos,
                   Address_Node =>
                     Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                       Make_Attribute_Reference (Loc,
                         Prefix         => New_Occurrence_Of (Prim, Loc),
                         Attribute_Name => Name_Unrestricted_Access))));
            end if;
         end if;

      --  Ada 2005 (AI-251): Primitive associated with an interface type

      --  Generate the code of the thunk only if the interface type is not an
      --  immediate ancestor of Typ; otherwise the dispatch table associated
      --  with the interface is the primary dispatch table and we have nothing
      --  else to do here.

      else
         Tag_Typ   := Find_Dispatching_Type (Alias (Prim));
         Iface_Typ := Find_Dispatching_Type (Interface_Alias (Prim));

         pragma Assert (Is_Interface (Iface_Typ));

         --  No action needed for interfaces that are ancestors of Typ because
         --  their primitives are located in the primary dispatch table.

         if Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True) then
            return L;

         --  No action needed for primitives located in the C++ part of the
         --  dispatch table. Their slot is set by the IC routine.

         elsif Is_CPP_Class (Root_Type (Tag_Typ))
            and then DT_Position (Alias (Prim)) <= CPP_Num_Prims (Tag_Typ)
            and then not Is_Predefined_Dispatching_Operation (Prim)
            and then not Is_Predefined_Dispatching_Alias (Prim)
         then
            return L;
         end if;

         Expand_Interface_Thunk (Prim, Thunk_Id, Thunk_Code, Iface_Typ);

         if not Is_Ancestor (Iface_Typ, Tag_Typ, Use_Full_View => True)
           and then Present (Thunk_Code)
         then
            --  Generate the code necessary to fill the appropriate entry of
            --  the secondary dispatch table of Prim's controlling type with
            --  Thunk_Id's address.

            Iface_DT_Elmt := Find_Interface_ADT (Tag_Typ, Iface_Typ);
            Iface_DT_Ptr  := Node (Iface_DT_Elmt);
            pragma Assert (Has_Thunks (Iface_DT_Ptr));

            Iface_Prim := Interface_Alias (Prim);
            Pos        := DT_Position (Iface_Prim);
            Tag        := First_Tag_Component (Iface_Typ);

            Prepend_To (L, Thunk_Code);

            if Is_Predefined_Dispatching_Operation (Prim)
              or else Is_Predefined_Dispatching_Alias (Prim)
            then
               Append_To (L,
                 Build_Set_Predefined_Prim_Op_Address (Loc,
                   Tag_Node =>
                     New_Occurrence_Of (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
                   Position => Pos,
                   Address_Node =>
                     Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                       Make_Attribute_Reference (Loc,
                         Prefix          => New_Occurrence_Of (Thunk_Id, Loc),
                         Attribute_Name  => Name_Unrestricted_Access))));

               Next_Elmt (Iface_DT_Elmt);
               Next_Elmt (Iface_DT_Elmt);
               Iface_DT_Ptr := Node (Iface_DT_Elmt);
               pragma Assert (not Has_Thunks (Iface_DT_Ptr));

               Append_To (L,
                 Build_Set_Predefined_Prim_Op_Address (Loc,
                   Tag_Node =>
                     New_Occurrence_Of (Node (Next_Elmt (Iface_DT_Elmt)), Loc),
                   Position => Pos,
                   Address_Node =>
                     Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                       Make_Attribute_Reference (Loc,
                         Prefix          =>
                           New_Occurrence_Of (Alias (Prim), Loc),
                         Attribute_Name  => Name_Unrestricted_Access))));

            else
               pragma Assert (Pos /= Uint_0
                 and then Pos <= DT_Entry_Count (Tag));

               Append_To (L,
                 Build_Set_Prim_Op_Address (Loc,
                   Typ          => Iface_Typ,
                   Tag_Node     => New_Occurrence_Of (Iface_DT_Ptr, Loc),
                   Position     => Pos,
                   Address_Node =>
                     Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                       Make_Attribute_Reference (Loc,
                         Prefix => New_Occurrence_Of (Thunk_Id, Loc),
                         Attribute_Name => Name_Unrestricted_Access))));

               Next_Elmt (Iface_DT_Elmt);
               Next_Elmt (Iface_DT_Elmt);
               Iface_DT_Ptr := Node (Iface_DT_Elmt);
               pragma Assert (not Has_Thunks (Iface_DT_Ptr));

               Append_To (L,
                 Build_Set_Prim_Op_Address (Loc,
                   Typ          => Iface_Typ,
                   Tag_Node     => New_Occurrence_Of (Iface_DT_Ptr, Loc),
                   Position     => Pos,
                   Address_Node =>
                     Unchecked_Convert_To (RTE (RE_Prim_Ptr),
                       Make_Attribute_Reference (Loc,
                         Prefix         =>
                           New_Occurrence_Of (Ultimate_Alias (Prim), Loc),
                         Attribute_Name => Name_Unrestricted_Access))));

            end if;
         end if;
      end if;

      return L;
   end Register_Primitive;

   -------------------------
   -- Set_All_DT_Position --
   -------------------------

   procedure Set_All_DT_Position (Typ : Entity_Id) is

      function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean;
      --  Returns True if Prim is located in the dispatch table of
      --  predefined primitives

      procedure Validate_Position (Prim : Entity_Id);
      --  Check that position assigned to Prim is completely safe (it has not
      --  been assigned to a previously defined primitive operation of Typ).

      ------------------------
      -- In_Predef_Prims_DT --
      ------------------------

      function In_Predef_Prims_DT (Prim : Entity_Id) return Boolean is
      begin
         --  Predefined primitives

         if Is_Predefined_Dispatching_Operation (Prim) then
            return True;

         --  Renamings of predefined primitives

         elsif Present (Alias (Prim))
           and then Is_Predefined_Dispatching_Operation (Ultimate_Alias (Prim))
         then
            if Chars (Ultimate_Alias (Prim)) /= Name_Op_Eq then
               return True;

            --  An overriding operation that is a user-defined renaming of
            --  predefined equality inherits its slot from the overridden
            --  operation. Otherwise it is treated as a predefined op and
            --  occupies the same predefined slot as equality. A call to it is
            --  transformed into a call to its alias, which is the predefined
            --  equality op. A dispatching call thus uses the proper slot if
            --  operation is further inherited and called with class-wide
            --  arguments.

            else
               return
                 not Comes_From_Source (Prim)
                   or else No (Overridden_Operation (Prim));
            end if;

         --  User-defined primitives

         else
            return False;
         end if;
      end In_Predef_Prims_DT;

      -----------------------
      -- Validate_Position --
      -----------------------

      procedure Validate_Position (Prim : Entity_Id) is
         Op_Elmt : Elmt_Id;
         Op      : Entity_Id;

      begin
         --  Aliased primitives are safe

         if Present (Alias (Prim)) then
            return;
         end if;

         Op_Elmt := First_Elmt (Primitive_Operations (Typ));
         while Present (Op_Elmt) loop
            Op := Node (Op_Elmt);

            --  No need to check against itself

            if Op = Prim then
               null;

            --  Primitive operations covering abstract interfaces are
            --  allocated later

            elsif Present (Interface_Alias (Op)) then
               null;

            --  Predefined dispatching operations are completely safe. They
            --  are allocated at fixed positions in a separate table.

            elsif Is_Predefined_Dispatching_Operation (Op)
               or else Is_Predefined_Dispatching_Alias (Op)
            then
               null;

            --  Aliased subprograms are safe

            elsif Present (Alias (Op)) then
               null;

            elsif DT_Position (Op) = DT_Position (Prim)
               and then not Is_Predefined_Dispatching_Operation (Op)
               and then not Is_Predefined_Dispatching_Operation (Prim)
               and then not Is_Predefined_Dispatching_Alias (Op)
               and then not Is_Predefined_Dispatching_Alias (Prim)
            then
               --  Handle aliased subprograms

               declare
                  Op_1 : Entity_Id;
                  Op_2 : Entity_Id;

               begin
                  Op_1 := Op;
                  loop
                     if Present (Overridden_Operation (Op_1)) then
                        Op_1 := Overridden_Operation (Op_1);
                     elsif Present (Alias (Op_1)) then
                        Op_1 := Alias (Op_1);
                     else
                        exit;
                     end if;
                  end loop;

                  Op_2 := Prim;
                  loop
                     if Present (Overridden_Operation (Op_2)) then
                        Op_2 := Overridden_Operation (Op_2);
                     elsif Present (Alias (Op_2)) then
                        Op_2 := Alias (Op_2);
                     else
                        exit;
                     end if;
                  end loop;

                  if Op_1 /= Op_2 then
                     raise Program_Error;
                  end if;
               end;
            end if;

            Next_Elmt (Op_Elmt);
         end loop;
      end Validate_Position;

      --  Local variables

      Parent_Typ : constant Entity_Id := Etype (Typ);
      First_Prim : constant Elmt_Id := First_Elmt (Primitive_Operations (Typ));
      The_Tag    : constant Entity_Id := First_Tag_Component (Typ);

      Adjusted  : Boolean := False;
      Finalized : Boolean := False;

      Count_Prim : Nat;
      DT_Length  : Nat;
      Nb_Prim    : Nat;
      Prim       : Entity_Id;
      Prim_Elmt  : Elmt_Id;

   --  Start of processing for Set_All_DT_Position

   begin
      pragma Assert (Present (First_Tag_Component (Typ)));

      --  Set the DT_Position for each primitive operation. Perform some sanity
      --  checks to avoid building inconsistent dispatch tables.

      --  First stage: Set DTC entity of all the primitive operations. This is
      --  required to properly read the DT_Position attribute in latter stages.

      Prim_Elmt  := First_Prim;
      Count_Prim := 0;
      while Present (Prim_Elmt) loop
         Prim := Node (Prim_Elmt);

         --  Predefined primitives have a separate dispatch table

         if not In_Predef_Prims_DT (Prim) then
            Count_Prim := Count_Prim + 1;
         end if;

         Set_DTC_Entity_Value (Typ, Prim);

         --  Clear any previous value of the DT_Position attribute. In this
         --  way we ensure that the final position of all the primitives is
         --  established by the following stages of this algorithm.

         Set_DT_Position_Value (Prim, No_Uint);

         Next_Elmt (Prim_Elmt);
      end loop;

      declare
         Fixed_Prim : array (Int range 0 .. Count_Prim) of Boolean :=
                        (others => False);

         E : Entity_Id;

         procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id);
         --  Called if Typ is declared in a nested package or a public child
         --  package to handle inherited primitives that were inherited by Typ
         --  in the visible part, but whose declaration was deferred because
         --  the parent operation was private and not visible at that point.

         procedure Set_Fixed_Prim (Pos : Nat);
         --  Sets to true an element of the Fixed_Prim table to indicate
         --  that this entry of the dispatch table of Typ is occupied.

         ------------------------------------------
         -- Handle_Inherited_Private_Subprograms --
         ------------------------------------------

         procedure Handle_Inherited_Private_Subprograms (Typ : Entity_Id) is
            Op_List     : Elist_Id;
            Op_Elmt     : Elmt_Id;
            Op_Elmt_2   : Elmt_Id;
            Prim_Op     : Entity_Id;
            Parent_Subp : Entity_Id;

         begin
            Op_List := Primitive_Operations (Typ);

            Op_Elmt := First_Elmt (Op_List);
            while Present (Op_Elmt) loop
               Prim_Op := Node (Op_Elmt);

               --  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)) /= Typ
                 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);

                  --  Check if the type has 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
                        Set_DT_Position_Value (Prim_Op,
                          DT_Position (Parent_Subp));
                        Set_DT_Position_Value (Node (Op_Elmt_2),
                          DT_Position (Parent_Subp));
                        Set_Fixed_Prim (UI_To_Int (DT_Position (Prim_Op)));

                        goto Next_Primitive;
                     end if;

                     Next_Elmt (Op_Elmt_2);
                  end loop;
               end if;

               <<Next_Primitive>>
               Next_Elmt (Op_Elmt);
            end loop;
         end Handle_Inherited_Private_Subprograms;

         --------------------
         -- Set_Fixed_Prim --
         --------------------

         procedure Set_Fixed_Prim (Pos : Nat) is
         begin
            pragma Assert (Pos <= Count_Prim);
            Fixed_Prim (Pos) := True;
         exception
            when Constraint_Error =>
               raise Program_Error;
         end Set_Fixed_Prim;

      begin
         --  In case of nested packages and public child package it may be
         --  necessary a special management on inherited subprograms so that
         --  the dispatch table is properly filled.

         if Ekind (Scope (Scope (Typ))) = E_Package
           and then Scope (Scope (Typ)) /= Standard_Standard
           and then ((Is_Derived_Type (Typ) and then not Is_Private_Type (Typ))
                       or else
                        (Nkind (Parent (Typ)) = N_Private_Extension_Declaration
                          and then Is_Generic_Type (Typ)))
           and then In_Open_Scopes (Scope (Etype (Typ)))
           and then Is_Base_Type (Typ)
         then
            Handle_Inherited_Private_Subprograms (Typ);
         end if;

         --  Second stage: Register fixed entries

         Nb_Prim   := 0;
         Prim_Elmt := First_Prim;
         while Present (Prim_Elmt) loop
            Prim := Node (Prim_Elmt);

            --  Predefined primitives have a separate table and all its
            --  entries are at predefined fixed positions.

            if In_Predef_Prims_DT (Prim) then
               if Is_Predefined_Dispatching_Operation (Prim) then
                  Set_DT_Position_Value (Prim,
                    Default_Prim_Op_Position (Prim));

               else pragma Assert (Present (Alias (Prim)));
                  Set_DT_Position_Value (Prim,
                    Default_Prim_Op_Position (Ultimate_Alias (Prim)));
               end if;

            --  Overriding primitives of ancestor abstract interfaces

            elsif Present (Interface_Alias (Prim))
              and then Is_Ancestor
                         (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
                          Use_Full_View => True)
            then
               pragma Assert (No (DT_Position (Prim)));
               pragma Assert (Present (DTC_Entity (Interface_Alias (Prim))));

               E := Interface_Alias (Prim);
               Set_DT_Position_Value (Prim, DT_Position (E));

               pragma Assert
                 (No (DT_Position (Alias (Prim)))
                    or else DT_Position (Alias (Prim)) = DT_Position (E));
               Set_DT_Position_Value (Alias (Prim), DT_Position (E));
               Set_Fixed_Prim (UI_To_Int (DT_Position (Prim)));

            --  Overriding primitives must use the same entry as the overridden
            --  primitive. Note that the Alias of the operation is set when the
            --  operation is declared by a renaming, in which case it is not
            --  overriding. If it renames another primitive it will use the
            --  same dispatch table slot, but if it renames an operation in a
            --  nested package it's a new primitive and will have its own slot.

            elsif not Present (Interface_Alias (Prim))
              and then Present (Alias (Prim))
              and then Chars (Prim) = Chars (Alias (Prim))
              and then Nkind (Unit_Declaration_Node (Prim)) /=
                         N_Subprogram_Renaming_Declaration
            then
               declare
                  Par_Type : constant Entity_Id :=
                               Find_Dispatching_Type (Alias (Prim));

               begin
                  if Present (Par_Type)
                    and then Par_Type /= Typ
                    and then Is_Ancestor (Par_Type, Typ, Use_Full_View => True)
                    and then Present (DTC_Entity (Alias (Prim)))
                  then
                     E := Alias (Prim);
                     Set_DT_Position_Value (Prim, DT_Position (E));

                     if not Is_Predefined_Dispatching_Alias (E) then
                        Set_Fixed_Prim (UI_To_Int (DT_Position (E)));
                     end if;
                  end if;
               end;
            end if;

            Next_Elmt (Prim_Elmt);
         end loop;

         --  Third stage: Fix the position of all the new primitives. Entries
         --  associated with primitives covering interfaces are handled in a
         --  latter round.

         Prim_Elmt := First_Prim;
         while Present (Prim_Elmt) loop
            Prim := Node (Prim_Elmt);

            --  Skip primitives previously set entries

            if Present (DT_Position (Prim)) then
               null;

            --  Primitives covering interface primitives are handled later

            elsif Present (Interface_Alias (Prim)) then
               null;

            else
               --  Take the next available position in the DT

               loop
                  Nb_Prim := Nb_Prim + 1;
                  pragma Assert (Nb_Prim <= Count_Prim);
                  exit when not Fixed_Prim (Nb_Prim);
               end loop;

               Set_DT_Position_Value (Prim, UI_From_Int (Nb_Prim));
               Set_Fixed_Prim (Nb_Prim);
            end if;

            Next_Elmt (Prim_Elmt);
         end loop;
      end;

      --  Fourth stage: Complete the decoration of primitives covering
      --  interfaces (that is, propagate the DT_Position attribute from
      --  the aliased primitive)

      Prim_Elmt := First_Prim;
      while Present (Prim_Elmt) loop
         Prim := Node (Prim_Elmt);

         if No (DT_Position (Prim))
           and then Present (Interface_Alias (Prim))
         then
            pragma Assert (Present (Alias (Prim))
              and then Find_Dispatching_Type (Alias (Prim)) = Typ);

            --  Check if this entry will be placed in the primary DT

            if Is_Ancestor
                 (Find_Dispatching_Type (Interface_Alias (Prim)), Typ,
                  Use_Full_View => True)
            then
               pragma Assert (Present (DT_Position (Alias (Prim))));
               Set_DT_Position_Value (Prim, DT_Position (Alias (Prim)));

            --  Otherwise it will be placed in the secondary DT

            else
               pragma Assert
                 (Present (DT_Position (Interface_Alias (Prim))));
               Set_DT_Position_Value (Prim,
                 DT_Position (Interface_Alias (Prim)));
            end if;
         end if;

         Next_Elmt (Prim_Elmt);
      end loop;

      --  Generate listing showing the contents of the dispatch tables. This
      --  action is done before some further static checks because in case of
      --  critical errors caused by a wrong dispatch table we need to see the
      --  contents of such table.

      if Debug_Flag_ZZ then
         Write_DT (Typ);
      end if;

      --  Final stage: Ensure that the table is correct plus some further
      --  verifications concerning the primitives.

      Prim_Elmt := First_Prim;
      DT_Length := 0;
      while Present (Prim_Elmt) loop
         Prim := Node (Prim_Elmt);

         --  At this point all the primitives MUST have a position in the
         --  dispatch table.

         if No (DT_Position (Prim)) then
            raise Program_Error;
         end if;

         --  Calculate real size of the dispatch table

         if not In_Predef_Prims_DT (Prim)
           and then UI_To_Int (DT_Position (Prim)) > DT_Length
         then
            DT_Length := UI_To_Int (DT_Position (Prim));
         end if;

         --  Ensure that the assigned position to non-predefined dispatching
         --  operations in the dispatch table is correct.

         if not Is_Predefined_Dispatching_Operation (Prim)
           and then not Is_Predefined_Dispatching_Alias (Prim)
         then
            Validate_Position (Prim);
         end if;

         if Chars (Prim) = Name_Finalize then
            Finalized := True;
         end if;

         if Chars (Prim) = Name_Adjust then
            Adjusted := True;
         end if;

         --  An abstract operation cannot be declared in the private part for a
         --  visible abstract type, because it can't be overridden outside this
         --  package hierarchy. For explicit declarations this is checked at
         --  the point of declaration, but for inherited operations it must be
         --  done when building the dispatch table.

         --  Ada 2005 (AI-251): Primitives associated with interfaces are
         --  excluded from this check because interfaces must be visible in
         --  the public and private part (RM 7.3 (7.3/2))

         --  We disable this check in Relaxed_RM_Semantics mode, to accommodate
         --  legacy Ada code.

         if not Relaxed_RM_Semantics
           and then Is_Abstract_Type (Typ)
           and then Is_Abstract_Subprogram (Prim)
           and then Present (Alias (Prim))
           and then not Is_Interface
                          (Find_Dispatching_Type (Ultimate_Alias (Prim)))
           and then not Present (Interface_Alias (Prim))
           and then Is_Derived_Type (Typ)
           and then In_Private_Part (Current_Scope)
           and then
             List_Containing (Parent (Prim)) =
               Private_Declarations (Package_Specification (Current_Scope))
           and then Original_View_In_Visible_Part (Typ)
         then
            --  We exclude Input and Output stream operations because
            --  Limited_Controlled inherits useless Input and Output stream
            --  operations from Root_Controlled, which can never be overridden.
            --  Move this check to sem???

            if not Is_TSS (Prim, TSS_Stream_Input)
                 and then
               not Is_TSS (Prim, TSS_Stream_Output)
            then
               Error_Msg_NE
                 ("abstract inherited private operation&" &
                  " must be overridden (RM 3.9.3(10))",
                 Parent (Typ), Prim);
            end if;
         end if;

         Next_Elmt (Prim_Elmt);
      end loop;

      --  Additional check

      if Is_Controlled (Typ) then
         if not Finalized then
            Error_Msg_N
              ("controlled type has no explicit Finalize method??", Typ);

         elsif not Adjusted then
            Error_Msg_N
              ("controlled type has no explicit Adjust method??", Typ);
         end if;
      end if;

      --  Set the final size of the Dispatch Table

      Set_DT_Entry_Count (The_Tag, UI_From_Int (DT_Length));

      --  The derived type must have at least as many components as its parent
      --  (for root types Etype points to itself and the test cannot fail).

      if DT_Entry_Count (The_Tag) <
           DT_Entry_Count (First_Tag_Component (Parent_Typ))
      then
         raise Program_Error;
      end if;
   end Set_All_DT_Position;

   --------------------------
   -- Set_CPP_Constructors --
   --------------------------

   procedure Set_CPP_Constructors (Typ : Entity_Id) is

      function Gen_Parameters_Profile (E : Entity_Id) return List_Id;
      --  Duplicate the parameters profile of the imported C++ constructor
      --  adding the "this" pointer to the object as the additional first
      --  parameter under the usual form _Init : in out Typ.

      ----------------------------
      -- Gen_Parameters_Profile --
      ----------------------------

      function Gen_Parameters_Profile (E : Entity_Id) return List_Id is
         Loc   : constant Source_Ptr := Sloc (E);
         Parms : List_Id;
         P     : Node_Id;

      begin
         Parms :=
           New_List (
             Make_Parameter_Specification (Loc,
               Defining_Identifier =>
                 Make_Defining_Identifier (Loc, Name_uInit),
               In_Present          => True,
               Out_Present         => True,
               Parameter_Type      => New_Occurrence_Of (Typ, Loc)));

         if Present (Parameter_Specifications (Parent (E))) then
            P := First (Parameter_Specifications (Parent (E)));
            while Present (P) loop
               Append_To (Parms,
                 Make_Parameter_Specification (Loc,
                   Defining_Identifier =>
                     Make_Defining_Identifier (Loc,
                       Chars => Chars (Defining_Identifier (P))),
                   Parameter_Type      => New_Copy_Tree (Parameter_Type (P)),
                   Expression          => New_Copy_Tree (Expression (P))));
               Next (P);
            end loop;
         end if;

         return Parms;
      end Gen_Parameters_Profile;

      --  Local variables

      Loc     : Source_Ptr;
      E       : Entity_Id;
      Found   : Boolean := False;
      IP      : Entity_Id;
      IP_Body : Node_Id;
      P       : Node_Id;
      Parms   : List_Id;

      Covers_Default_Constructor : Entity_Id := Empty;

   --  Start of processing for Set_CPP_Constructor

   begin
      pragma Assert (Is_CPP_Class (Typ));

      --  Look for the constructor entities

      E := Next_Entity (Typ);
      while Present (E) loop
         if Ekind (E) = E_Function
           and then Is_Constructor (E)
         then
            Found := True;
            Loc   := Sloc (E);
            Parms := Gen_Parameters_Profile (E);
            IP    := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));

            --  Case 1: Constructor of untagged type

            --  If the C++ class has no virtual methods then the matching Ada
            --  type is an untagged record type. In such case there is no need
            --  to generate a wrapper of the C++ constructor because the _tag
            --  component is not available.

            if not Is_Tagged_Type (Typ) then
               Discard_Node
                 (Make_Subprogram_Declaration (Loc,
                    Specification =>
                      Make_Procedure_Specification (Loc,
                        Defining_Unit_Name       => IP,
                        Parameter_Specifications => Parms)));

               Set_Init_Proc (Typ, IP);
               Set_Is_Imported    (IP);
               Set_Is_Constructor (IP);
               Set_Interface_Name (IP, Interface_Name (E));
               Set_Convention     (IP, Convention_CPP);
               Set_Is_Public      (IP);
               Set_Has_Completion (IP);

            --  Case 2: Constructor of a tagged type

            --  In this case we generate the IP routine as a wrapper of the
            --  C++ constructor because IP must also save a copy of the _tag
            --  generated in the C++ side. The copy of the _tag is used by
            --  Build_CPP_Init_Procedure to elaborate derivations of C++ types.

            --  Generate:
            --     procedure IP (_init : in out Typ; ...) is
            --        procedure ConstructorP (_init : in out Typ; ...);
            --        pragma Import (ConstructorP);
            --     begin
            --        ConstructorP (_init, ...);
            --        if Typ._tag = null then
            --           Typ._tag := _init._tag;
            --        end if;
            --     end IP;

            else
               declare
                  Body_Stmts            : constant List_Id := New_List;
                  Constructor_Id        : Entity_Id;
                  Constructor_Decl_Node : Node_Id;
                  Init_Tags_List        : List_Id;

               begin
                  Constructor_Id := Make_Temporary (Loc, 'P');

                  Constructor_Decl_Node :=
                    Make_Subprogram_Declaration (Loc,
                      Make_Procedure_Specification (Loc,
                        Defining_Unit_Name => Constructor_Id,
                        Parameter_Specifications => Parms));

                  Set_Is_Imported    (Constructor_Id);
                  Set_Is_Constructor (Constructor_Id);
                  Set_Interface_Name (Constructor_Id, Interface_Name (E));
                  Set_Convention     (Constructor_Id, Convention_CPP);
                  Set_Is_Public      (Constructor_Id);
                  Set_Has_Completion (Constructor_Id);

                  --  Build the init procedure as a wrapper of this constructor

                  Parms := Gen_Parameters_Profile (E);

                  --  Invoke the C++ constructor

                  declare
                     Actuals : constant List_Id := New_List;

                  begin
                     P := First (Parms);
                     while Present (P) loop
                        Append_To (Actuals,
                          New_Occurrence_Of (Defining_Identifier (P), Loc));
                        Next (P);
                     end loop;

                     Append_To (Body_Stmts,
                       Make_Procedure_Call_Statement (Loc,
                         Name => New_Occurrence_Of (Constructor_Id, Loc),
                         Parameter_Associations => Actuals));
                  end;

                  --  Initialize copies of C++ primary and secondary tags

                  Init_Tags_List := New_List;

                  declare
                     Tag_Elmt : Elmt_Id;
                     Tag_Comp : Node_Id;

                  begin
                     Tag_Elmt := First_Elmt (Access_Disp_Table (Typ));
                     Tag_Comp := First_Tag_Component (Typ);

                     while Present (Tag_Elmt)
                       and then Is_Tag (Node (Tag_Elmt))
                     loop
                        --  Skip the following assertion with primary tags
                        --  because Related_Type is not set on primary tag
                        --  components.

                        pragma Assert
                          (Tag_Comp = First_Tag_Component (Typ)
                             or else Related_Type (Node (Tag_Elmt))
                                       = Related_Type (Tag_Comp));

                        Append_To (Init_Tags_List,
                          Make_Assignment_Statement (Loc,
                            Name =>
                              New_Occurrence_Of (Node (Tag_Elmt), Loc),
                            Expression =>
                              Make_Selected_Component (Loc,
                                Prefix        =>
                                  Make_Identifier (Loc, Name_uInit),
                                Selector_Name =>
                                  New_Occurrence_Of (Tag_Comp, Loc))));

                        Tag_Comp := Next_Tag_Component (Tag_Comp);
                        Next_Elmt (Tag_Elmt);
                     end loop;
                  end;

                  Append_To (Body_Stmts,
                    Make_If_Statement (Loc,
                      Condition =>
                        Make_Op_Eq (Loc,
                          Left_Opnd =>
                            New_Occurrence_Of
                              (Node (First_Elmt (Access_Disp_Table (Typ))),
                               Loc),
                          Right_Opnd =>
                            Unchecked_Convert_To (RTE (RE_Tag),
                              New_Occurrence_Of (RTE (RE_Null_Address), Loc))),
                      Then_Statements => Init_Tags_List));

                  IP_Body :=
                    Make_Subprogram_Body (Loc,
                      Specification =>
                        Make_Procedure_Specification (Loc,
                          Defining_Unit_Name => IP,
                          Parameter_Specifications => Parms),
                      Declarations => New_List (Constructor_Decl_Node),
                      Handled_Statement_Sequence =>
                        Make_Handled_Sequence_Of_Statements (Loc,
                          Statements => Body_Stmts,
                          Exception_Handlers => No_List));

                  Discard_Node (IP_Body);
                  Set_Init_Proc (Typ, IP);
               end;
            end if;

            --  If this constructor has parameters and all its parameters have
            --  defaults then it covers the default constructor. The semantic
            --  analyzer ensures that only one constructor with defaults covers
            --  the default constructor.

            if Present (Parameter_Specifications (Parent (E)))
              and then Needs_No_Actuals (E)
            then
               Covers_Default_Constructor := IP;
            end if;
         end if;

         Next_Entity (E);
      end loop;

      --  If there are no constructors, mark the type as abstract since we
      --  won't be able to declare objects of that type.

      if not Found then
         Set_Is_Abstract_Type (Typ);
      end if;

      --  Handle constructor that has all its parameters with defaults and
      --  hence it covers the default constructor. We generate a wrapper IP
      --  which calls the covering constructor.

      if Present (Covers_Default_Constructor) then
         declare
            Body_Stmts : List_Id;

         begin
            Loc := Sloc (Covers_Default_Constructor);

            Body_Stmts := New_List (
              Make_Procedure_Call_Statement (Loc,
                Name                   =>
                  New_Occurrence_Of (Covers_Default_Constructor, Loc),
                Parameter_Associations => New_List (
                  Make_Identifier (Loc, Name_uInit))));

            IP := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));

            IP_Body :=
              Make_Subprogram_Body (Loc,
                Specification              =>
                  Make_Procedure_Specification (Loc,
                    Defining_Unit_Name       => IP,
                    Parameter_Specifications => New_List (
                      Make_Parameter_Specification (Loc,
                        Defining_Identifier =>
                          Make_Defining_Identifier (Loc, Name_uInit),
                        Parameter_Type      => New_Occurrence_Of (Typ, Loc)))),

                Declarations               => No_List,

                Handled_Statement_Sequence =>
                  Make_Handled_Sequence_Of_Statements (Loc,
                    Statements         => Body_Stmts,
                    Exception_Handlers => No_List));

            Discard_Node (IP_Body);
            Set_Init_Proc (Typ, IP);
         end;
      end if;

      --  If the CPP type has constructors then it must import also the default
      --  C++ constructor. It is required for default initialization of objects
      --  of the type. It is also required to elaborate objects of Ada types
      --  that are defined as derivations of this CPP type.

      if Has_CPP_Constructors (Typ)
        and then No (Init_Proc (Typ))
      then
         Error_Msg_N ("??default constructor must be imported from C++", Typ);
      end if;
   end Set_CPP_Constructors;

   ---------------------------
   -- Set_DT_Position_Value --
   ---------------------------

   procedure Set_DT_Position_Value (Prim : Entity_Id; Value : Uint) is
   begin
      Set_DT_Position (Prim, Value);

      --  Propagate the value to the wrapped subprogram (if one is present)

      if Ekind (Prim) in E_Function | E_Procedure
        and then Is_Primitive_Wrapper (Prim)
        and then Present (Wrapped_Entity (Prim))
        and then Is_Dispatching_Operation (Wrapped_Entity (Prim))
      then
         Set_DT_Position (Wrapped_Entity (Prim), Value);
      end if;
   end Set_DT_Position_Value;

   --------------------------
   -- Set_DTC_Entity_Value --
   --------------------------

   procedure Set_DTC_Entity_Value
     (Tagged_Type : Entity_Id;
      Prim        : Entity_Id)
   is
   begin
      if Present (Interface_Alias (Prim))
        and then Is_Interface
                   (Find_Dispatching_Type (Interface_Alias (Prim)))
      then
         Set_DTC_Entity (Prim,
           Find_Interface_Tag
             (T     => Tagged_Type,
              Iface => Find_Dispatching_Type (Interface_Alias (Prim))));
      else
         Set_DTC_Entity (Prim,
           First_Tag_Component (Tagged_Type));
      end if;

      --  Propagate the value to the wrapped subprogram (if one is present)

      if Ekind (Prim) in E_Function | E_Procedure
        and then Is_Primitive_Wrapper (Prim)
        and then Present (Wrapped_Entity (Prim))
        and then Is_Dispatching_Operation (Wrapped_Entity (Prim))
      then
         Set_DTC_Entity (Wrapped_Entity (Prim), DTC_Entity (Prim));
      end if;
   end Set_DTC_Entity_Value;

   -----------------
   -- Tagged_Kind --
   -----------------

   function Tagged_Kind (T : Entity_Id) return Node_Id is
      Conc_Typ : Entity_Id;
      Loc      : constant Source_Ptr := Sloc (T);

   begin
      pragma Assert
        (Is_Tagged_Type (T) and then RTE_Available (RE_Tagged_Kind));

      --  Abstract kinds

      if Is_Abstract_Type (T) then
         if Is_Limited_Record (T) then
            return New_Occurrence_Of
              (RTE (RE_TK_Abstract_Limited_Tagged), Loc);
         else
            return New_Occurrence_Of
              (RTE (RE_TK_Abstract_Tagged), Loc);
         end if;

      --  Concurrent kinds

      elsif Is_Concurrent_Record_Type (T) then
         Conc_Typ := Corresponding_Concurrent_Type (T);

         if Present (Full_View (Conc_Typ)) then
            Conc_Typ := Full_View (Conc_Typ);
         end if;

         if Ekind (Conc_Typ) = E_Protected_Type then
            return New_Occurrence_Of (RTE (RE_TK_Protected), Loc);
         else
            pragma Assert (Ekind (Conc_Typ) = E_Task_Type);
            return New_Occurrence_Of (RTE (RE_TK_Task), Loc);
         end if;

      --  Regular tagged kinds

      else
         if Is_Limited_Record (T) then
            return New_Occurrence_Of (RTE (RE_TK_Limited_Tagged), Loc);
         else
            return New_Occurrence_Of (RTE (RE_TK_Tagged), Loc);
         end if;
      end if;
   end Tagged_Kind;

   --------------
   -- Write_DT --
   --------------

   procedure Write_DT (Typ : Entity_Id) is
      Elmt : Elmt_Id;
      Prim : Node_Id;

   begin
      --  Protect this procedure against wrong usage. Required because it will
      --  be used directly from GDB

      if not (Typ <= Last_Node_Id)
        or else not Is_Tagged_Type (Typ)
      then
         Write_Str ("wrong usage: Write_DT must be used with tagged types");
         Write_Eol;
         return;
      end if;

      Write_Int (Int (Typ));
      Write_Str (": ");
      Write_Name (Chars (Typ));

      if Is_Interface (Typ) then
         Write_Str (" is interface");
      end if;

      Write_Eol;

      Elmt := First_Elmt (Primitive_Operations (Typ));
      while Present (Elmt) loop
         Prim := Node (Elmt);
         Write_Str  (" - ");

         --  Indicate if this primitive will be allocated in the primary
         --  dispatch table or in a secondary dispatch table associated
         --  with an abstract interface type

         if Present (DTC_Entity (Prim)) then
            if Is_RTE (Etype (DTC_Entity (Prim)), RE_Tag) then
               Write_Str ("[P] ");
            else
               Write_Str ("[s] ");
            end if;
         end if;

         --  Output the node of this primitive operation and its name

         Write_Int  (Int (Prim));
         Write_Str  (": ");

         if Is_Predefined_Dispatching_Operation (Prim) then
            Write_Str ("(predefined) ");
         end if;

         --  Prefix the name of the primitive with its corresponding tagged
         --  type to facilitate seeing inherited primitives.

         if Present (Alias (Prim)) then
            Write_Name
              (Chars (Find_Dispatching_Type (Ultimate_Alias (Prim))));
         else
            Write_Name (Chars (Typ));
         end if;

         Write_Str (".");
         Write_Name (Chars (Prim));

         --  Indicate if this primitive has an aliased primitive

         if Present (Alias (Prim)) then
            Write_Str (" (alias = ");
            Write_Int (Int (Alias (Prim)));

            --  If the DTC_Entity attribute is already set we can also output
            --  the name of the interface covered by this primitive (if any).

            if Ekind (Alias (Prim)) in E_Function | E_Procedure
              and then Present (DTC_Entity (Alias (Prim)))
              and then Is_Interface (Scope (DTC_Entity (Alias (Prim))))
            then
               Write_Str  (" from interface ");
               Write_Name (Chars (Scope (DTC_Entity (Alias (Prim)))));
            end if;

            if Present (Interface_Alias (Prim)) then
               Write_Str  (", AI_Alias of ");

               if Is_Null_Interface_Primitive (Interface_Alias (Prim)) then
                  Write_Str ("null primitive ");
               end if;

               Write_Name
                 (Chars (Find_Dispatching_Type (Interface_Alias (Prim))));
               Write_Char (':');
               Write_Int  (Int (Interface_Alias (Prim)));
            end if;

            Write_Str (")");
         end if;

         --  Display the final position of this primitive in its associated
         --  (primary or secondary) dispatch table.

         if Present (DTC_Entity (Prim))
           and then Present (DT_Position (Prim))
         then
            Write_Str (" at #");
            Write_Int (UI_To_Int (DT_Position (Prim)));
         end if;

         if Is_Abstract_Subprogram (Prim) then
            Write_Str (" is abstract;");

         --  Check if this is a null primitive

         elsif Comes_From_Source (Prim)
           and then Ekind (Prim) = E_Procedure
           and then Null_Present (Parent (Prim))
         then
            Write_Str (" is null;");
         end if;

         if Is_Eliminated (Ultimate_Alias (Prim)) then
            Write_Str (" (eliminated)");
         end if;

         if Is_Imported (Prim)
           and then Convention (Prim) = Convention_CPP
         then
            Write_Str (" (C++)");
         end if;

         Write_Eol;

         Next_Elmt (Elmt);
      end loop;
   end Write_DT;

end Exp_Disp;
