diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-05-05 07:18:49 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-05-05 08:05:10 +0200 |
commit | 53fcf00d88d1a3b34c7833aa4c421ea52f3e03dd (patch) | |
tree | 1d54f41e948b16a5ff6ad0cedafccf978a13bd89 /src/vhdl/sem_specs.adb | |
parent | d1f0fedf7882cf1b15ea6450da5bbd878d007a98 (diff) | |
download | ghdl-53fcf00d88d1a3b34c7833aa4c421ea52f3e03dd.tar.gz ghdl-53fcf00d88d1a3b34c7833aa4c421ea52f3e03dd.tar.bz2 ghdl-53fcf00d88d1a3b34c7833aa4c421ea52f3e03dd.zip |
vhdl: move sem* packages to vhdl children.
Diffstat (limited to 'src/vhdl/sem_specs.adb')
-rw-r--r-- | src/vhdl/sem_specs.adb | 1928 |
1 files changed, 0 insertions, 1928 deletions
diff --git a/src/vhdl/sem_specs.adb b/src/vhdl/sem_specs.adb deleted file mode 100644 index 429431539..000000000 --- a/src/vhdl/sem_specs.adb +++ /dev/null @@ -1,1928 +0,0 @@ --- Semantic analysis. --- Copyright (C) 2002, 2003, 2004, 2005 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 GHDL; see the file COPYING. If not, write to the Free --- Software Foundation, 59 Temple Place - Suite 330, Boston, MA --- 02111-1307, USA. -with Iirs_Utils; use Iirs_Utils; -with Sem_Expr; use Sem_Expr; -with Sem_Names; use Sem_Names; -with Evaluation; use Evaluation; -with Std_Package; use Std_Package; -with Errorout; use Errorout; -with Sem; use Sem; -with Sem_Lib; use Sem_Lib; -with Sem_Scopes; use Sem_Scopes; -with Sem_Assocs; use Sem_Assocs; -with Libraries; -with Iir_Chains; use Iir_Chains; -with Flags; use Flags; -with Std_Names; -with Sem_Decls; -with Xrefs; use Xrefs; -with Back_End; - -package body Sem_Specs is - function Get_Entity_Class_Kind (Decl : Iir) return Vhdl.Tokens.Token_Type - is - use Vhdl.Tokens; - begin - case Get_Kind (Decl) is - when Iir_Kind_Entity_Declaration => - return Tok_Entity; - when Iir_Kind_Architecture_Body => - return Tok_Architecture; - when Iir_Kind_Configuration_Declaration => - return Tok_Configuration; - when Iir_Kind_Package_Declaration => - return Tok_Package; - when Iir_Kind_Procedure_Declaration => - return Tok_Procedure; - when Iir_Kind_Function_Declaration => - return Tok_Function; - when Iir_Kind_Type_Declaration => - return Tok_Type; - when Iir_Kind_Subtype_Declaration => - return Tok_Subtype; - when Iir_Kind_Constant_Declaration - | Iir_Kind_Interface_Constant_Declaration => - return Tok_Constant; - when Iir_Kind_Signal_Declaration - | Iir_Kind_Interface_Signal_Declaration - | Iir_Kind_Guard_Signal_Declaration => - return Tok_Signal; - when Iir_Kind_Variable_Declaration - | Iir_Kind_Interface_Variable_Declaration => - return Tok_Variable; - when Iir_Kind_Component_Declaration => - return Tok_Component; - when Iir_Kind_Concurrent_Conditional_Signal_Assignment - | Iir_Kind_Concurrent_Selected_Signal_Assignment - | Iir_Kind_Sensitized_Process_Statement - | Iir_Kind_Process_Statement - | Iir_Kind_Concurrent_Assertion_Statement - | Iir_Kind_Component_Instantiation_Statement - | Iir_Kind_Block_Statement - | Iir_Kind_If_Generate_Statement - | Iir_Kind_For_Generate_Statement - | Iir_Kind_Concurrent_Procedure_Call_Statement - | Iir_Kinds_Sequential_Statement => - return Tok_Label; - when Iir_Kind_Enumeration_Literal => - return Tok_Literal; - when Iir_Kind_Unit_Declaration => - return Tok_Units; - when Iir_Kind_Group_Declaration => - return Tok_Group; - when Iir_Kind_File_Declaration - | Iir_Kind_Interface_File_Declaration => - return Tok_File; - when Iir_Kind_Attribute_Declaration => - -- Even if an attribute can't have a attribute... - -- Because an attribute declaration can appear in a declaration - -- region. - return Tok_Attribute; - when others => - Error_Kind ("get_entity_class_kind", Decl); - end case; - return Tok_Invalid; - end Get_Entity_Class_Kind; - - -- Return the node containing the attribute_value_chain field for DECL. - -- This is the parent of the attribute specification, so in general this - -- is also the parent of the declaration, but there are exceptions... - function Get_Attribute_Value_Chain_Parent (Decl : Iir) return Iir - is - Parent : Iir; - begin - case Get_Kind (Decl) is - when Iir_Kind_Entity_Declaration - | Iir_Kind_Package_Declaration - | Iir_Kind_Package_Instantiation_Declaration - | Iir_Kind_Architecture_Body - | Iir_Kind_Configuration_Declaration => - -- LRM93 5.1 - -- An attribute specification for an attribute of a design unit - -- [...] must appear immediately within the declarative part of - -- that design unit. - return Decl; - when Iir_Kind_Interface_Constant_Declaration - | Iir_Kind_Interface_Variable_Declaration - | Iir_Kind_Interface_Signal_Declaration - | Iir_Kind_Interface_File_Declaration => - -- LRM93 5.1 - -- Similarly, an attribute specification for an attribute of an - -- interface object of a design unit, subprogram, block statement - -- or package must appear immediately within the declarative part - -- of that design unit, subprogram, block statement, or package. - Parent := Get_Parent (Decl); - case Get_Kind (Parent) is - when Iir_Kind_Entity_Declaration - | Iir_Kind_Block_Statement - | Iir_Kind_Package_Declaration - | Iir_Kind_Package_Instantiation_Declaration => - return Parent; - when Iir_Kind_Procedure_Declaration - | Iir_Kind_Function_Declaration => - return Get_Subprogram_Body (Parent); - when others => - raise Internal_Error; - end case; - when Iir_Kinds_Sequential_Statement => - -- Sequential statements can be nested. - Parent := Get_Parent (Decl); - loop - if Get_Kind (Parent) not in Iir_Kinds_Sequential_Statement then - return Parent; - end if; - Parent := Get_Parent (Parent); - end loop; - when others => - -- This is also true for enumeration literals and physical units. - return Get_Parent (Decl); - end case; - end Get_Attribute_Value_Chain_Parent; - - function Find_Attribute_Value (Ent : Iir; Id : Name_Id) return Iir - is - Attr_Value_Parent : constant Iir := - Get_Attribute_Value_Chain_Parent (Ent); - Value : Iir; - Spec : Iir; - Attr_Decl : Iir; - begin - Value := Get_Attribute_Value_Chain (Attr_Value_Parent); - while Value /= Null_Iir loop - if Get_Designated_Entity (Value) = Ent then - Spec := Get_Attribute_Specification (Value); - Attr_Decl := Get_Attribute_Designator (Spec); - if Get_Identifier (Attr_Decl) = Id then - return Value; - end if; - end if; - Value := Get_Value_Chain (Value); - end loop; - return Null_Iir; - end Find_Attribute_Value; - - -- Decorate DECL with attribute ATTR. - -- If CHECK_CLASS is true, class of DECL must be class of ATTR, otherwise - -- returns silently. - -- If CHECK_DEFINED is true, DECL must not have been decorated, otherwise - -- returns silently. - procedure Attribute_A_Decl (Decl : Iir; - Attr : Iir_Attribute_Specification; - Check_Class : Boolean; - Check_Defined : Boolean) - is - use Vhdl.Tokens; - Attr_Expr : constant Iir := Get_Expression (Attr); - - El : Iir_Attribute_Value; - - -- Attribute declaration corresponding to ATTR. - -- Due to possible error, it is not required to be an attribute decl, - -- it may be a simple name. - Attr_Decl : Iir; - - Attr_Chain_Parent : Iir; - begin - -- LRM93 5.1 - -- It is an error if the class of those names is not the same as that - -- denoted by the entity class. - if Get_Entity_Class_Kind (Decl) /= Get_Entity_Class (Attr) then - if Check_Class then - Error_Msg_Sem (+Attr, "%n is not of class %t", - (+Decl, +Get_Entity_Class (Attr))); - if Get_Kind (Decl) = Iir_Kind_Subtype_Declaration - and then Get_Entity_Class (Attr) = Tok_Type - and then Get_Type (Decl) /= Null_Iir - and then Get_Base_Type (Get_Type (Decl)) /= Null_Iir - and then Get_Kind - (Get_Type_Declarator (Get_Base_Type (Get_Type (Decl)))) - = Iir_Kind_Anonymous_Type_Declaration - then - -- The type declaration declares an anonymous type - -- and a named subtype. - Error_Msg_Sem - (+Decl, - "%i declares both an anonymous type and a named subtype", - +Decl); - end if; - end if; - return; - end if; - - -- LRM93 5.1 - -- An attribute specification for an attribute of a design unit - -- (ie an entity declaration, an architecture, a configuration, or a - -- package) must appear immediately within the declarative part of - -- that design unit. - case Get_Entity_Class (Attr) is - when Tok_Entity - | Tok_Architecture - | Tok_Configuration - | Tok_Package => - if Get_Design_Unit (Decl) /= Get_Current_Design_Unit then - Error_Msg_Sem (+Attr, "%n must appear immediatly within %n", - (+Attr, +Decl)); - return; - end if; - when others => - null; - end case; - - Attr_Decl := Get_Named_Entity (Get_Attribute_Designator (Attr)); - - -- LRM93 5.1 - -- It is an error if a given attribute is associated more than once with - -- a given named entity. - -- LRM 5.1 - -- Similarly, it is an error if two different attributes with the - -- same simple name (whether predefined or user-defined) are both - -- associated with a given named entity. - Attr_Chain_Parent := Get_Attribute_Value_Chain_Parent (Decl); - El := Get_Attribute_Value_Chain (Attr_Chain_Parent); - while El /= Null_Iir loop - if Get_Designated_Entity (El) = Decl then - declare - El_Attr : constant Iir_Attribute_Declaration := - Get_Named_Entity (Get_Attribute_Designator - (Get_Attribute_Specification (El))); - begin - if El_Attr = Attr_Decl then - if Get_Attribute_Specification (El) = Attr then - -- Was already specified with the same attribute value. - -- This is possible only in one case: - -- - -- signal S1 : real; - -- alias S1_too : real is S1; - -- attribute ATTR : T1; - -- attribute ATTR of ALL : signal is '1'; - return; - end if; - if Check_Defined then - Error_Msg_Sem - (+Attr, "%n has already %n", (+Decl, +Attr), - Cont => True); - Error_Msg_Sem - (+Attr, "previous attribute specification at %l", +El); - end if; - return; - elsif Get_Identifier (El_Attr) = Get_Identifier (Attr_Decl) then - Error_Msg_Sem (+Attr, "%n is already decorated with an %n", - (+Decl, +El_Attr), Cont => True); - Error_Msg_Sem - (+El, "(previous attribute specification was here)"); - return; - end if; - end; - end if; - El := Get_Value_Chain (El); - end loop; - - El := Create_Iir (Iir_Kind_Attribute_Value); - Location_Copy (El, Attr); - Set_Name_Staticness (El, None); - Set_Attribute_Specification (El, Attr); - -- FIXME: create an expr_error node? - if Is_Error (Attr_Expr) then - Set_Expr_Staticness (El, Locally); - else - Set_Expr_Staticness (El, Get_Expr_Staticness (Attr_Expr)); - end if; - Set_Designated_Entity (El, Decl); - Set_Type (El, Get_Type (Attr_Expr)); - Set_Base_Name (El, El); - - -- Put the attribute value in the attribute_value_chain. - Set_Value_Chain (El, Get_Attribute_Value_Chain (Attr_Chain_Parent)); - Set_Attribute_Value_Chain (Attr_Chain_Parent, El); - - -- Put the attribute value in the chain of the attribute specification. - -- This is prepended, so in reverse order. Will be reversed later. - Set_Spec_Chain (El, Get_Attribute_Value_Spec_Chain (Attr)); - Set_Attribute_Value_Spec_Chain (Attr, El); - - -- Special handling for 'Foreign. - if (Flags.Vhdl_Std >= Vhdl_93c - and then Attr_Decl = Foreign_Attribute) - or else - (Flags.Vhdl_Std <= Vhdl_93c - and then Get_Identifier (Attr_Decl) = Std_Names.Name_Foreign) - then - -- LRM93 12.4 - -- The 'FOREIGN attribute may be associated only with - -- architectures or with subprograms. - case Get_Entity_Class (Attr) is - when Tok_Architecture => - null; - - when Tok_Function - | Tok_Procedure => - -- LRM93 12.4 - -- In the latter case, the attribute specification must - -- appear in the declarative part in which the subprogram - -- is declared. - -- GHDL: huh, this is the case for any attributes. - null; - - when others => - Error_Msg_Sem - (+Attr, - "'FOREIGN allowed only for architectures and subprograms"); - return; - end case; - - Set_Foreign_Flag (Decl, True); - - -- Use 'standard' convention call for foreign procedures, so as a - -- consequence they cannot be suspended. - if Get_Kind (Decl) = Iir_Kind_Procedure_Declaration then - Set_Suspend_Flag (Decl, False); - end if; - - declare - use Back_End; - begin - if Sem_Foreign /= null then - Sem_Foreign.all (Decl); - end if; - end; - end if; - end Attribute_A_Decl; - - -- Return TRUE if a named entity was attributed. - function Sem_Named_Entities (Scope : Iir; - Name : Iir; - Attr : Iir_Attribute_Specification; - Check_Defined : Boolean) - return Boolean - is - -- Name is set (ie neither ALL nor OTHERS). - Is_Designator : constant Boolean := Name /= Null_Iir; - - Res : Boolean; - - -- If declaration DECL matches then named entity ENT, apply attribute - -- specification and returns TRUE. Otherwise, return FALSE. - -- Note: ENT and DECL are different for aliases. - function Sem_Named_Entity1 (Ent : Iir; Decl : Iir) return Boolean - is - use Vhdl.Tokens; - Ent_Id : constant Name_Id := Get_Identifier (Ent); - begin - if (not Is_Designator or else Ent_Id = Get_Identifier (Name)) - and then Ent_Id /= Null_Identifier - then - if Is_Designator then - -- The designator is neither ALL nor OTHERS. - Set_Named_Entity (Name, Ent); - Xref_Ref (Name, Ent); - - if Get_Entity_Class (Attr) = Tok_Label then - -- Concurrent or sequential statements appear later in the - -- AST, but their label are considered to appear before - -- other items in the declarative part. - Set_Is_Forward_Ref (Name, True); - end if; - end if; - if Get_Visible_Flag (Ent) = False then - Error_Msg_Sem (+Attr, "%n is not yet visible", +Ent); - else - Attribute_A_Decl (Decl, Attr, Is_Designator, Check_Defined); - return True; - end if; - end if; - return False; - end Sem_Named_Entity1; - - procedure Sem_Named_Entity (Ent : Iir) is - begin - case Get_Kind (Ent) is - when Iir_Kinds_Library_Unit - | Iir_Kinds_Concurrent_Statement - | Iir_Kinds_Sequential_Statement - | Iir_Kinds_Non_Alias_Object_Declaration - | Iir_Kind_Type_Declaration - | Iir_Kind_Subtype_Declaration - | Iir_Kind_Component_Declaration - | Iir_Kind_Enumeration_Literal - | Iir_Kind_Unit_Declaration - | Iir_Kind_Group_Template_Declaration - | Iir_Kind_Group_Declaration => - Res := Res or Sem_Named_Entity1 (Ent, Ent); - when Iir_Kind_Function_Declaration - | Iir_Kind_Procedure_Declaration => - if not Is_Second_Subprogram_Specification (Ent) then - Res := Res or Sem_Named_Entity1 (Ent, Ent); - end if; - when Iir_Kind_Object_Alias_Declaration => - -- LRM93 5.1 - -- An entity designator that denotes an alias of an object is - -- required to denote the entire object, and not a subelement - -- or slice thereof. - declare - Decl : constant Iir := Get_Name (Ent); - Base : constant Iir := Get_Object_Prefix (Decl, False); - Applied : Boolean; - begin - Applied := Sem_Named_Entity1 (Ent, Base); - -- FIXME: check the alias denotes a local entity... - if Applied - and then Base /= Strip_Denoting_Name (Decl) - then - Error_Msg_Sem - (+Attr, "%n does not denote the entire object", +Ent); - end if; - Res := Res or Applied; - end; - when Iir_Kind_Non_Object_Alias_Declaration => - Res := Res - or Sem_Named_Entity1 (Ent, Get_Named_Entity (Get_Name (Ent))); - when Iir_Kind_Attribute_Declaration - | Iir_Kind_Attribute_Specification - | Iir_Kind_Configuration_Specification - | Iir_Kind_Use_Clause => - null; - when Iir_Kind_Procedure_Body - | Iir_Kind_Function_Body => - null; - when Iir_Kind_Anonymous_Type_Declaration => - null; - when others => - Error_Kind ("sem_named_entity", Ent); - end case; - end Sem_Named_Entity; - - procedure Sem_Named_Entity_Chain (Chain_First : Iir) - is - El : Iir; - Def : Iir; - begin - El := Chain_First; - while El /= Null_Iir loop - exit when El = Attr; - Sem_Named_Entity (El); - case Get_Kind (El) is - when Iir_Kind_Type_Declaration => - Def := Get_Type_Definition (El); - if Get_Kind (Def) = Iir_Kind_Enumeration_Type_Definition then - declare - List : constant Iir_Flist := - Get_Enumeration_Literal_List (Def); - El1 : Iir; - begin - for I in Flist_First .. Flist_Last (List) loop - El1 := Get_Nth_Element (List, I); - Sem_Named_Entity (El1); - end loop; - end; - end if; - when Iir_Kind_Anonymous_Type_Declaration => - Def := Get_Type_Definition (El); - if Get_Kind (Def) = Iir_Kind_Physical_Type_Definition then - declare - El1 : Iir; - begin - El1 := Get_Unit_Chain (Def); - while El1 /= Null_Iir loop - Sem_Named_Entity (El1); - El1 := Get_Chain (El1); - end loop; - end; - end if; - when Iir_Kind_For_Loop_Statement - | Iir_Kind_While_Loop_Statement => - Sem_Named_Entity_Chain (Get_Sequential_Statement_Chain (El)); - when Iir_Kind_If_Statement => - declare - Clause : Iir; - begin - Clause := El; - while Clause /= Null_Iir loop - Sem_Named_Entity_Chain - (Get_Sequential_Statement_Chain (Clause)); - Clause := Get_Else_Clause (Clause); - end loop; - end; - when Iir_Kind_Case_Statement => - declare - El1 : Iir; - begin - El1 := Get_Case_Statement_Alternative_Chain (El); - while El1 /= Null_Iir loop - Sem_Named_Entity_Chain (Get_Associated_Chain (El1)); - El1 := Get_Chain (El1); - end loop; - end; - - when Iir_Kind_If_Generate_Statement - | Iir_Kind_For_Generate_Statement => - -- INT-1991/issue 27 - -- Generate statements represent declarative region and - -- have implicit declarative parts. - -- Was: There is no declarative part in generate statement - -- for VHDL 87. - if False and then Flags.Vhdl_Std = Vhdl_87 then - Sem_Named_Entity_Chain - (Get_Concurrent_Statement_Chain (El)); - end if; - - when others => - null; - end case; - El := Get_Chain (El); - end loop; - end Sem_Named_Entity_Chain; - begin - -- The attribute specification was not yet applied. - Res := False; - - -- LRM 5.1 Attribute specification - -- o If a list of entity designators is supplied, then the - -- attribute specification applies to the named entities denoted - -- by those designators. - -- - -- o If the reserved word OTHERS is supplied, then the attribute - -- specification applies to named entities of the specified class - -- that are declared in the immediately enclosing declarative - -- part [...] - -- - -- o If the reserved word ALL is supplied, then the attribute - -- specification applies to all named entities of the specified - -- class that are declared in the immediatly enclosing - -- declarative part. - - -- NOTE: therefore, ALL/OTHERS do not apply to named entities declared - -- beyond the immediate declarative part, such as design unit or - -- interfaces. - if Is_Designator then - if Is_Error (Name) then - pragma Assert (Flags.Flag_Force_Analysis); - return True; - end if; - - -- LRM 5.1 Attribute specification - -- An attribute specification for an attribute of a design unit - -- (i.e. an entity declaration, an architecture, a configuration - -- or a package) must appear immediatly within the declarative part - -- of that design unit. - case Get_Kind (Scope) is - when Iir_Kind_Entity_Declaration - | Iir_Kind_Architecture_Body - | Iir_Kind_Configuration_Declaration - | Iir_Kind_Package_Declaration => - Sem_Named_Entity (Scope); - when others => - null; - end case; - - -- LRM 5.1 Attribute specification - -- Similarly, an attribute specification for an attribute of an - -- interface object of a design unit, subprogram or block statement - -- must appear immediatly within the declarative part of that design - -- unit, subprogram, or block statement. - case Get_Kind (Scope) is - when Iir_Kind_Entity_Declaration => - Sem_Named_Entity_Chain (Get_Generic_Chain (Scope)); - Sem_Named_Entity_Chain (Get_Port_Chain (Scope)); - when Iir_Kind_Block_Statement => - declare - Header : constant Iir := Get_Block_Header (Scope); - begin - if Header /= Null_Iir then - Sem_Named_Entity_Chain (Get_Generic_Chain (Header)); - Sem_Named_Entity_Chain (Get_Port_Chain (Header)); - end if; - end; - when Iir_Kind_Function_Body - | Iir_Kind_Procedure_Body => - declare - Spec : Iir; - begin - Spec := Get_Subprogram_Specification (Scope); - Sem_Named_Entity_Chain - (Get_Interface_Declaration_Chain (Spec)); - end; - when others => - null; - end case; - end if; - - case Get_Kind (Scope) is - when Iir_Kind_Entity_Declaration - | Iir_Kind_Architecture_Body - | Iir_Kind_Generate_Statement_Body => - Sem_Named_Entity_Chain (Get_Declaration_Chain (Scope)); - Sem_Named_Entity_Chain (Get_Concurrent_Statement_Chain (Scope)); - when Iir_Kind_Block_Statement => - declare - Guard : constant Iir := Get_Guard_Decl (Scope); - begin - if Guard /= Null_Iir then - Sem_Named_Entity (Guard); - end if; - end; - Sem_Named_Entity_Chain (Get_Declaration_Chain (Scope)); - Sem_Named_Entity_Chain (Get_Concurrent_Statement_Chain (Scope)); - when Iir_Kind_Configuration_Declaration => - null; - when Iir_Kind_Package_Declaration => - Sem_Named_Entity_Chain (Get_Declaration_Chain (Scope)); - when Iir_Kinds_Process_Statement => - Sem_Named_Entity_Chain (Get_Declaration_Chain (Scope)); - Sem_Named_Entity_Chain (Get_Sequential_Statement_Chain (Scope)); - when Iir_Kind_Package_Body => - Sem_Named_Entity_Chain (Get_Declaration_Chain (Scope)); - when Iir_Kind_Function_Body - | Iir_Kind_Procedure_Body => - Sem_Named_Entity_Chain (Get_Declaration_Chain (Scope)); - Sem_Named_Entity_Chain (Get_Sequential_Statement_Chain (Scope)); - when others => - Error_Kind ("sem_named_entities", Scope); - end case; - return Res; - end Sem_Named_Entities; - - procedure Sem_Signature_Entity_Designator - (Sig : Iir_Signature; Attr : Iir_Attribute_Specification) - is - Prefix : Iir; - Inter : Name_Interpretation_Type; - List : Iir_List; - Name : Iir; - begin - List := Create_Iir_List; - - -- Sem_Name cannot be used here (at least not directly) because only - -- the declarations of the current scope are considered. - Prefix := Get_Signature_Prefix (Sig); - Inter := Get_Interpretation (Get_Identifier (Prefix)); - while Valid_Interpretation (Inter) loop - exit when not Is_In_Current_Declarative_Region (Inter); - if not Is_Potentially_Visible (Inter) then - Name := Get_Declaration (Inter); - -- LRM 5.1 Attribute Specification - -- The entity tag of an entity designator containing a signature - -- must denote the name of one or more subprograms or enumeration - -- literals. - case Get_Kind (Name) is - when Iir_Kind_Function_Declaration - | Iir_Kind_Procedure_Declaration - | Iir_Kind_Enumeration_Literal => - Append_Element (List, Name); - when others => - Error_Msg_Sem - (+Sig, "entity tag must denote a subprogram or a literal"); - end case; - end if; - Inter := Get_Next_Interpretation (Inter); - end loop; - - Name := Sem_Decls.Sem_Signature (Create_Overload_List (List), Sig); - if Name = Null_Iir then - return; - end if; - - Set_Named_Entity (Prefix, Name); - Prefix := Finish_Sem_Name (Prefix); - Set_Signature_Prefix (Sig, Prefix); - - Attribute_A_Decl (Name, Attr, True, True); - end Sem_Signature_Entity_Designator; - - procedure Sem_Attribute_Specification - (Spec : Iir_Attribute_Specification; Scope : Iir) - is - -- Emit an error message when NAME is not found. - procedure Error_Attribute_Specification (Name : Iir) - is - Inter : Name_Interpretation_Type; - Decl : Iir; - begin - if Flag_Relaxed_Rules or Vhdl_Std = Vhdl_93c then - -- Some (clueless ?) vendors put attribute specifications in - -- architectures for ports (declared in entities). This is not - -- valid according to the LRM (eg: LRM02 5.1 Attribute - -- specification). Be tolerant. - Inter := Get_Interpretation (Get_Identifier (Name)); - if Valid_Interpretation (Inter) then - Decl := Get_Declaration (Inter); - if Get_Kind (Decl) = Iir_Kind_Interface_Signal_Declaration - and then (Get_Kind (Get_Parent (Decl)) - = Iir_Kind_Entity_Declaration) - and then Get_Kind (Scope) = Iir_Kind_Architecture_Body - then - Warning_Msg_Sem - (Warnid_Specs, +Name, - "attribute for port %i must be specified in the entity", - (1 => +Name)); - return; - end if; - end if; - end if; - - Error_Msg_Sem - (+Name, "no %i for attribute specification", (1 => +Name)); - end Error_Attribute_Specification; - - use Vhdl.Tokens; - - Name : Iir; - Attr : Iir_Attribute_Declaration; - Attr_Type : Iir; - List : Iir_Flist; - Expr : Iir; - Res : Boolean; - begin - -- LRM93 5.1 - -- The attribute designator must denote an attribute. - Name := Sem_Denoting_Name (Get_Attribute_Designator (Spec)); - Set_Attribute_Designator (Spec, Name); - - Attr := Get_Named_Entity (Name); - if Get_Kind (Attr) /= Iir_Kind_Attribute_Declaration then - Error_Class_Match (Name, "attribute"); - return; - end if; - - -- LRM 5.1 - -- The type of the expression in the attribute specification must be - -- the same as (or implicitly convertible to) the type mark in the - -- corresponding attribute declaration. - Attr_Type := Get_Type (Attr); - Expr := Sem_Expression (Get_Expression (Spec), Attr_Type); - if Expr /= Null_Iir then - Check_Read (Expr); - Expr := Eval_Expr_If_Static (Expr); - Set_Expression (Spec, Expr); - - -- LRM 5.1 - -- If the entity name list denotes an entity declaration, - -- architecture body or configuration declaration, then the - -- expression is required to be locally static. - -- GHDL: test based on the entity_class. - case Get_Entity_Class (Spec) is - when Tok_Entity - | Tok_Architecture - | Tok_Configuration => - if Get_Expr_Staticness (Expr) /= Locally then - Error_Msg_Sem - (+Spec, - "attribute expression for %t must be locally static", - +Get_Entity_Class (Spec)); - end if; - when others => - null; - end case; - else - Set_Expression - (Spec, Create_Error_Expr (Get_Expression (Spec), Attr_Type)); - end if; - - -- LRM93 3.2.1.1 Index constraints and discrete ranges - -- - For an attribute whose value is specified by an attribute - -- specification, the index ranges are defined by the expression - -- given in the specification, if the subtype of the attribute is - -- unconstrained [...] - -- GHDL: For attribute value. - - -- LRM 5.1 - -- The entity name list identifies those named entities, both - -- implicitly and explicitly defined, that inherit the attribute, as - -- defined below: - List := Get_Entity_Name_List (Spec); - if List = Iir_Flist_All then - -- o If the reserved word ALL is supplied, then the attribute - -- specification applies to all named entities of the specified - -- class that are declared in the immediatly enclosing - -- declarative part. - Res := Sem_Named_Entities (Scope, Null_Iir, Spec, True); - if Res = False and then Is_Warning_Enabled (Warnid_Specs) then - Warning_Msg_Sem - (Warnid_Specs, +Spec, - "attribute specification apply to no named entity"); - end if; - elsif List = Iir_Flist_Others then - -- o If the reserved word OTHERS is supplied, then the attribute - -- specification applies to named entities of the specified class - -- that are declared in the immediately enclosing declarative - -- part, provided that each such entity is not explicitly named - -- in the entity name list of a previous attribute specification - -- for the given attribute. - Res := Sem_Named_Entities (Scope, Null_Iir, Spec, False); - if Res = False and then Is_Warning_Enabled (Warnid_Specs) then - Warning_Msg_Sem - (Warnid_Specs, +Spec, - "attribute specification apply to no named entity"); - end if; - elsif List = Null_Iir_Flist then - pragma Assert (Flags.Flag_Force_Analysis); - null; - else - -- o If a list of entity designators is supplied, then the - -- attribute specification applies to the named entities denoted - -- by those designators. - declare - El : Iir; - begin - for I in Flist_First .. Flist_Last (List) loop - El := Get_Nth_Element (List, I); - if Get_Kind (El) = Iir_Kind_Signature then - Sem_Signature_Entity_Designator (El, Spec); - else - -- LRM 5.1 - -- It is an error if the class of those names is not the - -- same as that denoted by entity class. - if not Sem_Named_Entities (Scope, El, Spec, True) then - Error_Attribute_Specification (El); - end if; - end if; - end loop; - end; - end if; - - -- Reverse the chain of attribute value in specification, so that they - -- are in textual order. This is important if the expression is not - -- static. - declare - El : Iir; - New_El : Iir; - Tmp : Iir; - begin - El := Get_Attribute_Value_Spec_Chain (Spec); - New_El := Null_Iir; - while Is_Valid (El) loop - Tmp := Get_Spec_Chain (El); - Set_Spec_Chain (El, New_El); - New_El := El; - El := Tmp; - end loop; - Set_Attribute_Value_Spec_Chain (Spec, New_El); - end; - end Sem_Attribute_Specification; - - procedure Check_Post_Attribute_Specification - (Attr_Spec_Chain : Iir; Decl : Iir) - is - use Vhdl.Tokens; - - Has_Error : Boolean; - Spec : Iir; - Decl_Class : Token_Type; - Decl_Class2 : Token_Type; - Ent_Class : Token_Type; - begin - -- Some declaration items can never be attributed. - Decl_Class2 := Tok_Eof; - case Get_Kind (Decl) is - when Iir_Kind_Function_Body - | Iir_Kind_Procedure_Body - | Iir_Kind_Use_Clause - | Iir_Kind_Attribute_Declaration - | Iir_Kinds_Signal_Attribute - | Iir_Kind_Disconnection_Specification => - return; - when Iir_Kind_Anonymous_Type_Declaration => - -- A physical type definition declares units. - if Get_Kind (Get_Type_Definition (Decl)) - = Iir_Kind_Physical_Type_Definition - then - Decl_Class := Tok_Units; - else - return; - end if; - when Iir_Kind_Attribute_Specification => - Decl_Class := Get_Entity_Class (Decl); - when Iir_Kind_Type_Declaration => - Decl_Class := Tok_Type; - -- An enumeration type declares literals. - if Get_Kind (Get_Type_Definition (Decl)) - = Iir_Kind_Enumeration_Type_Definition - then - Decl_Class2 := Tok_Literal; - end if; - when Iir_Kind_Non_Object_Alias_Declaration - | Iir_Kind_Object_Alias_Declaration => - Decl_Class := Get_Entity_Class_Kind (Get_Name (Decl)); - -- NOTE: for non-object alias that declares an enumeration type - -- or a physical type, no need to set decl_class2, since - -- all implicit aliases are checked. - when others => - Decl_Class := Get_Entity_Class_Kind (Decl); - end case; - - Spec := Attr_Spec_Chain; - -- Skip itself (newly added, therefore first of the chain). - if Spec = Decl then - Spec := Get_Attribute_Specification_Chain (Spec); - end if; - while Spec /= Null_Iir loop - pragma Assert (Get_Entity_Name_List (Spec) in Iir_Flists_All_Others); - Ent_Class := Get_Entity_Class (Spec); - if Ent_Class = Decl_Class or Ent_Class = Decl_Class2 then - Has_Error := False; - - if Get_Kind (Decl) = Iir_Kind_Attribute_Specification then - -- LRM 5.1 Attribute specifications - -- An attribute specification with the entity name list OTHERS - -- or ALL for a given entity class that appears in a - -- declarative part must be the last such specification for the - -- given attribute for the given entity class in that - -- declarative part. - if Get_Identifier (Get_Attribute_Designator (Decl)) - = Get_Identifier (Get_Attribute_Designator (Spec)) - then - Error_Msg_Sem - (+Decl, "no attribute specification may follow an " - & "all/others spec", Cont => True); - Has_Error := True; - end if; - else - -- LRM 5.1 Attribute specifications - -- It is an error if a named entity in the specificied entity - -- class is declared in a given declarative part following such - -- an attribute specification. - Error_Msg_Sem - (+Decl, "no named entity may follow an all/others attribute " - & "specification", Cont => True); - Has_Error := True; - end if; - if Has_Error then - Error_Msg_Sem - (+Spec, "(previous all/others specification for the given " - &"entity class)"); - end if; - end if; - Spec := Get_Attribute_Specification_Chain (Spec); - end loop; - end Check_Post_Attribute_Specification; - - -- Compare ATYPE and TYPE_MARK. - -- ATYPE is a type definition, which can be anonymous. - -- TYPE_MARK is a subtype definition, established from a type mark. - -- Therefore, it is the name of a type or a subtype. - -- Return TRUE iff the type mark of ATYPE is TYPE_MARK. - function Is_Same_Type_Mark (Atype : Iir; Type_Mark : Iir) - return Boolean is - begin - if Get_Kind (Atype) in Iir_Kinds_Subtype_Definition - and then Is_Anonymous_Type_Definition (Atype) - then - -- FIXME: to be removed; used to catch uninitialized type_mark. - if Get_Subtype_Type_Mark (Atype) = Null_Iir then - raise Internal_Error; - end if; - return Get_Type (Get_Subtype_Type_Mark (Atype)) = Type_Mark; - else - return Atype = Type_Mark; - end if; - end Is_Same_Type_Mark; - - procedure Sem_Disconnection_Specification - (Dis : Iir_Disconnection_Specification) - is - Type_Mark : Iir; - Atype : Iir; - Time_Expr : Iir; - List : Iir_Flist; - El : Iir; - Sig : Iir; - Prefix : Iir; - begin - -- Sem type mark. - Type_Mark := Get_Type_Mark (Dis); - Type_Mark := Sem_Type_Mark (Type_Mark); - Set_Type_Mark (Dis, Type_Mark); - Atype := Get_Type (Type_Mark); - - -- LRM93 5.3 - -- The time expression in a disconnection specification must be static - -- and must evaluate to a non-negative value. - Time_Expr := Sem_Expression - (Get_Expression (Dis), Time_Subtype_Definition); - if Time_Expr /= Null_Iir then - Check_Read (Time_Expr); - Set_Expression (Dis, Time_Expr); - if Get_Expr_Staticness (Time_Expr) < Globally then - Error_Msg_Sem (+Time_Expr, "time expression must be static"); - end if; - end if; - - List := Get_Signal_List (Dis); - if List in Iir_Flists_All_Others then - -- FIXME: checks todo - null; - else - for I in Flist_First .. Flist_Last (List) loop - El := Get_Nth_Element (List, I); - - if Is_Error (El) then - Sig := Null_Iir; - else - Sem_Name (El); - El := Finish_Sem_Name (El); - Set_Nth_Element (List, I, El); - - Sig := Get_Named_Entity (El); - Sig := Name_To_Object (Sig); - end if; - - if Sig /= Null_Iir then - Set_Type (El, Get_Type (Sig)); - Prefix := Get_Object_Prefix (Sig); - -- LRM93 5.3 - -- Each signal name in a signal list in a guarded signal - -- specification must be a locally static name that - -- denotes a guarded signal. - case Get_Kind (Prefix) is - when Iir_Kind_Signal_Declaration - | Iir_Kind_Interface_Signal_Declaration => - null; - when others => - Error_Msg_Sem (+El, "object must be a signal"); - return; - end case; - if Get_Name_Staticness (Sig) /= Locally then - Error_Msg_Sem (+El, "signal name must be locally static"); - end if; - if not Get_Guarded_Signal_Flag (Prefix) then - Error_Msg_Sem (+El, "signal must be a guarded signal"); - end if; - Set_Has_Disconnect_Flag (Prefix, True); - - -- LRM93 5.3 - -- If the guarded signal is a declared signal or a slice of - -- thereof, the type mark must be the same as the type mark - -- indicated in the guarded signal specification. - -- If the guarded signal is an array element of an explicitly - -- declared signal, the type mark must be the same as the - -- element subtype indication in the (explicit or implicit) - -- array type declaration that declares the base type of the - -- explicitly declared signal. - -- If the guarded signal is a record element of an explicitly - -- declared signal, then the type mark must be the same as - -- the type mark in the element subtype definition of the - -- record type declaration that declares the type of the - -- explicitly declared signal. - -- FIXME: to be checked: the expression type (as set by - -- sem_expression) may be a base type instead of a type mark. - if not Is_Same_Type_Mark (Get_Type (Sig), Atype) then - Error_Msg_Sem (+El, "type mark and signal type mismatch"); - end if; - - -- LRM93 5.3 - -- Each signal must be declared in the declarative part - -- enclosing the disconnection specification. - -- FIXME: todo. - elsif not Is_Error (El) - and then Get_Designated_Entity (El) /= Error_Mark - then - Error_Msg_Sem (+El, "name must designate a signal"); - end if; - end loop; - end if; - end Sem_Disconnection_Specification; - - -- Analyze entity aspect ASPECT and return the entity declaration. - -- Return NULL_IIR if not found. - function Sem_Entity_Aspect (Aspect : Iir) return Iir is - begin - case Get_Kind (Aspect) is - when Iir_Kind_Entity_Aspect_Entity => - declare - Entity_Name : Iir; - Entity : Iir; - Arch_Name : Iir; - Arch_Unit : Iir; - begin - -- The entity. - Entity_Name := Sem_Denoting_Name (Get_Entity_Name (Aspect)); - Set_Entity_Name (Aspect, Entity_Name); - Entity := Get_Named_Entity (Entity_Name); - if Entity = Error_Mark then - return Null_Iir; - end if; - if Get_Kind (Entity) /= Iir_Kind_Entity_Declaration then - Error_Class_Match (Entity_Name, "entity"); - return Null_Iir; - end if; - -- Note: dependency is added by Sem_Denoting_Name. - - -- Check architecture. - Arch_Name := Get_Architecture (Aspect); - if Arch_Name /= Null_Iir then - Arch_Unit := Libraries.Find_Secondary_Unit - (Get_Design_Unit (Entity), Get_Identifier (Arch_Name)); - if Arch_Unit /= Null_Iir then - -- The architecture is known. - if Get_Date_State (Arch_Unit) >= Date_Parse then - -- And loaded! - Arch_Unit := Get_Library_Unit (Arch_Unit); - end if; - Set_Named_Entity (Arch_Name, Arch_Unit); - Xref_Ref (Arch_Name, Arch_Unit); - end if; - - -- FIXME: may emit a warning if the architecture does not - -- exist. - -- Note: the design needs the architecture. - Add_Dependence (Aspect); - end if; - return Entity; - end; - - when Iir_Kind_Entity_Aspect_Configuration => - declare - Conf_Name : Iir; - Conf : Iir; - begin - Conf_Name := - Sem_Denoting_Name (Get_Configuration_Name (Aspect)); - Set_Configuration_Name (Aspect, Conf_Name); - Conf := Get_Named_Entity (Conf_Name); - if Is_Error (Conf) then - return Null_Iir; - elsif Get_Kind (Conf) /= Iir_Kind_Configuration_Declaration then - Error_Class_Match (Conf, "configuration"); - return Null_Iir; - end if; - - return Get_Entity (Conf); - end; - - when Iir_Kind_Entity_Aspect_Open => - return Null_Iir; - - when others => - Error_Kind ("sem_entity_aspect", Aspect); - end case; - end Sem_Entity_Aspect; - - procedure Sem_Binding_Indication (Bind : Iir_Binding_Indication; - Parent : Iir; - Primary_Entity_Aspect : Iir) - is - Entity_Aspect : Iir; - Entity : Iir_Entity_Declaration; - begin - if Bind = Null_Iir then - raise Internal_Error; - end if; - - Entity_Aspect := Get_Entity_Aspect (Bind); - if Entity_Aspect /= Null_Iir then - Entity := Sem_Entity_Aspect (Entity_Aspect); - - -- LRM93 5.2.1 Binding Indication - -- An incremental binding indication must not have an entity aspect. - if Primary_Entity_Aspect /= Null_Iir then - Error_Msg_Sem - (+Bind, "entity aspect not allowed for incremental binding"); - end if; - - -- Return now in case of error. - if Entity = Null_Iir then - return; - end if; - else - -- LRM93 5.2.1 - -- When a binding indication is used in an explicit configuration - -- specification, it is an error if the entity aspect is absent. - case Get_Kind (Parent) is - when Iir_Kind_Component_Configuration => - if Primary_Entity_Aspect = Null_Iir then - Entity := Null_Iir; - else - case Get_Kind (Primary_Entity_Aspect) is - when Iir_Kind_Entity_Aspect_Entity => - Entity := Get_Entity (Primary_Entity_Aspect); - when others => - Error_Kind - ("sem_binding_indication", Primary_Entity_Aspect); - end case; - end if; - when Iir_Kind_Configuration_Specification => - Error_Msg_Sem - (+Bind, - "entity aspect required in a configuration specification"); - return; - when others => - raise Internal_Error; - end case; - end if; - if Entity = Null_Iir - or else Get_Kind (Entity) = Iir_Kind_Entity_Aspect_Open - then - -- LRM 5.2.1.1 Entity aspect - -- The third form of entity aspect is used to specify that the - -- indiciation of the design entity is to be defined. In this case, - -- the immediatly enclosing binding indication is said to not - -- imply any design entity. Furthermore, the immediatly enclosing - -- binding indication must not include a generic map aspect or a - -- port map aspect. - if Get_Generic_Map_Aspect_Chain (Bind) /= Null_Iir - or else Get_Port_Map_Aspect_Chain (Bind) /= Null_Iir - then - Error_Msg_Sem - (+Bind, "map aspect not allowed for open entity aspect"); - return; - end if; - else - Sem_Generic_Port_Association_Chain (Entity, Bind); - - -- LRM 5.2.1 Binding Indication - -- If the generic map aspect or port map aspect of a binding - -- indication is not present, then the default rules as described - -- in 5.2.2 apply. - -- GHDL: done in canon - end if; - end Sem_Binding_Indication; - - -- Set configuration_specification or component_configuration SPEC to - -- component instantiation COMP. - procedure Apply_Configuration_Specification - (Comp : Iir_Component_Instantiation_Statement; - Spec : Iir; - Primary_Entity_Aspect : in out Iir) - is - Prev_Spec : Iir; - Prev_Conf : Iir; - - procedure Prev_Spec_Error is - begin - Error_Msg_Sem - (+Spec, "%n is alreay bound by a configuration specification", - (1 => +Comp), Cont => True); - Error_Msg_Sem (+Prev_Spec, "(previous is %n)", +Prev_Spec); - end Prev_Spec_Error; - - Prev_Binding : Iir_Binding_Indication; - Prev_Entity_Aspect : Iir; - begin - Prev_Spec := Get_Configuration_Specification (Comp); - if Prev_Spec /= Null_Iir then - case Get_Kind (Spec) is - when Iir_Kind_Configuration_Specification => - Prev_Spec_Error; - return; - when Iir_Kind_Component_Configuration => - if Flags.Vhdl_Std = Vhdl_87 then - Prev_Spec_Error; - Error_Msg_Sem - (+Spec, "(incremental binding is not allowed in vhdl87)"); - return; - end if; - -- Incremental binding. - Prev_Binding := Get_Binding_Indication (Prev_Spec); - if Prev_Binding /= Null_Iir then - Prev_Entity_Aspect := Get_Entity_Aspect (Prev_Binding); - if Primary_Entity_Aspect = Null_Iir then - Primary_Entity_Aspect := Prev_Entity_Aspect; - else - -- FIXME: checks to do ? - null; - end if; - end if; - when others => - Error_Kind ("apply_configuration_specification", Spec); - end case; - end if; - Prev_Conf := Get_Component_Configuration (Comp); - if Prev_Conf /= Null_Iir then - case Get_Kind (Spec) is - when Iir_Kind_Configuration_Specification => - -- How can this happen ? - raise Internal_Error; - when Iir_Kind_Component_Configuration => - Error_Msg_Sem - (+Spec, "%n is already bound by a component configuration", - (1 => +Comp), Cont => True); - Error_Msg_Sem (+Prev_Conf, "(previous is %n)", +Prev_Conf); - return; - when others => - Error_Kind ("apply_configuration_specification(2)", Spec); - end case; - end if; - if Get_Kind (Spec) = Iir_Kind_Configuration_Specification then - Set_Configuration_Specification (Comp, Spec); - end if; - Set_Component_Configuration (Comp, Spec); - end Apply_Configuration_Specification; - - -- Analyze component_configuration or configuration_specification SPEC. - -- STMTS is the concurrent statement list related to SPEC. - procedure Sem_Component_Specification - (Parent_Stmts : Iir; Spec : Iir; Primary_Entity_Aspect : out Iir) - is - function Apply_Component_Specification - (Chain : Iir; Check_Applied : Boolean) return Boolean - is - Comp : constant Iir := Get_Named_Entity (Get_Component_Name (Spec)); - El : Iir; - Res : Boolean; - begin - if Chain = Null_Iir then - return False; - end if; - - El := Get_Concurrent_Statement_Chain (Chain); - Res := False; - while El /= Null_Iir loop - case Get_Kind (El) is - when Iir_Kind_Component_Instantiation_Statement => - if Is_Component_Instantiation (El) - and then - Get_Named_Entity (Get_Instantiated_Unit (El)) = Comp - and then - (not Check_Applied - or else Get_Component_Configuration (El) = Null_Iir) - then - Apply_Configuration_Specification - (El, Spec, Primary_Entity_Aspect); - Res := True; - end if; - when Iir_Kind_For_Generate_Statement - | Iir_Kind_If_Generate_Statement => - if False and then Flags.Vhdl_Std = Vhdl_87 then - Res := Res - or Apply_Component_Specification (El, Check_Applied); - end if; - when others => - null; - end case; - El := Get_Chain (El); - end loop; - return Res; - end Apply_Component_Specification; - - List : Iir_Flist; - El : Iir; - Inter : Sem_Scopes.Name_Interpretation_Type; - Comp : Iir; - Comp_Name : Iir; - Inst : Iir; - Inst_Unit : Iir; - begin - Primary_Entity_Aspect := Null_Iir; - Comp_Name := Get_Component_Name (Spec); - if Is_Error (Comp_Name) then - pragma Assert (Flags.Flag_Force_Analysis); - return; - end if; - Comp_Name := Sem_Denoting_Name (Comp_Name); - Set_Component_Name (Spec, Comp_Name); - Comp := Get_Named_Entity (Comp_Name); - if Get_Kind (Comp) /= Iir_Kind_Component_Declaration then - Error_Class_Match (Comp_Name, "component"); - return; - end if; - - List := Get_Instantiation_List (Spec); - if List = Iir_Flist_All then - -- LRM93 5.2 - -- * If the reserved word ALL is supplied, then the configuration - -- specification applies to all instances of the specified - -- component declaration whose labels are (implicitly) declared - -- in the immediately enclosing declarative region part. - -- This rule applies only to those component instantiation - -- statements whose corresponding instantiated units name - -- component. - if not Apply_Component_Specification (Parent_Stmts, False) - and then Is_Warning_Enabled (Warnid_Specs) - then - Warning_Msg_Sem (Warnid_Specs, +Spec, - "component specification applies to no instance"); - end if; - elsif List = Iir_Flist_Others then - -- LRM93 5.2 - -- * If the reserved word OTHERS is supplied, then the - -- configuration specification applies to instances of the - -- specified component declaration whoce labels are (implicitly) - -- declared in the immediatly enclosing declarative part, - -- provided that each such component instance is not explicitly - -- names in the instantiation list of a previous configuration - -- specification. - -- This rule applies only to those component instantiation - -- statements whose corresponding instantiated units name - -- components. - if not Apply_Component_Specification (Parent_Stmts, True) - and then Is_Warning_Enabled (Warnid_Specs) - then - Warning_Msg_Sem (Warnid_Specs, +Spec, - "component specification applies to no instance"); - end if; - else - -- LRM93 5.2 - -- * If a list of instantiation labels is supplied, then the - -- configuration specification applies to the corresponding - -- component instances. - -- Such labels must be (implicitly) declared within the - -- immediatly enclosing declarative part. - -- It is an error if these component instances are not instances - -- of the component declaration named in the component - -- specification. - -- It is also an error if any of the labels denote a component - -- instantiation statement whose corresponding instantiated unit - -- does not name a component. - -- FIXME: error message are *really* cryptic. - for I in Flist_First .. Flist_Last (List) loop - El := Get_Nth_Element (List, I); - Inter := Sem_Scopes.Get_Interpretation (Get_Identifier (El)); - if not Valid_Interpretation (Inter) then - Error_Msg_Sem - (+El, "no component instantation with label %i", +El); - elsif not Is_In_Current_Declarative_Region (Inter) then - -- FIXME. - Error_Msg_Sem (+El, "label not in block declarative part"); - else - Inst := Get_Declaration (Inter); - if Get_Kind (Inst) /= Iir_Kind_Component_Instantiation_Statement - then - Error_Msg_Sem - (+El, "label does not denote an instantiation"); - else - Inst_Unit := Get_Instantiated_Unit (Inst); - if Is_Entity_Instantiation (Inst) - or else (Get_Kind (Get_Named_Entity (Inst_Unit)) - /= Iir_Kind_Component_Declaration) - then - Error_Msg_Sem - (+El, "specification does not apply to " - & "direct instantiation"); - elsif Get_Named_Entity (Inst_Unit) /= Comp then - Error_Msg_Sem (+El, "component names mismatch"); - else - Apply_Configuration_Specification - (Inst, Spec, Primary_Entity_Aspect); - Xref_Ref (El, Inst); - Set_Named_Entity (El, Inst); - Set_Is_Forward_Ref (El, True); - end if; - end if; - end if; - end loop; - end if; - end Sem_Component_Specification; - - procedure Sem_Configuration_Specification - (Parent_Stmts : Iir; Conf : Iir_Configuration_Specification) - is - Primary_Entity_Aspect : Iir; - Component : Iir; - begin - Sem_Component_Specification (Parent_Stmts, Conf, Primary_Entity_Aspect); - Component := Get_Component_Name (Conf); - if Is_Error (Component) then - pragma Assert (Flags.Flag_Force_Analysis); - return; - end if; - Component := Get_Named_Entity (Component); - - -- Return now in case of error. - if Get_Kind (Component) /= Iir_Kind_Component_Declaration then - return; - end if; - -- Extend scope of component interface declaration. - Sem_Scopes.Open_Scope_Extension; - Sem_Scopes.Add_Component_Declarations (Component); - Sem_Binding_Indication - (Get_Binding_Indication (Conf), Conf, Primary_Entity_Aspect); - -- FIXME: check default port and generic association. - Sem_Scopes.Close_Scope_Extension; - end Sem_Configuration_Specification; - - function Sem_Create_Default_Binding_Indication - (Comp : Iir_Component_Declaration; - Entity_Unit : Iir_Design_Unit; - Parent : Iir; - Force : Boolean; - Create_Map_Aspect : Boolean) - return Iir_Binding_Indication - is - Entity : Iir_Entity_Declaration; - Entity_Name : Iir; - Aspect : Iir; - Res : Iir; - Design_Unit : Iir_Design_Unit; - begin - -- LRM 5.2.2 - -- The default binding indication consists of a default entity aspect, - -- together with a default generic map aspect and a default port map - -- aspect, as appropriate. - - if Entity_Unit = Null_Iir then - if not Force then - return Null_Iir; - end if; - - -- LRM 5.2.2 - -- If no visible entity declaration has the same simple name as that - -- of the instantiated component, then the default entity aspect is - -- OPEN. - Aspect := Create_Iir (Iir_Kind_Entity_Aspect_Open); - Location_Copy (Aspect, Comp); - Res := Create_Iir (Iir_Kind_Binding_Indication); - Set_Entity_Aspect (Res, Aspect); - return Res; - else - -- LRM 5.2.2 - -- Otherwise, the default entity aspect is of the form: - -- ENTITY entity_name ( architecture_identifier) - -- where the entity name is the simple name of the instantiated - -- component and the architecture identifier is the same as the - -- simple name of the most recently analyzed architecture body - -- associated with the entity declaration. - -- - -- If this rule is applied either to a binding indication contained - -- within a configuration specification or to a component - -- configuration that does not contain an explicit inner block - -- configuration, then the architecture identifier is determined - -- during elaboration of the design hierarchy containing the binding - -- indication. - -- - -- Likewise, if a component instantiation statement contains an - -- instantiated unit containing the reserved word ENTITY, but does - -- not contain an explicitly specified architecture identifier, this - -- rule is applied during the elaboration of the design hierarchy - -- containing a component instantiation statement. - -- - -- In all other cases, this rule is applied during analysis of the - -- binding indication. - -- - -- It is an error if there is no architecture body associated with - -- the entity declaration denoted by an entity name that is the - -- simple name of the instantiated component. - null; - end if; - - Design_Unit := Load_Primary_Unit - (Get_Library (Get_Design_File (Entity_Unit)), - Get_Identifier (Get_Library_Unit (Entity_Unit)), - Parent); - if Design_Unit = Null_Iir then - -- Found an entity which is not in the library. - raise Internal_Error; - end if; - - Entity := Get_Library_Unit (Design_Unit); - - Res := Create_Iir (Iir_Kind_Binding_Indication); - Aspect := Create_Iir (Iir_Kind_Entity_Aspect_Entity); - Location_Copy (Aspect, Parent); - - -- Create a name for the entity. As this is a default binding - -- indication, the design unit does *NOT* depend on the entity, so the - -- reference is a forward reference. - Entity_Name := Build_Simple_Name (Entity, Parent); - Set_Is_Forward_Ref (Entity_Name, True); - - Set_Entity_Name (Aspect, Entity_Name); - Set_Entity_Aspect (Res, Aspect); - - if Create_Map_Aspect then - -- LRM 5.2.2 - -- The default binding indication includes a default generic map - -- aspect if the design entity implied by the entity aspect contains - -- formal generics. - Set_Generic_Map_Aspect_Chain - (Res, - Create_Default_Map_Aspect (Comp, Entity, Map_Generic, Parent)); - - -- LRM 5.2.2 - -- The default binding indication includes a default port map aspect - -- if the design entity implied by the entity aspect contains formal - -- ports. - Set_Port_Map_Aspect_Chain - (Res, Create_Default_Map_Aspect (Comp, Entity, Map_Port, Parent)); - end if; - - return Res; - end Sem_Create_Default_Binding_Indication; - - -- LRM 5.2.2 - -- The default binding indication includes a default generic map aspect - -- if the design entity implied by the entity aspect contains formal - -- generics. - -- - -- The default generic map aspect associates each local generic in - -- the corresponding component instantiation (if any) with a formal - -- of the same simple name. - -- It is an error if such a formal does not exist, or if its mode and - -- type are not appropriate for such an association. - -- Any remaining unassociated formals are associated with the actual - -- designator OPEN. - - -- LRM 5.2.2 - -- The default binding indication includes a default port map aspect - -- if the design entity implied by the entity aspect contains formal - -- ports. - -- - -- The default port map aspect associates each local port in the - -- corresponding component instantiation (if any) with a formal of - -- the same simple name. - -- It is an error if such a formal does not exist, or if its mode - -- and type are not appropriate for such an association. - -- Any remaining unassociated formals are associated with the actual - -- designator OPEN. - function Create_Default_Map_Aspect - (Comp : Iir; Entity : Iir; Kind : Map_Kind_Type; Parent : Iir) - return Iir - is - Error : Boolean; - - procedure Error_Header is - begin - if Error then - return; - end if; - Error_Msg_Sem - (+Parent, "for default port binding of %n:", - (1 => +Parent), Cont => True); - Error := True; - end Error_Header; - - Res, Last : Iir; - Comp_El, Ent_El : Iir; - Assoc : Iir; - Name : Iir; - Found : Natural; - Comp_Chain : Iir; - Ent_Chain : Iir; - begin - case Kind is - when Map_Generic => - Ent_Chain := Get_Generic_Chain (Entity); - Comp_Chain := Get_Generic_Chain (Comp); - when Map_Port => - Ent_Chain := Get_Port_Chain (Entity); - Comp_Chain := Get_Port_Chain (Comp); - end case; - - -- No error found yet. - Error := False; - - Sub_Chain_Init (Res, Last); - Found := 0; - Ent_El := Ent_Chain; - while Ent_El /= Null_Iir loop - -- Find the component generic/port with the same name. - Comp_El := Find_Name_In_Chain (Comp_Chain, Get_Identifier (Ent_El)); - if Comp_El = Null_Iir then - Assoc := Create_Iir (Iir_Kind_Association_Element_Open); - Location_Copy (Assoc, Parent); - else - if Are_Nodes_Compatible (Comp_El, Ent_El) = Not_Compatible then - Error_Header; - Error_Msg_Sem - (+Parent, "type of %n declared at %l", - (+Comp_El, +Comp_El), Cont => True); - Error_Msg_Sem - (+Parent, "not compatible with type of %n declared at %l", - (+Ent_El, +Ent_El)); - elsif Kind = Map_Port - and then not Check_Port_Association_Mode_Restrictions - (Ent_El, Comp_El, Null_Iir) - then - Error_Header; - Error_Msg_Sem (+Parent, "cannot associate " - & Get_Mode_Name (Get_Mode (Ent_El)) - & " %n declared at %l", - (+Ent_El, +Ent_El), Cont => True); - Error_Msg_Sem (+Parent, "with actual port of mode " - & Get_Mode_Name (Get_Mode (Comp_El)) - & " declared at %l", +Comp_El); - end if; - Assoc := Create_Iir (Iir_Kind_Association_Element_By_Expression); - Location_Copy (Assoc, Parent); - Name := Build_Simple_Name (Comp_El, Parent); - Set_Type (Name, Get_Type (Comp_El)); - Set_Actual (Assoc, Name); - if Kind = Map_Port and then not Error then - Check_Port_Association_Bounds_Restrictions - (Ent_El, Comp_El, Assoc); - end if; - Found := Found + 1; - end if; - Set_Whole_Association_Flag (Assoc, True); - - -- Create the formal name. This is a forward reference as the - -- current design unit does not depend on the entity. - Name := Build_Simple_Name (Ent_El, Parent); - Set_Is_Forward_Ref (Name, True); - Set_Type (Name, Get_Type (Ent_El)); - Set_Formal (Assoc, Name); - - if Kind = Map_Port - and then not Error - and then Comp_El /= Null_Iir - then - Set_Collapse_Signal_Flag - (Assoc, Can_Collapse_Signals (Assoc, Ent_El)); - end if; - Sub_Chain_Append (Res, Last, Assoc); - Ent_El := Get_Chain (Ent_El); - end loop; - if Iir_Chains.Get_Chain_Length (Comp_Chain) /= Found then - -- At least one component generic/port cannot be associated with - -- the entity one. - - -- Disp unassociated interfaces. - Comp_El := Comp_Chain; - while Comp_El /= Null_Iir loop - Ent_El := Find_Name_In_Chain (Ent_Chain, Get_Identifier (Comp_El)); - if Ent_El = Null_Iir then - Error_Header; - Error_Msg_Sem (+Parent, "%n has no association in %n", - (+Comp_El, +Entity)); - end if; - Comp_El := Get_Chain (Comp_El); - end loop; - end if; - if Error then - return Null_Iir; - else - return Res; - end if; - end Create_Default_Map_Aspect; - - -- LRM93 §5.2.2 - function Get_Visible_Entity_Declaration (Comp: Iir_Component_Declaration) - return Iir_Design_Unit - is - -- Return the design_unit if DECL is an entity declaration or the - -- design unit of an entity declaration. Otherwise return Null_Iir. - -- This double check is needed as the interpretation may be both. - function Is_Entity_Declaration (Decl : Iir) return Iir is - begin - if Get_Kind (Decl) = Iir_Kind_Entity_Declaration then - return Get_Design_Unit (Decl); - elsif Get_Kind (Decl) = Iir_Kind_Design_Unit - and then - Get_Kind (Get_Library_Unit (Decl)) = Iir_Kind_Entity_Declaration - then - return Decl; - else - return Null_Iir; - end if; - end Is_Entity_Declaration; - - Name : constant Name_Id := Get_Identifier (Comp); - Inter : Name_Interpretation_Type; - Decl : Iir; - Res : Iir; - Target_Lib : Iir; - begin - Inter := Get_Interpretation (Name); - - if Valid_Interpretation (Inter) then - -- LRM93 5.2.2 Default binding indication - -- A visible entity declaration is either: - -- - -- a) An entity declaration that has the same simple name as that of - -- the instantiated component and that is directly visible - -- (see 10.3), - Decl := Get_Declaration (Inter); - Res := Is_Entity_Declaration (Decl); - if Res /= Null_Iir then - return Res; - end if; - - -- b) An entity declaration that has the same simple name that of - -- the instantiated component and that would be directly - -- visible in the absence of a directly visible (see 10.3) - -- component declaration with the same simple name as that - -- of the entity declaration, or - if Get_Kind (Decl) = Iir_Kind_Component_Declaration then - Inter := Get_Under_Interpretation (Name); - if Valid_Interpretation (Inter) then - Decl := Get_Declaration (Inter); - Res := Is_Entity_Declaration (Decl); - if Res /= Null_Iir then - return Res; - end if; - end if; - end if; - end if; - - -- VHDL02: - -- c) An entity declaration denoted by "L.C", where L is the target - -- library and C is the simple name of the instantiated component. - -- The target library is the library logical name of the library - -- containing the design unit in which the component C is - -- declared. - if Flags.Flag_Syn_Binding - or Flags.Vhdl_Std >= Vhdl_02 - or Flags.Vhdl_Std = Vhdl_93c - then - -- Find target library. - Target_Lib := Comp; - while Get_Kind (Target_Lib) /= Iir_Kind_Library_Declaration loop - Target_Lib := Get_Parent (Target_Lib); - end loop; - - Decl := Libraries.Find_Primary_Unit (Target_Lib, Name); - if Decl /= Null_Iir then - Res := Is_Entity_Declaration (Decl); - if Res /= Null_Iir then - return Res; - end if; - end if; - end if; - - -- --syn-binding - -- Search for any entity. - if Flags.Flag_Syn_Binding then - Decl := Libraries.Find_Entity_For_Component (Name); - if Decl /= Null_Iir then - return Decl; - end if; - end if; - - return Null_Iir; - end Get_Visible_Entity_Declaration; - - -- Explain why there is no default binding for COMP. - procedure Explain_No_Visible_Entity (Comp: Iir_Component_Declaration) - is - Inter : Name_Interpretation_Type; - Name : Name_Id; - Decl : Iir; - begin - Name := Get_Identifier (Comp); - Inter := Get_Interpretation (Name); - - if Valid_Interpretation (Inter) then - -- LRM93 5.2.2 Default binding indication - -- A visible entity declaration is either: - -- - -- a) An entity declaration that has the same simple name as that of - -- the instantiated component and that is directly visible - -- (see 10.3), - Decl := Get_Declaration (Inter); - Warning_Msg_Elab - (Warnid_Default_Binding, Decl, "visible declaration for %i", +Name); - - -- b) An entity declaration that has the same simple name that of - -- the instantiated component and that would be directly - -- visible in the absence of a directly visible (see 10.3) - -- component declaration with the same simple name as that - -- of the entity declaration, or - if Get_Kind (Decl) = Iir_Kind_Component_Declaration then - Inter := Get_Under_Interpretation (Name); - if Valid_Interpretation (Inter) then - Decl := Get_Declaration (Inter); - Warning_Msg_Elab (Warnid_Default_Binding, Comp, - "interpretation behind the component is %n", - +Decl); - end if; - end if; - end if; - - -- VHDL02: - -- c) An entity declaration denoted by "L.C", where L is the target - -- library and C is the simple name of the instantiated component. - -- The target library is the library logical name of the library - -- containing the design unit in which the component C is - -- declared. - if Flags.Vhdl_Std >= Vhdl_02 - or else Flags.Vhdl_Std = Vhdl_93c - then - Decl := Comp; - while Get_Kind (Decl) /= Iir_Kind_Library_Declaration loop - Decl := Get_Parent (Decl); - end loop; - - Warning_Msg_Elab (Warnid_Default_Binding, Comp, - "no entity %i in %n", (+Name, +Decl)); - end if; - end Explain_No_Visible_Entity; - - procedure Sem_Specification_Chain (Decls_Parent : Iir; Parent_Stmts: Iir) - is - Decl: Iir; - begin - Decl := Get_Declaration_Chain (Decls_Parent); - while Decl /= Null_Iir loop - case Get_Kind (Decl) is - when Iir_Kind_Configuration_Specification => - Sem_Configuration_Specification (Parent_Stmts, Decl); - when others => - null; - end case; - Decl := Get_Chain (Decl); - end loop; - end Sem_Specification_Chain; -end Sem_Specs; |