-- Ortho debug back-end declarations. -- Copyright (C) 2005-2014 Tristan Gingold -- -- GHDL is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. -- -- GHDL is distributed in the hope that it will be useful, but WITHOUT 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 -- along with GCC; see the file COPYING. If not, write to the Free -- Software Foundation, 59 Temple Place - Suite 330, Boston, MA -- 02111-1307, USA. with Interfaces; use Interfaces; with Ortho_Ident; use Ortho_Ident; -- Interface to create nodes. package Ortho_Debug is procedure Init; procedure Finish; private -- This back-end supports nested subprograms. Has_Nested_Subprograms : constant Boolean := True; -- A node for a type. type O_Tnode_Type (<>); type O_Tnode is access O_Tnode_Type; -- A node for a statement. type O_Snode_Type (<>); type O_Snode is access O_Snode_Type; Top : O_Snode; type Str_Acc is access String; type Decl_Scope_Type; type Decl_Scope_Acc is access Decl_Scope_Type; type On_Decl_Kind is (ON_Type_Decl, ON_Completed_Type_Decl, ON_Const_Decl, ON_Var_Decl, ON_Interface_Decl, ON_Function_Decl, ON_Function_Body, ON_Init_Value, ON_Debug_Line_Decl, ON_Debug_Comment_Decl, ON_Debug_Filename_Decl); type O_Dnode_Type (<>); type O_Dnode is access O_Dnode_Type; O_Dnode_Null : constant O_Dnode := null; type O_Dnode_Type (Kind : On_Decl_Kind) is record Next : O_Dnode; Name : O_Ident; Dtype : O_Tnode; Storage : O_Storage; -- Declare statement in which the declaration appears. Scope : O_Snode; -- Line number, for regen. Lineno : Natural; case Kind is when ON_Type_Decl => null; when ON_Completed_Type_Decl => null; when ON_Const_Decl | ON_Var_Decl => -- Corresponding declaration for initial value (if any). Value_Decl : O_Dnode; when ON_Init_Value => -- Corresponding declaration of the object. Init_Decl : O_Dnode; Value : O_Cnode; when ON_Function_Decl => Interfaces : O_Dnode; Func_Body : O_Dnode; Alive : Boolean; when ON_Function_Body => Func_Decl : O_Dnode; Func_Stmt : O_Snode; when ON_Interface_Decl => Func_Scope : O_Dnode; when ON_Debug_Line_Decl => Line : Natural; when ON_Debug_Comment_Decl => Comment : Str_Acc; when ON_Debug_Filename_Decl => Filename : Str_Acc; end case; end record; -- A node for a record element. type O_Fnode_Type; type O_Fnode is access O_Fnode_Type; O_Fnode_Null : constant O_Fnode := null; type O_Fnode_Type is record -- Record type. Parent : O_Tnode; -- Next field in the record. Next : O_Fnode; -- Name of the record field. Ident : O_Ident; -- Type of the record field. Ftype : O_Tnode; -- Offset in the field. Offset : Unsigned_32; end record; type O_Anode_Type; type O_Anode is access O_Anode_Type; type O_Anode_Type is record Next : O_Anode; Formal : O_Dnode; Actual : O_Enode; end record; type OC_Kind is ( OC_Boolean_Lit, OC_Unsigned_Lit, OC_Signed_Lit, OC_Float_Lit, OC_Enum_Lit, OC_Null_Lit, OC_Sizeof_Lit, OC_Alignof_Lit, OC_Offsetof_Lit, OC_Default_Lit, OC_Aggregate, OC_Aggr_Element, OC_Union_Aggr, OC_Address, OC_Unchecked_Address, OC_Subprogram_Address ); type O_Cnode_Type (Kind : OC_Kind) is record -- Type of the constant. Ctype : O_Tnode; -- True if referenced. Ref : Boolean; case Kind is when OC_Unsigned_Lit => U_Val : Unsigned_64; when OC_Signed_Lit => S_Val : Integer_64; when OC_Float_Lit => F_Val : IEEE_Float_64; when OC_Boolean_Lit => B_Val : Boolean; B_Id : O_Ident; when OC_Enum_Lit => E_Val : Integer; E_Next : O_Cnode; E_Name : O_Ident; when OC_Null_Lit => null; when OC_Default_Lit => null; when OC_Sizeof_Lit | OC_Alignof_Lit => S_Type : O_Tnode; when OC_Offsetof_Lit => Off_Field : O_Fnode; when OC_Aggregate => Aggr_Els : O_Cnode; when OC_Union_Aggr => Uaggr_Field : O_Fnode; Uaggr_Value : O_Cnode; when OC_Aggr_Element => Aggr_Value : O_Cnode; Aggr_Next : O_Cnode; when OC_Address | OC_Unchecked_Address | OC_Subprogram_Address => Decl : O_Dnode; end case; end record; type O_Cnode is access O_Cnode_Type; O_Cnode_Null : constant O_Cnode := null; type OE_Kind is ( -- Literals. OE_Lit, -- Dyadic operations. OE_Add_Ov, -- OE_Dyadic_Op_Kind OE_Sub_Ov, -- OE_Dyadic_Op_Kind OE_Mul_Ov, -- OE_Dyadic_Op_Kind OE_Div_Ov, -- OE_Dyadic_Op_Kind OE_Rem_Ov, -- OE_Dyadic_Op_Kind OE_Mod_Ov, -- OE_Dyadic_Op_Kind OE_Exp_Ov, -- OE_Dyadic_Op_Kind -- Binary operations. OE_And, -- OE_Dyadic_Op_Kind OE_Or, -- OE_Dyadic_Op_Kind OE_Xor, -- OE_Dyadic_Op_Kind -- Monadic operations. OE_Not, -- OE_Monadic_Op_Kind OE_Neg_Ov, -- OE_Monadic_Op_Kind OE_Abs_Ov, -- OE_Monadic_Op_Kind -- Comparaisons OE_Eq, -- OE_Compare_Op_Kind OE_Neq, -- OE_Compare_Op_Kind OE_Le, -- OE_Compare_Op_Kind OE_Lt, -- OE_Compare_Op_Kind OE_Ge, -- OE_Compare_Op_Kind OE_Gt, -- OE_Compare_Op_Kind -- Misc. OE_Convert_Ov, OE_Address, OE_Unchecked_Address, OE_Alloca, OE_Function_Call, OE_Value, OE_Nil ); subtype OE_Dyadic_Expr_Kind is OE_Kind range OE_Add_Ov .. OE_Xor; subtype OE_Monadic_Expr_Kind is OE_Kind range OE_Not .. OE_Abs_Ov; subtype OE_Compare_Expr_Kind is OE_Kind range OE_Eq .. OE_Gt; type O_Enode_Type (Kind : OE_Kind); type O_Enode is access O_Enode_Type; O_Enode_Null : constant O_Enode := null; type O_Enode_Type (Kind : OE_Kind) is record -- Type of the result. Rtype : O_Tnode; -- True if referenced. Ref : Boolean; case Kind is when OE_Dyadic_Expr_Kind | OE_Compare_Expr_Kind => Left : O_Enode; Right : O_Enode; when OE_Monadic_Expr_Kind => Operand : O_Enode; when OE_Lit => Lit : O_Cnode; when OE_Address | OE_Unchecked_Address => Lvalue : O_Lnode; when OE_Convert_Ov => Conv : O_Enode; when OE_Function_Call => Func : O_Dnode; Assoc : O_Anode; when OE_Value => Value : O_Lnode; when OE_Alloca => A_Size : O_Enode; when OE_Nil => null; end case; end record; type O_Enode_Array is array (Natural range <>) of O_Enode; type O_Enode_Array_Acc is access O_Enode_Array; type OL_Kind is ( -- Name. OL_Obj, OL_Indexed_Element, OL_Slice, OL_Selected_Element, OL_Access_Element -- Variable, constant, parameter reference. -- This allows to read/write a declaration. --OL_Var_Ref, --OL_Const_Ref, --OL_Param_Ref ); type O_Lnode_Type (Kind : OL_Kind); type O_Lnode is access O_Lnode_Type; O_Lnode_Null : constant O_Lnode := null; type O_Lnode_Type (Kind : OL_Kind) is record -- Type of the result. Rtype : O_Tnode; -- True if referenced. Ref : Boolean; case Kind is when OL_Obj => Obj : O_Dnode; when OL_Indexed_Element => Array_Base : O_Lnode; Index : O_Enode; when OL_Slice => Slice_Base : O_Lnode; Slice_Index : O_Enode; when OL_Selected_Element => Rec_Base : O_Lnode; Rec_El : O_Fnode; when OL_Access_Element => Acc_Base : O_Enode; -- when OL_Var_Ref -- | OL_Const_Ref -- | OL_Param_Ref => -- Decl : O_Dnode; end case; end record; O_Tnode_Null : constant O_Tnode := null; type ON_Type_Kind is (ON_Boolean_Type, ON_Enum_Type, ON_Unsigned_Type, ON_Signed_Type, ON_Float_Type, ON_Array_Type, ON_Array_Sub_Type, ON_Record_Type, ON_Union_Type, ON_Access_Type); type O_Tnode_Type (Kind : ON_Type_Kind) is record Decl : O_Dnode; -- True if the type was first created as an uncomplete type. Uncomplete : Boolean; -- True if the type is complete. Complete : Boolean; case Kind is when ON_Boolean_Type => True_N : O_Cnode; False_N : O_Cnode; when ON_Unsigned_Type | ON_Signed_Type => Int_Size : Natural; when ON_Float_Type => null; when ON_Enum_Type => Nbr : Natural; Literals: O_Cnode; when ON_Array_Type => El_Type : O_Tnode; Index_Type : O_Tnode; when ON_Access_Type => D_Type : O_Tnode; when ON_Record_Type | ON_Union_Type => Elements : O_Fnode; when ON_Array_Sub_Type => Length : O_Cnode; Base_Type : O_Tnode; end case; end record; type ON_Choice_Kind is (ON_Choice_Expr, ON_Choice_Range, ON_Choice_Default); type O_Choice_Type (Kind : ON_Choice_Kind); type O_Choice is access O_Choice_Type; type O_Choice_Type (Kind : ON_Choice_Kind) is record Next : O_Choice; case Kind is when ON_Choice_Expr => Expr : O_Cnode; when ON_Choice_Range => Low, High : O_Cnode; when ON_Choice_Default => null; end case; end record; O_Snode_Null : constant O_Snode := null; type ON_Stmt_Kind is (ON_Declare_Stmt, ON_Assign_Stmt, ON_Return_Stmt, ON_If_Stmt, ON_Elsif_Stmt, ON_Loop_Stmt, ON_Exit_Stmt, ON_Next_Stmt, ON_Case_Stmt, ON_When_Stmt, ON_Call_Stmt, ON_Debug_Line_Stmt, ON_Debug_Comment_Stmt); type O_Snode_Type (Kind : ON_Stmt_Kind) is record Next : O_Snode; Lineno : Natural; case Kind is when ON_Declare_Stmt => Decls : O_Dnode; Stmts : O_Snode; -- True if the statement is currently open. Alive : Boolean; when ON_Assign_Stmt => Target : O_Lnode; Value : O_Enode; when ON_Return_Stmt => Ret_Val : O_Enode; when ON_If_Stmt => Elsifs : O_Snode; If_Last : O_Snode; when ON_Elsif_Stmt => Cond : O_Enode; Next_Elsif : O_Snode; when ON_Loop_Stmt => Loop_Last : O_Snode; Loop_Level : Natural; when ON_Exit_Stmt | ON_Next_Stmt => Loop_Id : O_Snode; when ON_Case_Stmt => Selector : O_Enode; -- Simply linked list of branches Branches : O_Snode; Case_Last : O_Snode; when ON_When_Stmt => -- The corresponding 'case' Branch_Parent : O_Snode; Choice_List : O_Choice; Next_Branch : O_Snode; when ON_Call_Stmt => Proc : O_Dnode; Assoc : O_Anode; when ON_Debug_Line_Stmt => Line : Natural; when ON_Debug_Comment_Stmt => Comment : Str_Acc; end case; end record; type O_Inter_List is record Func : O_Dnode; Last : O_Dnode; end record; type O_Element_List is record -- The type definition. Res : O_Tnode; -- The last element added. Last : O_Fnode; end record; type O_Record_Aggr_List is record Res : O_Cnode; Last : O_Cnode; Field : O_Fnode; end record; type O_Array_Aggr_List is record Res : O_Cnode; Last : O_Cnode; El_Type : O_Tnode; end record; type O_Assoc_List is record Subprg : O_Dnode; Interfaces : O_Dnode; First, Last : O_Anode; end record; type O_Enum_List is record -- The type built. Res : O_Tnode; -- the chain of declarations. Last : O_Cnode; end record; type O_Case_Block is record Case_Stmt : O_Snode; end record; type O_If_Block is record null; end record; end Ortho_Debug;