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