------------------------------------------------------------------------------
--                                                                          --
--                         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 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 : Node_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;

      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.

      ---------------
      -- 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;

      --  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);

      --  The tagged type of a dispatching call must be frozen at this stage

      pragma Assert (Is_Frozen (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));

      --  The debugging information for type Ada.Tags.Type_Specific_Data is
      --  needed by the debugger in order to display values of tagged types.

      Set_Needs_Debug_Info (TSD, Needs_Debug_Info (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;
