home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
gnat-2.06-src.tgz
/
tar.out
/
fsf
/
gnat
/
ada
/
exp_ch13.adb
< prev
next >
Wrap
Text File
|
1996-09-28
|
15KB
|
410 lines
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- E X P _ C H 1 3 --
-- --
-- B o d y --
-- --
-- $Revision: 1.28 $ --
-- --
-- Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
with Atree; use Atree;
with Einfo; use Einfo;
with Exp_Ch3; use Exp_Ch3;
with Exp_Ch6; use Exp_Ch6;
with Exp_TSS; use Exp_TSS;
with Nlists; use Nlists;
with Nmake; use Nmake;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Ch7; use Sem_Ch7;
with Sem_Ch8; use Sem_Ch8;
with Sem_Eval; use Sem_Eval;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Snames; use Snames;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
package body Exp_Ch13 is
------------------------------------------
-- Expand_N_Attribute_Definition_Clause --
------------------------------------------
-- Expansion action depends on attribute involved
procedure Expand_N_Attribute_Definition_Clause (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Exp : constant Node_Id := Expression (N);
Ent : Entity_Id;
V : Node_Id;
begin
Ent := Entity (Name (N));
if Is_Type (Ent) then
Ent := Underlying_Type (Ent);
end if;
case Get_Attribute_Id (Chars (N)) is
-- Alignment
when Attribute_Alignment =>
-- As required by Gigi, we guarantee that the operand is an
-- integer literal (this simplifies things in Gigi).
if Nkind (Exp) /= N_Integer_Literal then
Rewrite_Substitute_Tree
(Exp, Make_Integer_Literal (Loc, Expr_Value (Exp)));
end if;
-- Input attribute
when Attribute_Input => Input : declare
Input_Ent : Entity_Id;
Input_Decl : Node_Id;
F : Entity_Id;
Subp : Entity_Id;
Etyp : Entity_Id;
begin
Subp := Entity (Exp);
F := First_Formal (Subp);
Input_Ent := Make_Defining_Identifier (Loc, Name_uInput);
Etyp := Etype (Subp);
Input_Decl :=
Make_Subprogram_Renaming_Declaration (Loc,
Specification =>
Make_Function_Specification (Loc,
Defining_Unit_Name => Input_Ent,
Parameter_Specifications =>
New_List (
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('S')),
Parameter_Type =>
Make_Access_Definition (Loc,
Subtype_Mark =>
New_Reference_To (
Designated_Type (Etype (F)), Loc)))),
Subtype_Mark =>
New_Reference_To (Etyp, Loc)),
Name => New_Reference_To (Subp, Loc));
if No (Freeze_Node (Ent)) then
Set_Freeze_Node (Ent, Make_Freeze_Entity (Loc));
Set_TSS_Elist (Freeze_Node (Ent), No_Elist);
end if;
Set_TSS (Ent, Input_Ent);
end Input;
-- Attribute Output
when Attribute_Output => Output : declare
Output_Ent : Entity_Id;
Output_Decl : Node_Id;
F : Entity_Id;
Subp : Entity_Id;
Etyp : Entity_Id;
begin
Subp := Entity (Exp);
F := First_Formal (Subp);
Output_Ent := Make_Defining_Identifier (Loc, Name_uOutput);
Etyp := Etype (Next_Formal (F));
Output_Decl :=
Make_Subprogram_Renaming_Declaration (Loc,
Specification =>
Make_Procedure_Specification (Loc,
Defining_Unit_Name => Output_Ent,
Parameter_Specifications =>
New_List (
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('S')),
Parameter_Type =>
Make_Access_Definition (Loc,
Subtype_Mark =>
New_Reference_To (
Designated_Type (Etype (F)), Loc))),
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('V')),
Parameter_Type =>
New_Reference_To (Etyp, Loc)))),
Name => New_Reference_To (Subp, Loc));
if No (Freeze_Node (Ent)) then
Set_Freeze_Node (Ent, Make_Freeze_Entity (Loc));
Set_TSS_Elist (Freeze_Node (Ent), No_Elist);
end if;
Set_TSS (Ent, Output_Ent);
end Output;
-- Read attribute
when Attribute_Read => Read : declare
Read_Ent : Entity_Id;
Read_Decl : Node_Id;
F : Entity_Id;
Subp : Entity_Id;
Etyp : Entity_Id;
begin
Subp := Entity (Exp);
F := First_Formal (Subp);
Read_Ent := Make_Defining_Identifier (Loc, Name_uRead);
Etyp := Etype (Next_Formal (F));
Read_Decl :=
Make_Subprogram_Renaming_Declaration (Loc,
Specification =>
Make_Procedure_Specification (Loc,
Defining_Unit_Name => Read_Ent,
Parameter_Specifications =>
New_List (
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('S')),
Parameter_Type =>
Make_Access_Definition (Loc,
Subtype_Mark =>
New_Reference_To (
Designated_Type (Etype (F)), Loc))),
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('V')),
Out_Present => True,
Parameter_Type =>
New_Reference_To (Etyp, Loc)))),
Name => New_Reference_To (Subp, Loc));
if No (Freeze_Node (Ent)) then
Set_Freeze_Node (Ent, Make_Freeze_Entity (Loc));
Set_TSS_Elist (Freeze_Node (Ent), No_Elist);
end if;
Set_TSS (Ent, Read_Ent);
end Read;
-- Storage_Size
when Attribute_Storage_Size =>
-- If the type is a task type, then assign the value of the
-- storage size to the Size variable associated with the task.
-- task_typeZ := expression
if Ekind (Ent) = E_Task_Type then
Rewrite_Substitute_Tree (N,
Make_Assignment_Statement (Loc,
Name => New_Reference_To (Storage_Size_Variable (Ent), Loc),
Expression =>
Make_Type_Conversion (Loc,
Subtype_Mark =>
New_Reference_To (RTE (RE_Size_Type), Loc),
Expression => Expression (N))));
Analyze (N);
-- For Storage_Size for an access type, create a variable to hold
-- the value of the specified size with name typeV and expand an
-- assignment statement to initialze this value.
elsif Ekind (Ent) = E_Access_Type then
V := Make_Defining_Identifier (Loc,
New_External_Name (Chars (Ent), 'V'));
Rewrite_Substitute_Tree (N,
Make_Object_Declaration (Loc,
Defining_Identifier => V,
Object_Definition =>
New_Reference_To (RTE (RE_Storage_Offset), Loc),
Expression =>
Make_Type_Conversion (Loc,
Subtype_Mark =>
New_Reference_To (RTE (RE_Storage_Offset), Loc),
Expression => Expression (N))));
Analyze (N);
Set_Storage_Size_Variable (Ent, Entity_Id (V));
end if;
-- Write attribute
when Attribute_Write => Write : declare
Write_Ent : Entity_Id;
Write_Decl : Node_Id;
F : Entity_Id;
Subp : Entity_Id;
Etyp : Entity_Id;
begin
Subp := Entity (Exp);
F := First_Formal (Subp);
Write_Ent := Make_Defining_Identifier (Loc, Name_uWrite);
Etyp := Etype (Next_Formal (F));
Write_Decl :=
Make_Subprogram_Renaming_Declaration (Loc,
Specification =>
Make_Procedure_Specification (Loc,
Defining_Unit_Name => Write_Ent,
Parameter_Specifications =>
New_List (
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('S')),
Parameter_Type =>
Make_Access_Definition (Loc,
Subtype_Mark =>
New_Reference_To (
Designated_Type (Etype (F)), Loc))),
Make_Parameter_Specification (Loc,
Defining_Identifier =>
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('V')),
Parameter_Type =>
New_Reference_To (Etyp, Loc)))),
Name => New_Reference_To (Subp, Loc));
if No (Freeze_Node (Ent)) then
Set_Freeze_Node (Ent, Make_Freeze_Entity (Loc));
Set_TSS_Elist (Freeze_Node (Ent), No_Elist);
end if;
Set_TSS (Ent, Write_Ent);
end Write;
-- Other attributes require no expansion
when others => null;
end case;
end Expand_N_Attribute_Definition_Clause;
----------------------------
-- Expand_N_Freeze_Entity --
----------------------------
procedure Expand_N_Freeze_Entity (N : Node_Id) is
E : constant Entity_Id := Entity (N);
Inner_Scope : Boolean := False;
begin
if not Is_Type (E) and then not Is_Subprogram (E) then
return;
end if;
-- If the entity being frozen is defined in an inner package or task,
-- we must establish the proper visibility before freezing the
-- entity, and related subprograms.
if Scope (Scope (E)) = Current_Scope then
New_Scope (Scope (E));
Install_Visible_Declarations (Scope (E));
Install_Private_Declarations (Scope (E));
Inner_Scope := True;
end if;
-- If type, freeze the type
if Is_Type (E) then
Freeze_Type (N);
-- If subprogram, freeze the subprogram
elsif Is_Subprogram (E) then
Freeze_Subprogram (N);
-- No other entities require any front end freeze actions
else
null;
end if;
-- Analyze actions generated by freezing.
if Present (Actions (N)) then
Analyze_List (Actions (N));
end if;
if Inner_Scope then
if Ekind (Current_Scope) = E_Package then
End_Package_Scope (Scope (E));
else
End_Scope;
end if;
end if;
end Expand_N_Freeze_Entity;
-------------------------------------------
-- Expand_N_Record_Representation_Clause --
-------------------------------------------
-- The only expansion required is for the case of a mod clause present,
-- which is removed, and translated into an alignment representation
-- clause inserted immediately after the record rep clause.
procedure Expand_N_Record_Representation_Clause (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Rectype : constant Entity_Id := Entity (Identifier (N));
Mod_Val : Uint;
begin
if Present (Mod_Clause (N)) then
Mod_Val := Expr_Value (Expression (Mod_Clause (N)));
Set_Mod_Clause (N, Empty);
Insert_After (N,
Make_Attribute_Definition_Clause (Loc,
Name => New_Reference_To (Rectype, Loc),
Chars => Name_Alignment,
Expression => Make_Integer_Literal (Loc, Mod_Val)));
end if;
end Expand_N_Record_Representation_Clause;
end Exp_Ch13;