blob: af83a26a23d76101ff958a0143334d33eaa8fe7b [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- E X P _ S E L --
-- --
-- B o d y --
-- --
-- Copyright (C) 1992-2022, 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 Einfo; use Einfo;
with Einfo.Entities; use Einfo.Entities;
with Nlists; use Nlists;
with Nmake; use Nmake;
with Opt; use Opt;
with Rtsfind; use Rtsfind;
with Sinfo; use Sinfo;
with Sinfo.Nodes; use Sinfo.Nodes;
with Snames; use Snames;
with Stand; use Stand;
with Tbuild; use Tbuild;
package body Exp_Sel is
-----------------------
-- Build_Abort_Block --
-----------------------
function Build_Abort_Block
(Loc : Source_Ptr;
Abr_Blk_Ent : Entity_Id;
Cln_Blk_Ent : Entity_Id;
Blk : Node_Id) return Node_Id
is
begin
return
Make_Block_Statement (Loc,
Identifier => New_Occurrence_Of (Abr_Blk_Ent, Loc),
Declarations => No_List,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
Statements =>
New_List (
Make_Implicit_Label_Declaration (Loc,
Defining_Identifier => Cln_Blk_Ent,
Label_Construct => Blk),
Blk),
Exception_Handlers =>
New_List (Build_Abort_Block_Handler (Loc))));
end Build_Abort_Block;
-------------------------------
-- Build_Abort_Block_Handler --
-------------------------------
function Build_Abort_Block_Handler (Loc : Source_Ptr) return Node_Id is
begin
return Make_Implicit_Exception_Handler (Loc,
Exception_Choices =>
New_List (New_Occurrence_Of (Stand.Abort_Signal, Loc)),
Statements => New_List (Make_Null_Statement (Loc)));
end Build_Abort_Block_Handler;
-------------
-- Build_B --
-------------
function Build_B
(Loc : Source_Ptr;
Decls : List_Id) return Entity_Id
is
B : constant Entity_Id := Make_Temporary (Loc, 'B');
begin
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => B,
Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
Expression => New_Occurrence_Of (Standard_False, Loc)));
return B;
end Build_B;
-------------
-- Build_C --
-------------
function Build_C
(Loc : Source_Ptr;
Decls : List_Id) return Entity_Id
is
C : constant Entity_Id := Make_Temporary (Loc, 'C');
begin
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => C,
Object_Definition =>
New_Occurrence_Of (RTE (RE_Prim_Op_Kind), Loc)));
return C;
end Build_C;
-------------------------
-- Build_Cleanup_Block --
-------------------------
function Build_Cleanup_Block
(Loc : Source_Ptr;
Blk_Ent : Entity_Id;
Stmts : List_Id;
Clean_Ent : Entity_Id) return Node_Id
is
Cleanup_Block : constant Node_Id :=
Make_Block_Statement (Loc,
Identifier =>
New_Occurrence_Of (Blk_Ent, Loc),
Declarations => No_List,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
Statements => Stmts),
Is_Asynchronous_Call_Block => True);
begin
Set_Entry_Cancel_Parameter (Blk_Ent, Clean_Ent);
return Cleanup_Block;
end Build_Cleanup_Block;
-------------
-- Build_K --
-------------
function Build_K
(Loc : Source_Ptr;
Decls : List_Id;
Obj : Entity_Id) return Entity_Id
is
K : constant Entity_Id := Make_Temporary (Loc, 'K');
Tag_Node : Node_Id;
begin
if Tagged_Type_Expansion then
Tag_Node := Unchecked_Convert_To (RTE (RE_Tag), Obj);
else
Tag_Node :=
Make_Attribute_Reference (Loc,
Prefix => Obj,
Attribute_Name => Name_Tag);
end if;
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => K,
Object_Definition =>
New_Occurrence_Of (RTE (RE_Tagged_Kind), Loc),
Expression =>
Make_Function_Call (Loc,
Name => New_Occurrence_Of (RTE (RE_Get_Tagged_Kind), Loc),
Parameter_Associations => New_List (Tag_Node))));
return K;
end Build_K;
-------------
-- Build_S --
-------------
function Build_S
(Loc : Source_Ptr;
Decls : List_Id) return Entity_Id
is
S : constant Entity_Id := Make_Temporary (Loc, 'S');
begin
Append_To (Decls,
Make_Object_Declaration (Loc,
Defining_Identifier => S,
Object_Definition => New_Occurrence_Of (Standard_Integer, Loc)));
return S;
end Build_S;
------------------------
-- Build_S_Assignment --
------------------------
function Build_S_Assignment
(Loc : Source_Ptr;
S : Entity_Id;
Obj : Entity_Id;
Call_Ent : Entity_Id) return Node_Id
is
Typ : constant Entity_Id := Etype (Obj);
begin
if Tagged_Type_Expansion then
return
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (S, Loc),
Expression =>
Make_Function_Call (Loc,
Name => New_Occurrence_Of (RTE (RE_Get_Offset_Index), Loc),
Parameter_Associations => New_List (
Unchecked_Convert_To (RTE (RE_Tag), Obj),
Make_Integer_Literal (Loc, DT_Position (Call_Ent)))));
-- VM targets
else
return
Make_Assignment_Statement (Loc,
Name => New_Occurrence_Of (S, Loc),
Expression =>
Make_Function_Call (Loc,
Name => New_Occurrence_Of (RTE (RE_Get_Offset_Index), Loc),
Parameter_Associations => New_List (
-- Obj_Typ
Make_Attribute_Reference (Loc,
Prefix => Obj,
Attribute_Name => Name_Tag),
-- Iface_Typ
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (Typ, Loc),
Attribute_Name => Name_Tag),
-- Position
Make_Integer_Literal (Loc, DT_Position (Call_Ent)))));
end if;
end Build_S_Assignment;
end Exp_Sel;