-- Common operations on nodes. -- Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold -- -- This program 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 of the License, or -- (at your option) any later version. -- -- This program 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 this program. If not, see . with Name_Table; with Str_Table; with Std_Names; use Std_Names; with Flags; with Files_Map; with Vhdl.Std_Package; with Vhdl.Errors; use Vhdl.Errors; with PSL.Nodes; package body Vhdl.Utils is function Is_Error (N : Iir) return Boolean is begin return Get_Kind (N) = Iir_Kind_Error; end Is_Error; function Is_Overflow_Literal (N : Iir) return Boolean is begin return Get_Kind (N) = Iir_Kind_Overflow_Literal; end Is_Overflow_Literal; function Strip_Literal_Origin (N : Iir) return Iir is Orig : Iir; begin if N = Null_Iir then return N; end if; case Get_Kind (N) is when Iir_Kind_String_Literal8 | Iir_Kind_Integer_Literal | Iir_Kind_Floating_Point_Literal | Iir_Kind_Physical_Int_Literal | Iir_Kind_Physical_Fp_Literal | Iir_Kind_Simple_Aggregate | Iir_Kind_Overflow_Literal | Iir_Kind_Enumeration_Literal | Iir_Kind_Aggregate => Orig := Get_Literal_Origin (N); if Orig /= Null_Iir then return Orig; else return N; end if; when others => return N; end case; end Strip_Literal_Origin; function List_To_Flist (L : Iir_List) return Iir_Flist is Len : constant Natural := Get_Nbr_Elements (L); It : List_Iterator; Temp_L : Iir_List; Res : Iir_Flist; begin Res := Create_Iir_Flist (Len); It := List_Iterate (L); for I in 0 .. Len - 1 loop pragma Assert (Is_Valid (It)); Set_Nth_Element (Res, I, Get_Element (It)); Next (It); end loop; pragma Assert (not Is_Valid (It)); Temp_L := L; Destroy_Iir_List (Temp_L); return Res; end List_To_Flist; function Truncate_Flist (L : Iir_Flist; Len : Natural) return Iir_Flist is Res : Iir_Flist; Temp_L : Iir_Flist; begin Res := Create_Iir_Flist (Len); for I in 0 .. Len - 1 loop Set_Nth_Element (Res, I, Get_Nth_Element (L, I)); end loop; Temp_L := L; Destroy_Iir_Flist (Temp_L); return Res; end Truncate_Flist; function Get_Operator_Name (Op : Iir) return Name_Id is begin case Get_Kind (Op) is when Iir_Kind_And_Operator | Iir_Kind_Reduction_And_Operator => return Name_And; when Iir_Kind_Or_Operator | Iir_Kind_Reduction_Or_Operator => return Name_Or; when Iir_Kind_Nand_Operator | Iir_Kind_Reduction_Nand_Operator => return Name_Nand; when Iir_Kind_Nor_Operator | Iir_Kind_Reduction_Nor_Operator => return Name_Nor; when Iir_Kind_Xor_Operator | Iir_Kind_Reduction_Xor_Operator => return Name_Xor; when Iir_Kind_Xnor_Operator | Iir_Kind_Reduction_Xnor_Operator => return Name_Xnor; when Iir_Kind_Equality_Operator => return Name_Op_Equality; when Iir_Kind_Inequality_Operator => return Name_Op_Inequality; when Iir_Kind_Less_Than_Operator => return Name_Op_Less; when Iir_Kind_Less_Than_Or_Equal_Operator => return Name_Op_Less_Equal; when Iir_Kind_Greater_Than_Operator => return Name_Op_Greater; when Iir_Kind_Greater_Than_Or_Equal_Operator => return Name_Op_Greater_Equal; when Iir_Kind_Match_Equality_Operator => return Name_Op_Match_Equality; when Iir_Kind_Match_Inequality_Operator => return Name_Op_Match_Inequality; when Iir_Kind_Match_Less_Than_Operator => return Name_Op_Match_Less; when Iir_Kind_Match_Less_Than_Or_Equal_Operator => return Name_Op_Match_Less_Equal; when Iir_Kind_Match_Greater_Than_Operator => return Name_Op_Match_Greater; when Iir_Kind_Match_Greater_Than_Or_Equal_Operator => return Name_Op_Match_Greater_Equal; when Iir_Kind_Sll_Operator => return Name_Sll; when Iir_Kind_Sla_Operator => return Name_Sla; when Iir_Kind_Srl_Operator => return Name_Srl; when Iir_Kind_Sra_Operator => return Name_Sra; when Iir_Kind_Rol_Operator => return Name_Rol; when Iir_Kind_Ror_Operator => return Name_Ror; when Iir_Kind_Addition_Operator => return Name_Op_Plus; when Iir_Kind_Substraction_Operator => return Name_Op_Minus; when Iir_Kind_Concatenation_Operator => return Name_Op_Concatenation; when Iir_Kind_Multiplication_Operator => return Name_Op_Mul; when Iir_Kind_Division_Operator => return Name_Op_Div; when Iir_Kind_Modulus_Operator => return Name_Mod; when Iir_Kind_Remainder_Operator => return Name_Rem; when Iir_Kind_Exponentiation_Operator => return Name_Op_Exp; when Iir_Kind_Not_Operator => return Name_Not; when Iir_Kind_Negation_Operator => return Name_Op_Minus; when Iir_Kind_Identity_Operator => return Name_Op_Plus; when Iir_Kind_Absolute_Operator => return Name_Abs; when Iir_Kind_Condition_Operator | Iir_Kind_Implicit_Condition_Operator => return Name_Op_Condition; when others => raise Internal_Error; end case; end Get_Operator_Name; function Get_Longest_Static_Prefix (Expr: Iir) return Iir is Adecl: Iir; begin Adecl := Expr; loop case Get_Kind (Adecl) is when Iir_Kind_Variable_Declaration | Iir_Kind_Interface_Variable_Declaration => return Adecl; when Iir_Kind_Constant_Declaration | Iir_Kind_Interface_Constant_Declaration => return Adecl; when Iir_Kind_Signal_Declaration | Iir_Kind_Guard_Signal_Declaration | Iir_Kind_Interface_Signal_Declaration => return Adecl; when Iir_Kind_Object_Alias_Declaration => -- LRM 4.3.3.1 Object Aliases -- 2. The name must be a static name [...] return Adecl; when Iir_Kind_Slice_Name | Iir_Kind_Indexed_Name | Iir_Kind_Selected_Element => if Get_Name_Staticness (Adecl) >= Globally then return Adecl; else Adecl := Get_Prefix (Adecl); end if; when Iir_Kind_Simple_Name | Iir_Kind_Selected_Name => Adecl := Get_Named_Entity (Adecl); when Iir_Kind_Type_Conversion => return Null_Iir; when others => Error_Kind ("get_longest_static_prefix", Adecl); end case; end loop; end Get_Longest_Static_Prefix; function Get_Object_Prefix (Name: Iir; With_Alias : Boolean := True) return Iir is Adecl : Iir; begin Adecl := Name; loop case Get_Kind (Adecl) is when Iir_Kinds_Non_Alias_Object_Declaration | Iir_Kinds_Quantity_Declaration | Iir_Kind_Terminal_Declaration | Iir_Kind_Interface_Quantity_Declaration | Iir_Kind_Interface_Terminal_Declaration | Iir_Kind_Interface_Type_Declaration | Iir_Kind_Interface_Package_Declaration | Iir_Kind_Interface_Function_Declaration | Iir_Kind_Interface_Procedure_Declaration | Iir_Kind_External_Signal_Name | Iir_Kind_External_Constant_Name | Iir_Kind_External_Variable_Name => return Adecl; when Iir_Kind_Object_Alias_Declaration => if With_Alias then Adecl := Get_Name (Adecl); else return Adecl; end if; when Iir_Kind_Indexed_Name | Iir_Kind_Slice_Name | Iir_Kind_Selected_Element | Iir_Kind_Selected_By_All_Name => Adecl := Get_Base_Name (Adecl); when Iir_Kinds_Literal | Iir_Kind_Overflow_Literal | Iir_Kind_Enumeration_Literal | Iir_Kinds_Monadic_Operator | Iir_Kinds_Dyadic_Operator | Iir_Kind_Function_Call | Iir_Kind_Qualified_Expression | Iir_Kind_Type_Conversion | Iir_Kind_Allocator_By_Expression | Iir_Kind_Allocator_By_Subtype | Iir_Kind_Parenthesis_Expression | Iir_Kinds_Attribute | Iir_Kind_Attribute_Value | Iir_Kind_Aggregate | Iir_Kind_Simple_Aggregate | Iir_Kind_Dereference | Iir_Kind_Implicit_Dereference | Iir_Kind_Unit_Declaration | Iir_Kind_Psl_Expression | Iir_Kinds_Concurrent_Statement | Iir_Kinds_Sequential_Statement | Iir_Kinds_Simultaneous_Statement | Iir_Kind_Suspend_State_Statement => return Adecl; when Iir_Kind_Simple_Name | Iir_Kind_Selected_Name => Adecl := Get_Named_Entity (Adecl); when Iir_Kind_Attribute_Name => return Get_Named_Entity (Adecl); when Iir_Kind_Error | Iir_Kind_Unused | Iir_Kind_Parenthesis_Name | Iir_Kind_Conditional_Expression | Iir_Kind_Character_Literal | Iir_Kind_Operator_Symbol | Iir_Kind_Design_File | Iir_Kind_Design_Unit | Iir_Kind_Library_Clause | Iir_Kind_Use_Clause | Iir_Kind_Context_Reference | Iir_Kind_PSL_Inherit_Spec | Iir_Kind_Library_Declaration | Iir_Kinds_Library_Unit | Iir_Kind_Component_Declaration | Iir_Kind_Function_Declaration | Iir_Kind_Procedure_Declaration | Iir_Kind_Function_Instantiation_Declaration | Iir_Kind_Procedure_Instantiation_Declaration | Iir_Kind_Attribute_Declaration | Iir_Kind_Nature_Declaration | Iir_Kind_Subnature_Declaration | Iir_Kinds_Type_Declaration | Iir_Kinds_Type_And_Subtype_Definition | Iir_Kind_Foreign_Vector_Type_Definition | Iir_Kinds_Nature_Definition | Iir_Kinds_Subnature_Definition | Iir_Kind_Wildcard_Type_Definition | Iir_Kind_Subtype_Definition | Iir_Kind_Group_Template_Declaration | Iir_Kind_Group_Declaration | Iir_Kind_Attribute_Implicit_Declaration | Iir_Kind_Suspend_State_Declaration | Iir_Kind_Unaffected_Waveform | Iir_Kind_Waveform_Element | Iir_Kind_Conditional_Waveform | Iir_Kind_Binding_Indication | Iir_Kind_Component_Configuration | Iir_Kind_Block_Configuration | Iir_Kinds_Specification | Iir_Kind_Non_Object_Alias_Declaration | Iir_Kinds_Subprogram_Body | Iir_Kind_Protected_Type_Body | Iir_Kind_Generate_Statement_Body | Iir_Kind_Package_Instantiation_Body | Iir_Kind_Procedure_Call | Iir_Kind_Aggregate_Info | Iir_Kind_Entity_Class | Iir_Kind_Signature | Iir_Kind_Break_Element | Iir_Kind_Reference_Name | Iir_Kind_Package_Header | Iir_Kind_Block_Header | Iir_Kinds_Association_Element | Iir_Kinds_Choice | Iir_Kinds_Entity_Aspect | Iir_Kind_Psl_Hierarchical_Name | Iir_Kind_Psl_Prev | Iir_Kind_Psl_Stable | Iir_Kind_Psl_Rose | Iir_Kind_Psl_Fell | Iir_Kind_Psl_Onehot | Iir_Kind_Psl_Onehot0 | Iir_Kind_If_Generate_Else_Clause | Iir_Kind_Elsif | Iir_Kind_Simultaneous_Elsif | Iir_Kind_Record_Element_Constraint | Iir_Kind_Array_Element_Resolution | Iir_Kind_Record_Resolution | Iir_Kind_Record_Element_Resolution | Iir_Kind_Element_Declaration | Iir_Kind_Nature_Element_Declaration | Iir_Kind_Psl_Endpoint_Declaration | Iir_Kind_Psl_Boolean_Parameter | Iir_Kind_Psl_Declaration | Iir_Kind_Psl_Default_Clock | Iir_Kind_Package_Pathname | Iir_Kind_Absolute_Pathname | Iir_Kind_Relative_Pathname | Iir_Kind_Pathname_Element | Iir_Kind_Range_Expression | Iir_Kind_Overload_List => return Adecl; end case; end loop; end Get_Object_Prefix; function Is_Object_Name (Name : Iir) return Boolean is Obj : constant Iir := Name_To_Object (Name); begin return Obj /= Null_Iir; end Is_Object_Name; function Name_To_Object (Name : Iir) return Iir is begin -- LRM08 6.4 Objects -- An object is a named entity that contains (has) a value of a type. -- An object is obe of the following: case Get_Kind (Name) is -- An object declared by an object declaration (see 6.4.2) when Iir_Kind_Signal_Declaration | Iir_Kind_Variable_Declaration | Iir_Kind_File_Declaration | Iir_Kind_Constant_Declaration | Iir_Kind_Free_Quantity_Declaration | Iir_Kind_Across_Quantity_Declaration | Iir_Kind_Through_Quantity_Declaration => return Name; -- A loop of generate parameter. when Iir_Kind_Iterator_Declaration => return Name; -- A formal parameter of a subprogram -- A formal port -- A formal generic constant -- A local port -- A local generic constant when Iir_Kind_Interface_Constant_Declaration | Iir_Kind_Interface_Variable_Declaration | Iir_Kind_Interface_Signal_Declaration | Iir_Kind_Interface_File_Declaration | Iir_Kind_Interface_Quantity_Declaration => return Name; -- An implicit signak GUARD defined by the guard expression of a -- block statement when Iir_Kind_Guard_Signal_Declaration => return Name; -- In addition, the following are objects [ but are not named -- entities]: -- An implicit signal defined by any of the predefined attributes -- 'DELAYED, 'STABLE, 'QUIET, and 'TRANSACTION when Iir_Kinds_Signal_Attribute => return Name; -- An element or a slice of another object when Iir_Kind_Slice_Name | Iir_Kind_Indexed_Name | Iir_Kind_Selected_Element => if Name_To_Object (Get_Prefix (Name)) = Null_Iir then -- The prefix may not be an object. return Null_Iir; end if; return Name; -- An object designated by a value of an access type when Iir_Kind_Implicit_Dereference | Iir_Kind_Dereference => return Name; -- LRM08 6.6 Alias declarations -- An object alias is an alias whose alias designatore denotes an -- object. when Iir_Kind_Object_Alias_Declaration => return Name; when Iir_Kind_Simple_Name | Iir_Kind_Selected_Name => -- LRM08 8 Names -- Names can denote declared entities [...] -- GHDL: in particular, names can denote objects. return Name_To_Object (Get_Named_Entity (Name)); when Iir_Kinds_External_Name => return Name; -- AMS-LRM17 6.4 Objects -- An implicit signal defined by any of the predefined attributes -- 'above, [...] when Iir_Kind_Above_Attribute => return Name; -- AMS-LRM17 6.4 Objects -- An implicit quantity defined by any of the predefined attributes -- 'DOT, 'INTEG, 'DELAYED, 'ZOH, 'LTF, 'ZTF, 'REFERENCE, -- 'CONTRIBUTION, 'RAMP, and 'SLEW. when Iir_Kind_Dot_Attribute | Iir_Kind_Integ_Attribute => return Name; when others => return Null_Iir; end case; end Name_To_Object; function Name_To_Value (Name : Iir) return Iir is begin case Get_Kind (Name) is when Iir_Kind_Attribute_Value | Iir_Kind_Function_Call | Iir_Kinds_Expression_Attribute => return Name; when Iir_Kind_Simple_Name | Iir_Kind_Selected_Name => return Name_To_Value (Get_Named_Entity (Name)); when Iir_Kind_Indexed_Name | Iir_Kind_Selected_Element | Iir_Kind_Slice_Name => -- Already a value. return Name; when others => return Name_To_Object (Name); end case; end Name_To_Value; -- Return TRUE if EXPR is a signal name. function Is_Signal_Name (Expr : Iir) return Boolean is Obj : Iir; begin Obj := Name_To_Object (Expr); if Obj /= Null_Iir then return Is_Signal_Object (Obj); else return False; end if; end Is_Signal_Name; function Is_Signal_Object (Name : Iir) return Boolean is Adecl: Iir; begin Adecl := Get_Object_Prefix (Name, True); case Get_Kind (Adecl) is when Iir_Kind_Signal_Declaration | Iir_Kind_Interface_Signal_Declaration | Iir_Kind_Guard_Signal_Declaration | Iir_Kinds_Signal_Attribute => return True; when Iir_Kind_Object_Alias_Declaration => -- Must have been handled by Get_Object_Prefix. raise Internal_Error; when others => return False; end case; end Is_Signal_Object; function Is_Quantity_Object (Name : Iir) return Boolean is Adecl: Iir; begin Adecl := Get_Object_Prefix (Name, True); case Get_Kind (Adecl) is when Iir_Kinds_Quantity_Declaration | Iir_Kind_Interface_Quantity_Declaration | Iir_Kind_Integ_Attribute | Iir_Kind_Dot_Attribute => return True; when Iir_Kind_Object_Alias_Declaration => -- Must have been handled by Get_Object_Prefix. raise Internal_Error; when others => return False; end case; end Is_Quantity_Object; function Is_Quantity_Name (Expr : Iir) return Boolean is Obj : Iir; begin Obj := Name_To_Object (Expr); if Obj /= Null_Iir then return Is_Quantity_Object (Obj); else return False; end if; end Is_Quantity_Name; function Is_Signal_Parameter (Obj : Iir) return Boolean is begin return Get_Kind (Obj) = Iir_Kind_Interface_Signal_Declaration and then Get_Kind (Get_Parent (Obj)) in Iir_Kinds_Subprogram_Declaration; end Is_Signal_Parameter; function Get_Interface_Of_Formal (Formal : Iir) return Iir is El : Iir; begin El := Formal; loop case Get_Kind (El) is when Iir_Kind_Simple_Name | Iir_Kind_Reference_Name | Iir_Kind_Operator_Symbol => -- Operator is for subprogram interfaces. return Get_Named_Entity (El); when Iir_Kinds_Interface_Declaration => return El; when Iir_Kind_Slice_Name | Iir_Kind_Indexed_Name | Iir_Kind_Selected_Element => -- FIXME: use get_base_name ? El := Get_Prefix (El); when others => Error_Kind ("get_interface_of_formal", El); end case; end loop; end Get_Interface_Of_Formal; function Get_Association_Interface (Assoc : Iir; Inter : Iir) return Iir is Formal : constant Iir := Get_Formal (Assoc); begin if Formal /= Null_Iir then return Get_Interface_Of_Formal (Formal); else return Inter; end if; end Get_Association_Interface; procedure Next_Association_Interface (Assoc : in out Iir; Inter : in out Iir) is Formal : Iir; begin -- In canon, open association can be inserted after an association by -- name. So do not assume there is no association by position after -- association by name. Assoc := Get_Chain (Assoc); if Assoc = Null_Iir then -- End of the chain Inter := Null_Iir; return; end if; Formal := Get_Formal (Assoc); if Is_Valid (Formal) then Inter := Get_Interface_Of_Formal (Formal); else Inter := Get_Chain (Inter); end if; -- If INTER is null, this is an extra association. Should it be -- skipped here ? Or add a _Safe variant ? end Next_Association_Interface; function Get_Association_Formal (Assoc : Iir; Inter : Iir) return Iir is Formal : constant Iir := Get_Formal (Assoc); begin if Formal /= Null_Iir then -- Strip denoting name case Get_Kind (Formal) is when Iir_Kind_Simple_Name | Iir_Kind_Reference_Name | Iir_Kind_Operator_Symbol => return Get_Named_Entity (Formal); when Iir_Kinds_Interface_Declaration => -- Shouldn't happen. raise Internal_Error; when Iir_Kind_Slice_Name | Iir_Kind_Indexed_Name | Iir_Kind_Selected_Element => return Formal; when others => Error_Kind ("get_association_formal", Formal); end case; else return Inter; end if; end Get_Association_Formal; function Find_First_Association_For_Interface (Assoc_Chain : Iir; Inter_Chain : Iir; Inter : Iir) return Iir is Assoc_El : Iir; Inter_El : Iir; begin Assoc_El := Assoc_Chain; Inter_El := Inter_Chain; while Is_Valid (Assoc_El) loop if Get_Association_Interface (Assoc_El, Inter_El) = Inter then return Assoc_El; end if; Next_Association_Interface (Assoc_El, Inter_El); end loop; return Null_Iir; end Find_First_Association_For_Interface; function Is_Parameter (Inter : Iir) return Boolean is begin case Get_Kind (Get_Parent (Inter)) is when Iir_Kinds_Subprogram_Declaration | Iir_Kinds_Interface_Subprogram_Declaration => return True; when others => -- Port return False; end case; end Is_Parameter; function Is_Copyback_Parameter (Inter : Iir) return Boolean is begin if Get_Kind (Inter) = Iir_Kind_Interface_Variable_Declaration and then Get_Mode (Inter) in Iir_Out_Mode .. Iir_Inout_Mode then -- For Vhdl-87, files are not copyback. return Get_Kind (Get_Type (Inter)) /= Iir_Kind_File_Type_Definition; else return False; end if; end Is_Copyback_Parameter; procedure Set_Interface_Associated (Inter_Chain : Iir; Assoc_Chain : Iir) is Inter, Assoc_Inter, Assoc : Iir; begin Assoc := Assoc_Chain; Assoc_Inter := Inter_Chain; while Assoc /= Null_Node loop Inter := Get_Association_Interface (Assoc, Assoc_Inter); case Iir_Kinds_Interface_Declaration (Get_Kind (Inter)) is when Iir_Kind_Interface_Type_Declaration => declare Tdef : constant Iir := Get_Interface_Type_Definition (Inter); begin pragma Assert (Get_Associated_Type (Tdef) = Null_Iir); Set_Associated_Type (Tdef, Get_Actual_Type (Assoc)); end; -- TODO: subprograms ? when Iir_Kind_Interface_Package_Declaration => pragma Assert (Get_Associated_Package (Inter) = Null_Iir); Set_Associated_Package (Inter, Get_Named_Entity (Get_Actual (Assoc))); when Iir_Kinds_Interface_Subprogram_Declaration => pragma Assert (Get_Associated_Subprogram (Inter) = Null_Iir); Set_Associated_Subprogram (Inter, Get_Named_Entity (Get_Actual (Assoc))); when Iir_Kinds_Interface_Object_Declaration | Iir_Kind_Interface_Terminal_Declaration => null; end case; Next_Association_Interface (Assoc, Assoc_Inter); end loop; end Set_Interface_Associated; procedure Clear_Interface_Associated (Inter_Chain : Iir) is Inter : Iir; begin Inter := Inter_Chain; while Inter /= Null_Node loop case Iir_Kinds_Interface_Declaration (Get_Kind (Inter)) is when Iir_Kind_Interface_Type_Declaration => declare Tdef : constant Iir := Get_Interface_Type_Definition (Inter); begin Set_Associated_Type (Tdef, Null_Iir); end; -- TODO: subprograms ? when Iir_Kind_Interface_Package_Declaration => Set_Associated_Package (Inter, Null_Iir); when Iir_Kinds_Interface_Subprogram_Declaration => Set_Associated_Subprogram (Inter, Null_Iir); when Iir_Kinds_Interface_Object_Declaration | Iir_Kind_Interface_Terminal_Declaration => null; end case; Inter := Get_Chain (Inter); end loop; end Clear_Interface_Associated; function Find_Name_In_Flist (List : Iir_Flist; Lit : Name_Id) return Iir is El : Iir; begin for I in Flist_First .. Flist_Last (List) loop El := Get_Nth_Element (List, I); if Get_Identifier (El) = Lit then return El; end if; end loop; return Null_Iir; end Find_Name_In_Flist; function Find_Name_In_Chain (Chain: Iir; Lit: Name_Id) return Iir is El: Iir := Chain; begin while El /= Null_Iir loop if Get_Identifier (El) = Lit then return El; end if; El := Get_Chain (El); end loop; return Null_Iir; end Find_Name_In_Chain; function Is_In_Chain (Chain : Iir; El : Iir) return Boolean is Chain_El : Iir; begin Chain_El := Chain; while Chain_El /= Null_Iir loop if Chain_El = El then return True; end if; Chain_El := Get_Chain (Chain_El); end loop; return False; end Is_In_Chain; procedure Add_Dependence (Target: Iir_Design_Unit; Unit: Iir) is begin -- Do not add self-dependency if Unit = Target then return; end if; pragma Assert (Kind_In (Unit, Iir_Kind_Design_Unit, Iir_Kind_Foreign_Module, Iir_Kind_Entity_Aspect_Entity)); Add_Element (Get_Dependence_List (Target), Unit); end Add_Dependence; function Get_Unit_From_Dependence (Dep : Iir) return Iir is begin case Get_Kind (Dep) is when Iir_Kind_Design_Unit => return Dep; when Iir_Kind_Entity_Aspect_Entity => return Get_Design_Unit (Get_Entity (Dep)); when others => Error_Kind ("get_unit_from_dependence", Dep); end case; end Get_Unit_From_Dependence; procedure Clear_Instantiation_Configuration (Parent : Iir) is El : Iir; begin El := Get_Concurrent_Statement_Chain (Parent); while El /= Null_Iir loop case Get_Kind (El) is when Iir_Kind_Component_Instantiation_Statement => Set_Component_Configuration (El, Null_Iir); when Iir_Kind_For_Generate_Statement => declare Bod : constant Iir := Get_Generate_Statement_Body (El); begin Set_Generate_Block_Configuration (Bod, Null_Iir); end; when Iir_Kind_If_Generate_Statement => declare Clause : Iir; Bod : Iir; begin Clause := El; while Clause /= Null_Iir loop Bod := Get_Generate_Statement_Body (Clause); Set_Generate_Block_Configuration (Bod, Null_Iir); Clause := Get_Generate_Else_Clause (Clause); end loop; end; when Iir_Kind_Block_Statement => Set_Block_Block_Configuration (El, Null_Iir); when others => null; end case; El := Get_Chain (El); end loop; end Clear_Instantiation_Configuration; -- Get identifier of NODE as a string. function Image_Identifier (Node : Iir) return String is begin return Name_Table.Image (Vhdl.Nodes.Get_Identifier (Node)); end Image_Identifier; function Image_String_Lit (Str : Iir) return String is begin return Str_Table.String_String8 (Get_String8_Id (Str), Get_String_Length (Str)); end Image_String_Lit; function Copy_Enumeration_Literal (Lit : Iir) return Iir is Res : Iir; begin Res := Create_Iir (Iir_Kind_Enumeration_Literal); Set_Identifier (Res, Get_Identifier (Lit)); Location_Copy (Res, Lit); Set_Parent (Res, Get_Parent (Lit)); Set_Type (Res, Get_Type (Lit)); Set_Enum_Pos (Res, Get_Enum_Pos (Lit)); Set_Expr_Staticness (Res, Locally); return Res; end Copy_Enumeration_Literal; procedure Create_Range_Constraint_For_Enumeration_Type (Def : Iir_Enumeration_Type_Definition) is Range_Expr : Iir_Range_Expression; Literal_List : constant Iir_Flist := Get_Enumeration_Literal_List (Def); List_Len : constant Natural := Get_Nbr_Elements (Literal_List); begin -- Create a constraint. Range_Expr := Create_Iir (Iir_Kind_Range_Expression); Location_Copy (Range_Expr, Def); Set_Type (Range_Expr, Def); Set_Direction (Range_Expr, Dir_To); if List_Len >= 1 then Set_Left_Limit (Range_Expr, Get_Nth_Element (Literal_List, 0)); Set_Right_Limit (Range_Expr, Get_Nth_Element (Literal_List, List_Len - 1)); end if; Set_Expr_Staticness (Range_Expr, Locally); Set_Range_Constraint (Def, Range_Expr); end Create_Range_Constraint_For_Enumeration_Type; function Is_Static_Construct (Expr : Iir) return Boolean is begin case Get_Kind (Expr) is when Iir_Kind_Aggregate => return Get_Aggregate_Expand_Flag (Expr); when Iir_Kinds_Literal => return True; when Iir_Kind_Simple_Aggregate | Iir_Kind_Enumeration_Literal | Iir_Kind_Character_Literal => return True; when Iir_Kind_Overflow_Literal => -- Needs to generate an error. return False; when others => return False; end case; end Is_Static_Construct; procedure Free_Name (Node : Iir) is N : Iir; N1 : Iir; begin if Node = Null_Iir then return; end if; N := Node; case Get_Kind (N) is when Iir_Kind_Simple_Name | Iir_Kind_Character_Literal | Iir_Kind_String_Literal8 | Iir_Kind_Subtype_Definition => Free_Iir (N); when Iir_Kind_Selected_Name | Iir_Kind_Parenthesis_Name | Iir_Kind_Selected_By_All_Name => N1 := Get_Prefix (N); Free_Iir (N); Free_Name (N1); when Iir_Kind_Library_Declaration | Iir_Kind_Package_Declaration | Iir_Kind_Entity_Declaration | Iir_Kind_Architecture_Body | Iir_Kind_Design_Unit | Iir_Kinds_Concurrent_Statement | Iir_Kinds_Sequential_Statement => return; when others => Error_Kind ("free_name", Node); --Free_Iir (N); end case; end Free_Name; procedure Free_Recursive_List (List : Iir_List) is It : List_Iterator; begin It := List_Iterate (List); while Is_Valid (It) loop Free_Recursive (Get_Element (It)); Next (It); end loop; end Free_Recursive_List; procedure Free_Recursive_Flist (List : Iir_Flist) is El : Iir; begin for I in Flist_First .. Flist_Last (List) loop El := Get_Nth_Element (List, I); Free_Recursive (El); end loop; end Free_Recursive_Flist; procedure Free_Recursive (Node : Iir; Free_List : Boolean := False) is N : Iir; begin if Node = Null_Iir then return; end if; N := Node; case Get_Kind (N) is when Iir_Kind_Library_Declaration => return; when Iir_Kind_Simple_Name | Iir_Kind_Parenthesis_Name | Iir_Kind_Character_Literal => null; when Iir_Kind_Enumeration_Literal => return; when Iir_Kind_Selected_Name => Free_Recursive (Get_Prefix (N)); when Iir_Kind_Interface_Constant_Declaration | Iir_Kind_Interface_Variable_Declaration | Iir_Kind_Interface_Signal_Declaration => Free_Recursive (Get_Type (N)); Free_Recursive (Get_Default_Value (N)); when Iir_Kind_Range_Expression => Free_Recursive (Get_Left_Limit (N)); Free_Recursive (Get_Right_Limit (N)); when Iir_Kind_Subtype_Definition => Free_Recursive (Get_Base_Type (N)); when Iir_Kind_Integer_Literal => null; when Iir_Kind_Package_Declaration | Iir_Kind_Package_Body | Iir_Kind_Entity_Declaration | Iir_Kind_Configuration_Declaration | Iir_Kind_Context_Declaration => null; when Iir_Kind_File_Type_Definition | Iir_Kind_Access_Type_Definition | Iir_Kind_Array_Type_Definition | Iir_Kind_Enumeration_Type_Definition | Iir_Kind_Integer_Subtype_Definition | Iir_Kind_Enumeration_Subtype_Definition | Iir_Kind_Physical_Subtype_Definition => return; when Iir_Kind_Architecture_Body => Free_Recursive (Get_Entity_Name (N)); when Iir_Kind_Overload_List => Free_Recursive_List (Get_Overload_List (N)); if not Free_List then return; end if; when Iir_Kind_Array_Subtype_Definition => Free_Recursive_Flist (Get_Index_List (N)); Free_Recursive (Get_Base_Type (N)); when Iir_Kind_Entity_Aspect_Entity => Free_Recursive (Get_Entity_Name (N)); Free_Recursive (Get_Architecture (N)); when others => Error_Kind ("free_recursive", Node); end case; Free_Iir (N); end Free_Recursive; function Get_Predefined_Function_Name (Func : Iir_Predefined_Functions) return String is begin return Iir_Predefined_Functions'Image (Func); end Get_Predefined_Function_Name; function Get_Callees_List_Holder (Subprg : Iir) return Iir is begin case Get_Kind (Subprg) is when Iir_Kind_Procedure_Declaration | Iir_Kind_Function_Declaration => return Get_Subprogram_Body (Subprg); when Iir_Kind_Sensitized_Process_Statement | Iir_Kind_Process_Statement => return Subprg; when others => Error_Kind ("get_callees_list_holder", Subprg); end case; end Get_Callees_List_Holder; procedure Clear_Seen_Flag (Top : Iir) is Callees_List : Iir_Callees_List; It : List_Iterator; El: Iir; begin if Get_Seen_Flag (Top) then Set_Seen_Flag (Top, False); Callees_List := Get_Callees_List (Get_Callees_List_Holder (Top)); if Callees_List /= Null_Iir_List then It := List_Iterate (Callees_List); while Is_Valid (It) loop El := Get_Element (It); if Get_Seen_Flag (El) = False then Clear_Seen_Flag (El); end if; Next (It); end loop; end if; end if; end Clear_Seen_Flag; function Get_Base_Type (Atype : Iir) return Iir is Res : Iir; begin Res := Atype; loop case Get_Kind (Res) is when Iir_Kind_Access_Type_Definition | Iir_Kind_Integer_Type_Definition | Iir_Kind_Floating_Type_Definition | Iir_Kind_Enumeration_Type_Definition | Iir_Kind_Physical_Type_Definition | Iir_Kind_Array_Type_Definition | Iir_Kind_Record_Type_Definition | Iir_Kind_Protected_Type_Declaration | Iir_Kind_File_Type_Definition | Iir_Kind_Incomplete_Type_Definition | Iir_Kind_Interface_Type_Definition | Iir_Kind_Wildcard_Type_Definition | Iir_Kind_Foreign_Vector_Type_Definition | Iir_Kind_Error => return Res; when Iir_Kind_Access_Subtype_Definition | Iir_Kind_File_Subtype_Definition | Iir_Kind_Integer_Subtype_Definition | Iir_Kind_Floating_Subtype_Definition | Iir_Kind_Enumeration_Subtype_Definition | Iir_Kind_Physical_Subtype_Definition | Iir_Kind_Array_Subtype_Definition | Iir_Kind_Record_Subtype_Definition => Res := Get_Parent_Type (Res); when others => Error_Kind ("get_base_type", Res); end case; end loop; end Get_Base_Type; function Is_Anonymous_Type_Definition (Def : Iir) return Boolean is begin return Get_Type_Declarator (Def) = Null_Iir; end Is_Anonymous_Type_Definition; function Is_Array_Type (Def : Iir) return Boolean is begin return Get_Kind (Def) in Iir_Kinds_Array_Type_Definition; end Is_Array_Type; function Is_Fully_Constrained_Type (Def : Iir) return Boolean is begin return Get_Kind (Def) not in Iir_Kinds_Composite_Type_Definition or else Get_Constraint_State (Def) = Fully_Constrained; end Is_Fully_Constrained_Type; function Is_Object_Fully_Constrained (Decl : Iir) return Boolean is begin -- That's true if the object type is constrained. if Is_Fully_Constrained_Type (Get_Type (Decl)) then return True; end if; -- That's also true if the object is declared with a subtype attribute. if Get_Kind (Get_Subtype_Indication (Decl)) = Iir_Kind_Subtype_Attribute then return True; end if; -- Otherwise this is false. return False; end Is_Object_Fully_Constrained; function Is_Object_Name_Fully_Constrained (Obj : Iir) return Boolean is Base : Iir; begin -- That's true if the object type is constrained. if Flags.Flag_Relaxed_Rules or else Is_Fully_Constrained_Type (Get_Type (Obj)) then return True; end if; -- That's also true if the object is declared with a subtype attribute. Base := Get_Base_Name (Obj); case Get_Kind (Base) is when Iir_Kind_Variable_Declaration | Iir_Kind_Signal_Declaration | Iir_Kind_Interface_Variable_Declaration | Iir_Kind_Interface_Signal_Declaration | Iir_Kind_Object_Alias_Declaration => declare Ind : constant Iir := Get_Subtype_Indication (Base); begin -- Note: an object alias may not have subtype indication. if Ind /= Null_Iir and then Get_Kind (Ind) = Iir_Kind_Subtype_Attribute then return True; end if; end; when Iir_Kind_Dereference | Iir_Kind_Implicit_Dereference => null; when others => Error_Kind ("is_object_name_fully_constrained", Base); end case; -- Otherwise this is false. return False; end Is_Object_Name_Fully_Constrained; function Strip_Denoting_Name (Name : Iir) return Iir is begin if Get_Kind (Name) in Iir_Kinds_Denoting_Name then return Get_Named_Entity (Name); else return Name; end if; end Strip_Denoting_Name; function Build_Simple_Name (Ref : Iir; Loc : Location_Type) return Iir is Res : Iir; begin Res := Create_Iir (Iir_Kind_Simple_Name); Set_Location (Res, Loc); Set_Identifier (Res, Get_Identifier (Ref)); Set_Named_Entity (Res, Ref); Set_Base_Name (Res, Res); -- FIXME: set type and expr staticness ? return Res; end Build_Simple_Name; function Build_Simple_Name (Ref : Iir; Loc : Iir) return Iir is begin return Build_Simple_Name (Ref, Get_Location (Loc)); end Build_Simple_Name; function Build_Reference_Name (Name : Iir) return Iir is Res : Iir; begin pragma Assert (Get_Kind (Name) in Iir_Kinds_Denoting_Name); Res := Create_Iir (Iir_Kind_Reference_Name); Location_Copy (Res, Name); Set_Referenced_Name (Res, Name); Set_Is_Forward_Ref (Res, True); Set_Named_Entity (Res, Get_Named_Entity (Name)); return Res; end Build_Reference_Name; function Strip_Reference_Name (N : Iir) return Iir is begin if Get_Kind (N) = Iir_Kind_Reference_Name then return Get_Named_Entity (N); else return N; end if; end Strip_Reference_Name; function Has_Resolution_Function (Subtyp : Iir) return Iir is Ind : constant Iir := Get_Resolution_Indication (Subtyp); begin if Ind /= Null_Iir and then Get_Kind (Ind) in Iir_Kinds_Denoting_Name then -- A resolution indication can be an array/record element resolution. return Get_Named_Entity (Ind); else return Null_Iir; end if; end Has_Resolution_Function; function Is_Type_Name (Name : Iir) return Iir is Ent : Iir; begin case Get_Kind (Name) is when Iir_Kinds_Denoting_Name | Iir_Kind_Attribute_Name => Ent := Get_Named_Entity (Name); case Get_Kind (Ent) is when Iir_Kind_Type_Declaration => return Get_Type_Definition (Ent); when Iir_Kind_Subtype_Declaration | Iir_Kind_Base_Attribute | Iir_Kind_Subtype_Attribute | Iir_Kind_Element_Attribute => return Get_Type (Ent); when others => return Null_Iir; end case; when Iir_Kind_Subtype_Attribute => return Get_Type (Ent); when Iir_Kind_Element_Attribute => return Get_Type (Name); when others => return Null_Iir; end case; end Is_Type_Name; function Get_Type_Of_Subtype_Indication (Ind : Iir) return Iir is begin case Get_Kind (Ind) is when Iir_Kinds_Denoting_Name => return Get_Type (Ind); when Iir_Kinds_Subtype_Definition => return Ind; when Iir_Kind_Subtype_Attribute | Iir_Kind_Element_Attribute | Iir_Kind_Across_Attribute | Iir_Kind_Through_Attribute => return Get_Type (Ind); when Iir_Kind_Interface_Type_Definition => return Ind; when Iir_Kind_Error => return Ind; when others => Error_Kind ("get_type_of_subtype_indication", Ind); end case; end Get_Type_Of_Subtype_Indication; function Get_Nature_Of_Subnature_Indication (Ind : Iir) return Iir is begin case Get_Kind (Ind) is when Iir_Kinds_Denoting_Name => -- Name of a nature. return Get_Nature (Get_Named_Entity (Ind)); when Iir_Kind_Array_Subnature_Definition => return Ind; when others => Error_Kind ("get_nature_of_subnature_indication", Ind); end case; end Get_Nature_Of_Subnature_Indication; function Is_Proper_Subtype_Indication (Def : Iir) return Boolean is begin case Get_Kind (Def) is when Iir_Kinds_Subtype_Definition => return True; when Iir_Kinds_Denoting_Name | Iir_Kind_Element_Attribute | Iir_Kind_Subtype_Attribute => return False; when others => Error_Kind ("is_proper_subtype_indication", Def); end case; end Is_Proper_Subtype_Indication; function Is_Proper_Subnature_Indication (Def : Iir) return Boolean is begin case Get_Kind (Def) is when Iir_Kinds_Subnature_Definition => return True; when Iir_Kinds_Denoting_Name => return False; when others => Error_Kind ("is_proper_subnature_indication", Def); end case; end Is_Proper_Subnature_Indication; function Has_Owned_Subtype_Indication (Decl : Iir) return Boolean is Def : Iir; begin -- Subtype indication is shared with a previous declaration, like in: -- signal a, b : std_logic_vector (7 downto 0); if Get_Is_Ref (Decl) then return False; end if; Def := Get_Subtype_Indication (Decl); -- Implicit functions don't have subtype indication. -- TODO: make them regular ? -- Also, object aliases may not have a subtype indication. if Def = Null_Iir then return False; end if; return Is_Proper_Subtype_Indication (Def); end Has_Owned_Subtype_Indication; function Get_Index_Type (Indexes : Iir_Flist; Idx : Natural) return Iir is Index : constant Iir := Get_Nth_Element (Indexes, Idx); begin if Index = Null_Iir then return Null_Iir; else return Get_Index_Type (Index); end if; end Get_Index_Type; function Get_Index_Type (Array_Type : Iir; Idx : Natural) return Iir is begin return Get_Index_Type (Get_Index_Subtype_List (Array_Type), Idx); end Get_Index_Type; function Get_Nbr_Dimensions (Array_Type : Iir) return Natural is begin return Get_Nbr_Elements (Get_Index_Subtype_List (Array_Type)); end Get_Nbr_Dimensions; function Is_One_Dimensional_Array_Type (A_Type : Iir) return Boolean is Base_Type : constant Iir := Get_Base_Type (A_Type); begin return Get_Kind (Base_Type) = Iir_Kind_Array_Type_Definition and then Get_Nbr_Dimensions (Base_Type) = 1; end Is_One_Dimensional_Array_Type; function Are_Array_Indexes_Locally_Static (Array_Type : Iir) return Boolean is Indexes : constant Iir_Flist := Get_Index_Subtype_List (Array_Type); Index : Iir; begin for I in Flist_First .. Flist_Last (Indexes) loop Index := Get_Index_Type (Indexes, I); if Get_Type_Staticness (Index) /= Locally then return False; end if; end loop; return True; end Are_Array_Indexes_Locally_Static; function Are_Bounds_Locally_Static (Def : Iir) return Boolean is begin if Get_Type_Staticness (Def) = Locally then return True; end if; case Iir_Kinds_Type_And_Subtype_Definition (Get_Kind (Def)) is when Iir_Kind_Array_Subtype_Definition => pragma Assert (Get_Constraint_State (Def) = Fully_Constrained); -- Indexes. if not Are_Array_Indexes_Locally_Static (Def) then return False; end if; -- Element. return Are_Bounds_Locally_Static (Get_Element_Subtype (Def)); when Iir_Kind_Array_Type_Definition => return False; when Iir_Kind_Record_Subtype_Definition | Iir_Kind_Record_Type_Definition => pragma Assert (Get_Constraint_State (Def) = Fully_Constrained); declare El_List : constant Iir_Flist := Get_Elements_Declaration_List (Def); El : Iir; begin for I in Flist_First .. Flist_Last (El_List) loop El := Get_Nth_Element (El_List, I); if not Are_Bounds_Locally_Static (Get_Type (El)) then return False; end if; end loop; return True; end; when Iir_Kinds_Scalar_Type_And_Subtype_Definition | Iir_Kind_Protected_Type_Declaration | Iir_Kind_Access_Type_Definition | Iir_Kind_Access_Subtype_Definition => return True; when Iir_Kind_Incomplete_Type_Definition | Iir_Kind_File_Type_Definition | Iir_Kind_File_Subtype_Definition | Iir_Kind_Interface_Type_Definition => Error_Kind ("are_bounds_locally_static", Def); end case; end Are_Bounds_Locally_Static; function Get_Denoted_Type_Mark (Subtyp : Iir) return Iir is Type_Mark_Name : constant Iir := Get_Subtype_Type_Mark (Subtyp); begin if Type_Mark_Name = Null_Iir then -- No type_mark (for array subtype created by constrained array -- definition. return Null_Iir; else return Get_Type (Get_Named_Entity (Type_Mark_Name)); end if; end Get_Denoted_Type_Mark; function Get_Base_Element_Declaration (El : Iir) return Iir is Rec_Type : constant Iir := Get_Base_Type (Get_Parent (El)); Els_List : constant Iir_Flist := Get_Elements_Declaration_List (Rec_Type); begin return Get_Nth_Element (Els_List, Natural (Get_Element_Position (El))); end Get_Base_Element_Declaration; procedure Append_Owned_Element_Constraint (Rec_Type : Iir; El : Iir) is begin pragma Assert (Get_Parent (El) = Rec_Type); Set_Chain (El, Get_Owned_Elements_Chain (Rec_Type)); Set_Owned_Elements_Chain (Rec_Type, El); end Append_Owned_Element_Constraint; function Is_Second_Subprogram_Specification (Spec : Iir) return Boolean is Bod : constant Iir := Get_Chain (Spec); begin -- FIXME: don't directly use Subprogram_Body as it is not yet correctly -- set during instantiation. return Get_Has_Body (Spec) and then Get_Subprogram_Specification (Bod) /= Spec; end Is_Second_Subprogram_Specification; function Is_Implicit_Subprogram (Spec : Iir) return Boolean is begin return Get_Kind (Spec) in Iir_Kinds_Subprogram_Declaration and then Get_Implicit_Definition (Spec) in Iir_Predefined_Implicit; end Is_Implicit_Subprogram; function Is_Function_Declaration (N : Iir) return Boolean is begin return Kind_In (N, Iir_Kind_Function_Declaration, Iir_Kind_Interface_Function_Declaration); end Is_Function_Declaration; function Is_Procedure_Declaration (N : Iir) return Boolean is begin return Kind_In (N, Iir_Kind_Procedure_Declaration, Iir_Kind_Interface_Procedure_Declaration); end Is_Procedure_Declaration; function Is_Same_Profile (L, R: Iir) return Boolean is L1, R1 : Iir; L_Kind, R_Kind : Iir_Kind; El_L, El_R : Iir; begin L_Kind := Get_Kind (L); if L_Kind = Iir_Kind_Non_Object_Alias_Declaration then L1 := Get_Named_Entity (Get_Name (L)); L_Kind := Get_Kind (L1); else L1 := L; end if; R_Kind := Get_Kind (R); if R_Kind = Iir_Kind_Non_Object_Alias_Declaration then R1 := Get_Named_Entity (Get_Name (R)); R_Kind := Get_Kind (R1); else R1 := R; end if; -- Check L and R are both of the same 'kind'. -- Also the return profile for functions. if L_Kind = Iir_Kind_Function_Declaration and then R_Kind = Iir_Kind_Function_Declaration then if Get_Base_Type (Get_Return_Type (L1)) /= Get_Base_Type (Get_Return_Type (R1)) then return False; end if; elsif L_Kind = Iir_Kind_Procedure_Declaration and then R_Kind = Iir_Kind_Procedure_Declaration then null; elsif L_Kind = Iir_Kind_Enumeration_Literal and then R_Kind = Iir_Kind_Enumeration_Literal then return Get_Type (L1) = Get_Type (R1); elsif L_Kind = Iir_Kind_Enumeration_Literal and then R_Kind = Iir_Kind_Function_Declaration then return Get_Interface_Declaration_Chain (R1) = Null_Iir and then Get_Base_Type (Get_Return_Type (R1)) = Get_Type (L1); elsif L_Kind = Iir_Kind_Function_Declaration and then R_Kind = Iir_Kind_Enumeration_Literal then return Get_Interface_Declaration_Chain (L1) = Null_Iir and then Get_Base_Type (Get_Return_Type (L1)) = Get_Type (R1); else -- Kind mismatch. return False; end if; -- Check parameters profile. El_L := Get_Interface_Declaration_Chain (L1); El_R := Get_Interface_Declaration_Chain (R1); loop exit when El_L = Null_Iir and El_R = Null_Iir; if El_L = Null_Iir or El_R = Null_Iir then return False; end if; if Get_Base_Type (Get_Type (El_L)) /= Get_Base_Type (Get_Type (El_R)) then return False; end if; El_L := Get_Chain (El_L); El_R := Get_Chain (El_R); end loop; return True; end Is_Same_Profile; function Is_Operation_For_Type (Subprg : Iir; Atype : Iir) return Boolean is pragma Assert (Get_Kind (Subprg) in Iir_Kinds_Subprogram_Declaration); Base_Type : constant Iir := Get_Base_Type (Atype); Inter : Iir; begin Inter := Get_Interface_Declaration_Chain (Subprg); while Inter /= Null_Iir loop if Get_Base_Type (Get_Type (Inter)) = Base_Type then return True; end if; Inter := Get_Chain (Inter); end loop; if Get_Kind (Subprg) = Iir_Kind_Function_Declaration and then Get_Base_Type (Get_Return_Type (Subprg)) = Base_Type then return True; end if; return False; end Is_Operation_For_Type; -- From a block_specification, returns the block. function Get_Block_From_Block_Specification (Block_Spec : Iir) return Iir is Res : Iir; begin case Get_Kind (Block_Spec) is when Iir_Kind_Design_Unit => Res := Get_Library_Unit (Block_Spec); pragma Assert (Get_Kind (Res) = Iir_Kind_Architecture_Body); return Res; when Iir_Kind_Block_Statement | Iir_Kind_Architecture_Body | Iir_Kind_For_Generate_Statement | Iir_Kind_If_Generate_Statement => return Block_Spec; when Iir_Kind_Indexed_Name | Iir_Kind_Selected_Name | Iir_Kind_Slice_Name => return Get_Named_Entity (Get_Prefix (Block_Spec)); when Iir_Kind_Simple_Name => return Get_Named_Entity (Block_Spec); when Iir_Kind_Parenthesis_Name => -- An alternative label. return Get_Named_Entity (Block_Spec); when others => Error_Kind ("get_block_from_block_specification", Block_Spec); return Null_Iir; end case; end Get_Block_From_Block_Specification; function Get_Entity (Decl : Iir) return Iir is Name : constant Iir := Get_Entity_Name (Decl); Res : constant Iir := Get_Named_Entity (Name); begin if Res = Null_Iir or else Res = Vhdl.Std_Package.Error_Mark then return Null_Iir; end if; pragma Assert (Kind_In (Res, Iir_Kind_Entity_Declaration, Iir_Kind_Foreign_Module)); return Res; end Get_Entity; function Get_Configuration (Aspect : Iir) return Iir is Name : constant Iir := Get_Configuration_Name (Aspect); Res : constant Iir := Get_Named_Entity (Name); begin pragma Assert (Get_Kind (Res) = Iir_Kind_Configuration_Declaration); return Res; end Get_Configuration; function Get_Entity_Identifier_Of_Architecture (Arch : Iir) return Name_Id is Name : constant Iir := Get_Entity_Name (Arch); begin case Get_Kind (Name) is when Iir_Kind_Simple_Name | Iir_Kind_Selected_Name => return Get_Identifier (Name); when Iir_Kind_Error => return Null_Identifier; when others => Error_Kind ("get_entity_identifier_of_architecture", Name); end case; end Get_Entity_Identifier_Of_Architecture; function Is_Component_Instantiation (Inst : Iir_Component_Instantiation_Statement) return Boolean is begin case Get_Kind (Get_Instantiated_Unit (Inst)) is when Iir_Kinds_Denoting_Name => return True; when Iir_Kind_Entity_Aspect_Entity | Iir_Kind_Entity_Aspect_Configuration => return False; when others => Error_Kind ("is_component_instantiation", Inst); end case; end Is_Component_Instantiation; function Is_Entity_Instantiation (Inst : Iir_Component_Instantiation_Statement) return Boolean is begin case Get_Kind (Get_Instantiated_Unit (Inst)) is when Iir_Kinds_Denoting_Name => return False; when Iir_Kind_Entity_Aspect_Entity | Iir_Kind_Entity_Aspect_Configuration => return True; when others => Error_Kind ("is_entity_instantiation", Inst); end case; end Is_Entity_Instantiation; function Get_Attribute_Name_Expression (Name : Iir) return Iir is Attr_Val : constant Iir := Get_Named_Entity (Name); Attr_Spec : constant Iir := Get_Attribute_Specification (Attr_Val); Attr_Expr : constant Iir := Get_Expression (Attr_Spec); begin return Attr_Expr; end Get_Attribute_Name_Expression; function Get_String_Type_Bound_Type (Sub_Type : Iir) return Iir is begin if Get_Kind (Sub_Type) /= Iir_Kind_Array_Subtype_Definition then Error_Kind ("get_string_type_bound_type", Sub_Type); end if; return Get_Nth_Element (Get_Index_Subtype_List (Sub_Type), 0); end Get_String_Type_Bound_Type; procedure Get_Low_High_Limit (Arange : Iir_Range_Expression; Low, High : out Iir) is begin case Get_Direction (Arange) is when Dir_To => Low := Get_Left_Limit (Arange); High := Get_Right_Limit (Arange); when Dir_Downto => High := Get_Left_Limit (Arange); Low := Get_Right_Limit (Arange); end case; end Get_Low_High_Limit; function Get_Low_Limit (Arange : Iir_Range_Expression) return Iir is begin case Get_Direction (Arange) is when Dir_To => return Get_Left_Limit (Arange); when Dir_Downto => return Get_Right_Limit (Arange); end case; end Get_Low_Limit; function Get_High_Limit (Arange : Iir_Range_Expression) return Iir is begin case Get_Direction (Arange) is when Dir_To => return Get_Right_Limit (Arange); when Dir_Downto => return Get_Left_Limit (Arange); end case; end Get_High_Limit; function Is_Range_Attribute_Name (Expr : Iir) return Boolean is Attr : Iir; Id : Name_Id; begin if Get_Kind (Expr) = Iir_Kind_Parenthesis_Name then Attr := Get_Prefix (Expr); else Attr := Expr; end if; if Get_Kind (Attr) /= Iir_Kind_Attribute_Name then return False; end if; Id := Get_Identifier (Attr); return Id = Name_Range or Id = Name_Reverse_Range; end Is_Range_Attribute_Name; function Get_Range_From_Discrete_Range (Rng : Iir) return Iir is begin case Get_Kind (Rng) is when Iir_Kinds_Denoting_Name => return Get_Range_From_Discrete_Range (Get_Named_Entity (Rng)); when Iir_Kinds_Scalar_Subtype_Definition => return Get_Range_Constraint (Rng); when Iir_Kind_Range_Expression => return Rng; when Iir_Kinds_Range_Attribute => return Rng; when others => Error_Kind ("get_range_from_discrete_range", Rng); end case; end Get_Range_From_Discrete_Range; function Create_Array_Subtype (Arr_Type : Iir; Loc : Location_Type) return Iir_Array_Subtype_Definition is Base_Type : constant Iir := Get_Base_Type (Arr_Type); El_Type : constant Iir := Get_Element_Subtype (Base_Type); Res : Iir_Array_Subtype_Definition; List : Iir_Flist; begin Res := Create_Iir (Iir_Kind_Array_Subtype_Definition); Set_Location (Res, Loc); Set_Parent_Type (Res, Base_Type); Set_Element_Subtype (Res, El_Type); if Get_Kind (Arr_Type) = Iir_Kind_Array_Subtype_Definition then Set_Resolution_Indication (Res, Get_Resolution_Indication (Arr_Type)); end if; Set_Resolved_Flag (Res, Get_Resolved_Flag (Arr_Type)); Set_Signal_Type_Flag (Res, Get_Signal_Type_Flag (Arr_Type)); Set_Type_Staticness (Res, Get_Type_Staticness (El_Type)); List := Create_Iir_Flist (Get_Nbr_Dimensions (Base_Type)); Set_Index_Subtype_List (Res, List); Set_Index_Constraint_List (Res, List); return Res; end Create_Array_Subtype; function Is_Subprogram_Method (Spec : Iir) return Boolean is begin case Get_Kind (Get_Parent (Spec)) is when Iir_Kind_Protected_Type_Declaration | Iir_Kind_Protected_Type_Body => return True; when others => return False; end case; end Is_Subprogram_Method; function Get_Method_Type (Spec : Iir) return Iir is Parent : Iir; begin Parent := Get_Parent (Spec); case Get_Kind (Parent) is when Iir_Kind_Protected_Type_Declaration => return Parent; when Iir_Kind_Protected_Type_Body => return Get_Protected_Type_Declaration (Parent); when others => return Null_Iir; end case; end Get_Method_Type; function Get_Actual_Or_Default (Assoc : Iir; Inter : Iir) return Iir is begin case Get_Kind (Assoc) is when Iir_Kind_Association_Element_By_Expression => return Get_Actual (Assoc); when Iir_Kind_Association_Element_Open => return Get_Default_Value (Inter); when others => Error_Kind ("get_actual_or_default", Assoc); end case; end Get_Actual_Or_Default; function Create_Error (Orig : Iir) return Iir is Res : Iir; begin Res := Create_Iir (Iir_Kind_Error); if Orig /= Null_Iir then Set_Error_Origin (Res, Orig); Location_Copy (Res, Orig); end if; return Res; end Create_Error; function Create_Error_Expr (Orig : Iir; Atype : Iir) return Iir is Res : Iir; begin Res := Create_Error (Orig); Set_Expr_Staticness (Res, None); Set_Type (Res, Atype); return Res; end Create_Error_Expr; function Create_Error_Type (Orig : Iir) return Iir is Res : Iir; begin Res := Create_Error (Orig); --Set_Expr_Staticness (Res, Locally); Set_Type_Declarator (Res, Null_Iir); Set_Resolved_Flag (Res, True); Set_Signal_Type_Flag (Res, True); return Res; end Create_Error_Type; function Create_Error_Name (Orig : Iir) return Iir is Res : Iir; begin Res := Create_Iir (Iir_Kind_Error); Set_Expr_Staticness (Res, None); Set_Error_Origin (Res, Orig); Location_Copy (Res, Orig); return Res; end Create_Error_Name; -- Extract the entity from ASPECT. -- Note: if ASPECT is a component declaration, returns ASPECT. function Get_Entity_From_Entity_Aspect (Aspect : Iir) return Iir is Inst : Iir; begin case Get_Kind (Aspect) is when Iir_Kinds_Denoting_Name => -- A component declaration. Inst := Get_Named_Entity (Aspect); pragma Assert (Get_Kind (Inst) = Iir_Kind_Component_Declaration); return Inst; when Iir_Kind_Component_Declaration => return Aspect; when Iir_Kind_Entity_Aspect_Entity => return Get_Entity (Aspect); when Iir_Kind_Entity_Aspect_Configuration => Inst := Get_Configuration (Aspect); return Get_Entity (Inst); when Iir_Kind_Entity_Aspect_Open => return Null_Iir; when others => Error_Kind ("get_entity_from_entity_aspect", Aspect); end case; end Get_Entity_From_Entity_Aspect; function Get_Entity_From_Configuration (Config : Iir) return Iir is Conf_Unit : constant Iir := Get_Library_Unit (Config); Arch : constant Iir := Get_Named_Entity (Get_Block_Specification (Get_Block_Configuration (Conf_Unit))); Entity : constant Iir := Vhdl.Utils.Get_Entity (Arch); begin return Entity; end Get_Entity_From_Configuration; function Is_Nested_Package (Pkg : Iir) return Boolean is begin return Get_Kind (Get_Parent (Pkg)) /= Iir_Kind_Design_Unit; end Is_Nested_Package; -- LRM08 4.7 Package declarations -- If the package header is empty, the package declared by a package -- declaration is called a simple package. function Is_Simple_Package (Pkg : Iir) return Boolean is begin return Get_Package_Header (Pkg) = Null_Iir; end Is_Simple_Package; -- LRM08 4.7 Package declarations -- If the package header contains a generic clause and no generic map -- aspect, the package is called an uninstantiated package. function Is_Uninstantiated_Package (Pkg : Iir) return Boolean is Header : constant Iir := Get_Package_Header (Pkg); begin return Header /= Null_Iir and then Get_Generic_Map_Aspect_Chain (Header) = Null_Iir; end Is_Uninstantiated_Package; -- LRM08 4.7 Package declarations -- If the package header contains both a generic clause and a generic -- map aspect, the package is declared a generic-mapped package. function Is_Generic_Mapped_Package (Pkg : Iir) return Boolean is Header : constant Iir := Get_Package_Header (Pkg); begin return Header /= Null_Iir and then Get_Generic_Map_Aspect_Chain (Header) /= Null_Iir; end Is_Generic_Mapped_Package; -- LRM08 4.2 Subprogram declarations -- If the subprogram header contains the reserved word GENERIC, a generic -- list, and no generic map aspect, the subprogram is called an -- uninstantiated subprogram. function Is_Uninstantiated_Subprogram (Subprg : Iir) return Boolean is begin return Get_Generic_Chain (Subprg) /= Null_Iir; end Is_Uninstantiated_Subprogram; function Kind_In (N : Iir; K1, K2 : Iir_Kind) return Boolean is K : constant Iir_Kind := Get_Kind (N); begin return K = K1 or K = K2; end Kind_In; function Kind_In (N : Iir; K1, K2, K3 : Iir_Kind) return Boolean is K : constant Iir_Kind := Get_Kind (N); begin return K = K1 or K = K2 or K = K3; end Kind_In; procedure Set_Attribute_Parameter (Attr : Iir; N : Parameter_Index; Param : Iir) is begin case N is when 1 => Set_Parameter (Attr, Param); when 2 => Set_Parameter_2 (Attr, Param); when 3 => Set_Parameter_3 (Attr, Param); when 4 => Set_Parameter_4 (Attr, Param); end case; end Set_Attribute_Parameter; function Get_Attribute_Parameter (Attr : Iir; N : Parameter_Index) return Iir is begin case N is when 1 => return Get_Parameter (Attr); when 2 => return Get_Parameter_2 (Attr); when 3 => return Get_Parameter_3 (Attr); when 4 => return Get_Parameter_4 (Attr); end case; end Get_Attribute_Parameter; function Get_File_Signature_Length (Def : Iir) return Natural is begin case Get_Kind (Def) is when Iir_Kinds_Scalar_Type_And_Subtype_Definition => return 1; when Iir_Kind_Array_Type_Definition | Iir_Kind_Array_Subtype_Definition => return 2 + Get_File_Signature_Length (Get_Element_Subtype (Def)); when Iir_Kind_Record_Type_Definition | Iir_Kind_Record_Subtype_Definition => declare List : constant Iir_Flist := Get_Elements_Declaration_List (Get_Base_Type (Def)); El : Iir; Res : Natural; begin Res := 2; for I in Flist_First .. Flist_Last (List) loop El := Get_Nth_Element (List, I); Res := Res + Get_File_Signature_Length (Get_Type (El)); end loop; return Res; end; when others => Error_Kind ("get_file_signature_length", Def); end case; end Get_File_Signature_Length; procedure Get_File_Signature (Def : Iir; Res : in out String; Off : in out Natural) is Base_Type : constant Iir := Get_Base_Type (Def); begin case Get_Kind (Base_Type) is when Iir_Kind_Integer_Type_Definition => case Get_Scalar_Size (Base_Type) is when Scalar_32 => Res (Off) := 'i'; when Scalar_64 => Res (Off) := 'I'; when others => raise Internal_Error; end case; Off := Off + 1; when Iir_Kind_Physical_Type_Definition => case Get_Scalar_Size (Base_Type) is when Scalar_32 => Res (Off) := 'p'; when Scalar_64 => Res (Off) := 'P'; when others => raise Internal_Error; end case; Off := Off + 1; when Iir_Kind_Floating_Type_Definition => Res (Off) := 'F'; Off := Off + 1; when Iir_Kind_Enumeration_Type_Definition => if Base_Type = Std_Package.Boolean_Type_Definition then Res (Off) := 'b'; else case Get_Scalar_Size (Base_Type) is when Scalar_8 => Res (Off) := 'e'; when Scalar_32 => Res (Off) := 'E'; when others => raise Internal_Error; end case; end if; Off := Off + 1; when Iir_Kind_Array_Type_Definition | Iir_Kind_Array_Subtype_Definition => Res (Off) := '['; Off := Off + 1; Get_File_Signature (Get_Element_Subtype (Def), Res, Off); Res (Off) := ']'; Off := Off + 1; when Iir_Kind_Record_Type_Definition | Iir_Kind_Record_Subtype_Definition => declare List : constant Iir_Flist := Get_Elements_Declaration_List (Get_Base_Type (Def)); El : Iir; begin Res (Off) := '<'; Off := Off + 1; for I in Flist_First .. Flist_Last (List) loop El := Get_Nth_Element (List, I); Get_File_Signature (Get_Type (El), Res, Off); end loop; Res (Off) := '>'; Off := Off + 1; end; when others => Error_Kind ("get_file_signature", Def); end case; end Get_File_Signature; function Get_Source_Identifier (Decl : Iir) return Name_Id is use Files_Map; use Name_Table; Loc : constant Location_Type := Get_Location (Decl); Len : constant Natural := Get_Name_Length (Get_Identifier (Decl)); subtype Ident_Str is String (1 .. Len); File : Source_File_Entry; Pos : Source_Ptr; Buf : File_Buffer_Acc; begin Location_To_File_Pos (Loc, File, Pos); Buf := Get_File_Source (File); return Get_Identifier (Ident_Str (Buf (Pos .. Pos + Source_Ptr (Len - 1)))); end Get_Source_Identifier; function Get_HDL_Node (N : PSL_Node) return Iir is begin return Iir (PSL.Nodes.Get_HDL_Node (N)); end Get_HDL_Node; procedure Set_HDL_Node (N : PSL_Node; Expr : Iir) is begin PSL.Nodes.Set_HDL_Node (N, PSL.Nodes.HDL_Node (Expr)); end Set_HDL_Node; end Vhdl.Utils;