Skip to content

Commit 1f7f49a

Browse files
committed
Implement representation clause address
We handle it by 1: declaring a new variable with type one pointer deeper 2: assign the address to it 3: store the name (we'll need to replace it in the symbol table -- next commit)
1 parent b1567bc commit 1f7f49a

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

gnat2goto/driver/goto_utils.ads

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ with Atree; use Atree;
44
with Sinfo; use Sinfo;
55
with Symbol_Table_Info; use Symbol_Table_Info;
66
with Uintp; use Uintp;
7+
with GNAT.Table;
78

89
package GOTO_Utils is
910

@@ -19,6 +20,15 @@ package GOTO_Utils is
1920

2021
Synthetic_Variable_Counter : Positive := 1;
2122

23+
type String_Access is access String;
24+
25+
package Addressed_Variables is new
26+
GNAT.Table (Table_Component_Type => String_Access,
27+
Table_Index_Type => Natural,
28+
Table_Low_Bound => 1,
29+
Table_Initial => 1,
30+
Table_Increment => 20);
31+
2232
function Fresh_Var_Name (Infix : String) return String;
2333
function Fresh_Var_Symbol_Expr (Ty : Irep; Infix : String) return Irep;
2434

gnat2goto/driver/tree_walk.adb

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4634,18 +4634,16 @@ package body Tree_Walk is
46344634
Entity_Esize : constant Uint := Esize (Entity (N));
46354635
Target_Type_Irep : constant Irep :=
46364636
Follow_Symbol_Type (Get_Type (Target_Name), Global_Symbol_Table);
4637-
Expression_Value : constant Uint := Intval (Expression (N));
46384637
begin
46394638
pragma Assert (Kind (Target_Type_Irep) in Class_Type);
46404639
if Attr_Id = "size" then
4641-
46424640
-- Just check that the front-end already applied this size
46434641
-- clause, i .e. that the size of type-irep we already had
46444642
-- equals the entity type this clause is applied to (and the
46454643
-- size specified in this clause).
46464644
pragma Assert (Entity_Esize =
46474645
UI_From_Int (Int (Get_Width (Target_Type_Irep)))
4648-
and Entity_Esize = Expression_Value);
4646+
and Entity_Esize = Intval (Expression (N)));
46494647
return;
46504648
elsif Attr_Id = "component_size" then
46514649
if not Is_Array_Type (Entity (N)) then
@@ -4661,6 +4659,7 @@ package body Tree_Walk is
46614659
Global_Symbol_Table);
46624660
Target_Subtype_Width : constant Uint :=
46634661
UI_From_Int (Int (Get_Width (Target_Subtype)));
4662+
Expression_Value : constant Uint := Intval (Expression (N));
46644663
begin
46654664
if Component_Size (Entity (N)) /= Expression_Value or
46664665
Target_Subtype_Width /= Expression_Value
@@ -4671,10 +4670,77 @@ package body Tree_Walk is
46714670
end if;
46724671
end;
46734672
return;
4674-
end if;
46754673

4676-
Report_Unhandled_Node_Empty (N, "Process_Declaration",
4674+
elsif Attr_Id = "address" then
4675+
-- Assuming this Ada code:
4676+
--------------------
4677+
-- Var : VarType;
4678+
-- for Var'Address use System'To_Address (hex_address);
4679+
--------------------
4680+
--
4681+
-- Produce this C code:
4682+
--------------------
4683+
-- VarType *Ptr_Var;
4684+
-- Ptr_Var = (VarType*)hex_address;
4685+
--------------------
4686+
pragma Assert (Global_Symbol_Table.Contains (Intern
4687+
(Get_Identifier (Target_Name))));
4688+
4689+
declare
4690+
Source_Loc : constant Source_Ptr := Sloc (N);
4691+
function Get_Address_Expr return Irep;
4692+
function Get_Address_Expr return Irep is
4693+
begin
4694+
if Nkind (Expression (N)) = N_Function_Call then
4695+
declare
4696+
Parameters : constant List_Id :=
4697+
Parameter_Associations (Expression (N));
4698+
begin
4699+
pragma Assert (not Is_Empty_List (Parameters) and then
4700+
Nkind (First (Parameters)) = N_Integer_Literal);
4701+
return
4702+
Integer_Constant_To_Expr
4703+
(Value => Intval (First (Parameters)),
4704+
Expr_Type => CProver_Size_T,
4705+
Type_Width => Size_T_Width,
4706+
Source_Location => Source_Loc);
4707+
end;
4708+
else
4709+
return Do_Expression (Expression (N));
4710+
end if;
4711+
end Get_Address_Expr;
4712+
4713+
Address_Expr : constant Irep := Get_Address_Expr;
4714+
Address_Type : constant Irep :=
4715+
Make_Pointer_Type (Target_Type_Irep);
4716+
Lhs_Expr : constant Irep :=
4717+
Make_Symbol_Expr (Source_Location => Source_Loc,
4718+
I_Type => Address_Type,
4719+
Range_Check => False,
4720+
Identifier =>
4721+
"Ptr_" & Get_Identifier (Target_Name));
4722+
Rhs_Expr : constant Irep :=
4723+
Typecast_If_Necessary (Expr => Address_Expr,
4724+
New_Type => Address_Type,
4725+
A_Symbol_Table => Global_Symbol_Table);
4726+
begin
4727+
New_Object_Symbol_Entry
4728+
(Object_Name =>
4729+
Intern ("Ptr_" & Get_Identifier (Target_Name)),
4730+
Object_Type => Address_Type,
4731+
Object_Init_Value => Rhs_Expr,
4732+
A_Symbol_Table => Global_Symbol_Table);
4733+
Append_Declare_And_Init (Symbol => Lhs_Expr,
4734+
Value => Rhs_Expr,
4735+
Block => Block,
4736+
Source_Loc => Source_Loc);
4737+
Addressed_Variables.Append (
4738+
new String'(Get_Identifier (Target_Name)));
4739+
end;
4740+
else
4741+
Report_Unhandled_Node_Empty (N, "Process_Declaration",
46774742
"Representation clause unsupported: " & Attr_Id);
4743+
end if;
46784744
end Handle_Representation_Clause;
46794745

46804746
begin

0 commit comments

Comments
 (0)