-- Semantic analysis pass.
-- 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 <gnu.org/licenses>.
with Errorout; use Errorout;
with Libraries;
with Std_Names;
with Flags; use Flags;
with Str_Table;
with Vhdl.Errors; use Vhdl.Errors;
with Vhdl.Std_Package; use Vhdl.Std_Package;
with Vhdl.Ieee.Std_Logic_1164;
with Vhdl.Sem_Scopes; use Vhdl.Sem_Scopes;
with Vhdl.Sem_Expr; use Vhdl.Sem_Expr;
with Vhdl.Sem_Names; use Vhdl.Sem_Names;
with Vhdl.Sem_Specs; use Vhdl.Sem_Specs;
with Vhdl.Sem_Decls; use Vhdl.Sem_Decls;
with Vhdl.Sem_Assocs; use Vhdl.Sem_Assocs;
with Vhdl.Sem_Types;
with Vhdl.Sem_Inst;
with Vhdl.Sem_Lib; use Vhdl.Sem_Lib;
with Vhdl.Sem_Psl;
with Vhdl.Utils; use Vhdl.Utils;
with Vhdl.Sem_Utils;
with Vhdl.Sem_Stmts; use Vhdl.Sem_Stmts;
with Vhdl.Nodes_Utils;
with Vhdl.Xrefs; use Vhdl.Xrefs;
with Vhdl.Elocations;
package body Vhdl.Sem is
-- Forward declarations.
procedure Sem_Context_Clauses (Unit: Iir);
procedure Sem_Block_Configuration
(Block_Conf : Iir_Block_Configuration; Father: Iir);
procedure Sem_Component_Configuration
(Conf : Iir_Component_Configuration; Father : Iir);
procedure Add_Dependence (Unit : Iir)
is
Targ : constant Iir := Get_Current_Design_Unit;
begin
-- During normal analysis, there is a current design unit. But not
-- during debugging outside of any context.
if Targ = Null_Iir then
return;
end if;
Add_Dependence (Targ, Unit);
end Add_Dependence;
-- LRM 1.1 Entity declaration.
procedure Sem_Entity_Declaration (Entity : Iir_Entity_Declaration) is
begin
Xrefs.Xref_Decl (Entity);
Sem_Scopes.Add_Name (Entity);
Set_Visible_Flag (Entity, True);
Set_Is_Within_Flag (Entity, True);
-- LRM 10.1
-- 1. An entity declaration, together with a corresponding architecture
-- body.
Open_Declarative_Region;
-- Sem generics.
Sem_Interface_Chain (Get_Generic_Chain (Entity), Generic_Interface_List);
-- Sem ports.
Sem_Interface_Chain (Get_Port_Chain (Entity), Port_Interface_List);
-- Entity declarative part and concurrent statements.
Sem_Block (Entity);
Close_Declarative_Region;
Set_Is_Within_Flag (Entity, False);
end Sem_Entity_Declaration;
-- Get the entity unit for LIBRARY_UNIT (an architecture or a
-- configuration declaration).
-- Return NULL_IIR in case of error (not found, bad library).
function Sem_Entity_Name (Library_Unit : Iir) return Iir
is
Name : Iir;
Library : Iir_Library_Declaration;
Entity : Iir;
begin
-- Get the library of architecture/configuration.
Library := Get_Library
(Get_Design_File (Get_Design_Unit (Library_Unit)));
-- Resolve the name.
Name := Get_Entity_Name (Library_Unit);
if Is_Error (Name) then
pragma Assert (Flags.Flag_Force_Analysis);
return Null_Iir;
end if;
if Get_Kind (Name) = Iir_Kind_Simple_Name then
-- LRM93 10.1 Declarative Region
-- LRM08 12.1 Declarative Region
-- a) An entity declaration, tohether with a corresponding
-- architecture body.
--
-- GHDL: simple name needs to be handled specially. Because
-- architecture body is in the declarative region of its entity,
-- the entity name is directly visible. But we cannot really use
-- that rule as is, as we don't know which is the entity.
Entity := Load_Primary_Unit
(Library, Get_Identifier (Name), Library_Unit);
if Entity = Null_Iir then
Error_Msg_Sem (+Name, "entity %n was not analysed", +Name);
return Null_Iir;
end if;
Entity := Get_Library_Unit (Entity);
Set_Named_Entity (Name, Entity);
Xrefs.Xref_Ref (Name, Entity);
else
-- Certainly an expanded name. Use the standard name analysis.
Name := Sem_Denoting_Name (Name);
Set_Entity_Name (Library_Unit, Name);
Entity := Get_Named_Entity (Name);
end if;
if Get_Kind (Entity) /= Iir_Kind_Entity_Declaration then
Error_Class_Match (Name, "entity");
return Null_Iir;
end if;
-- LRM 1.2 Architecture bodies
-- For a given design entity, both the entity declaration and the
-- associated architecture body must reside in the same library.
-- LRM 1.3 Configuration Declarations
-- For a configuration of a given design entity, both the
-- configuration declaration and the corresponding entity
-- declaration must reside in the same library.
if Get_Library (Get_Design_File (Get_Design_Unit (Entity))) /= Library
then
Error_Msg_Sem
(+Library_Unit, "%n does not reside in %n", (+Entity, +Library));
return Null_Iir;
end if;
return Entity;
end Sem_Entity_Name;
-- LRM 1.2 Architecture bodies.
procedure Sem_Architecture_Body (Arch: Iir_Architecture_Body)
is
Entity_Unit : Iir_Design_Unit;
Entity_Library : Iir_Entity_Declaration;
begin
Xrefs.Xref_Decl (Arch);
-- First, find the entity.
Entity_Library := Sem_Entity_Name (Arch);
if Entity_Library = Null_Iir then
return;
end if;
Entity_Unit := Get_Design_Unit (Entity_Library);
-- LRM93 11.4
-- In each case, the second unit depends on the first unit.
-- GHDL: an architecture depends on its entity.
Add_Dependence (Entity_Unit);
Add_Context_Clauses (Entity_Unit);
Set_Is_Within_Flag (Arch, True);
Set_Is_Within_Flag (Entity_Library, True);
-- Makes the entity name visible.
-- FIXME: quote LRM.
declare
Prev_Hide : constant Boolean := Is_Warning_Enabled (Warnid_Hide);
begin
-- Avoid spurious warning from entity name (if it has the same
-- identifier as a library clause).
Enable_Warning (Warnid_Hide, False);
Sem_Scopes.Add_Name
(Entity_Library, Get_Identifier (Entity_Library), False);
Enable_Warning (Warnid_Hide, Prev_Hide);
end;
-- LRM 10.1 Declarative Region
-- 1. An entity declaration, together with a corresponding architecture
-- body.
Open_Declarative_Region;
Sem_Scopes.Add_Entity_Declarations (Entity_Library);
-- LRM02 1.2 Architecture bodies
-- For the purpose of interpreting the scope and visibility of the
-- identifier (see 10.2 and 10.3), the declaration of the identifier is
-- considered to occur after the final declarative item of the entity
-- declarative part of the corresponding entity declaration.
--
-- FIXME: before VHDL-02, an architecture is not a declaration.
Sem_Scopes.Add_Name (Arch, Get_Identifier (Arch), True);
Set_Visible_Flag (Arch, True);
-- LRM02 10.1 Declarative region
-- The declarative region associated with an architecture body is
-- considered to occur immediatly within the declarative region
-- associated with the entity declaration corresponding to the given
-- architecture body.
--
-- GHDL: this is only in vhdl-2002.
if Vhdl_Std = Vhdl_02 then
Open_Declarative_Region;
end if;
Current_Psl_Default_Clock := Null_Iir;
Sem_Block (Arch);
if Vhdl_Std = Vhdl_02 then
Close_Declarative_Region;
end if;
Close_Declarative_Region;
Set_Is_Within_Flag (Arch, False);
Set_Is_Within_Flag (Entity_Library, False);
end Sem_Architecture_Body;
-- Return the real resolver used for (sub) object OBJ.
-- Return NULL_IIR if none.
function Get_Resolver (Obj : Iir) return Iir
is
Obj_Type : Iir;
Res : Iir;
begin
case Get_Kind (Obj) is
when Iir_Kind_Indexed_Name
| Iir_Kind_Slice_Name
| Iir_Kind_Selected_Element =>
Res := Get_Resolver (Get_Prefix (Obj));
if Res /= Null_Iir then
return Res;
end if;
when Iir_Kind_Signal_Declaration
| Iir_Kind_Interface_Signal_Declaration
| Iir_Kind_Guard_Signal_Declaration =>
null;
when Iir_Kind_Object_Alias_Declaration =>
return Get_Resolver (Get_Name (Obj));
when Iir_Kind_Simple_Name
| Iir_Kind_Selected_Name =>
return Get_Resolver (Get_Named_Entity (Obj));
when others =>
Error_Kind ("get_resolved", Obj);
end case;