aboutsummaryrefslogtreecommitdiffstats
path: root/sem_inst.adb
diff options
context:
space:
mode:
Diffstat (limited to 'sem_inst.adb')
-rw-r--r--sem_inst.adb219
1 files changed, 217 insertions, 2 deletions
diff --git a/sem_inst.adb b/sem_inst.adb
index c368e1f69..d6368397f 100644
--- a/sem_inst.adb
+++ b/sem_inst.adb
@@ -19,6 +19,7 @@ with Nodes;
with Nodes_Meta;
with Types; use Types;
with Iirs_Utils; use Iirs_Utils;
+with Errorout; use Errorout;
package body Sem_Inst is
-- Table of origin. This is an extension of vhdl nodes to track the
@@ -330,7 +331,7 @@ package body Sem_Inst is
begin
Res := Get_Instance (N);
- if Kind = Iir_Kind_Constant_Interface_Declaration
+ if Kind = Iir_Kind_Interface_Constant_Declaration
and then Get_Identifier (N) = Null_Identifier
and then Res /= Null_Iir
then
@@ -355,8 +356,11 @@ package body Sem_Inst is
for I in Fields'Range loop
F := Fields (I);
+ -- Fields that are handled specially.
case F is
when Field_Index_Subtype_List =>
+ -- Index_Subtype_List is always a reference, so retrieve
+ -- the instance of the referenced list.
declare
List : Iir_List;
begin
@@ -389,6 +393,9 @@ package body Sem_Inst is
-- Subprogram body is a forward declaration.
Set_Subprogram_Body (Res, Null_Iir);
when others =>
+ -- TODO: other forward references:
+ -- incomplete constant
+ -- attribute_value
null;
end case;
@@ -396,6 +403,213 @@ package body Sem_Inst is
end;
end Instantiate_Iir;
+ -- As the scope generic interfaces extends beyond the immediate scope (see
+ -- LRM08 12.2 Scope of declarations), they must be instantiated.
+ function Instantiate_Generic_Chain (Inst : Iir; Inters : Iir) return Iir
+ is
+ Inter : Iir;
+ First : Iir;
+ Last : Iir;
+ Res : Iir;
+ begin
+ First := Null_Iir;
+ Last := Null_Iir;
+
+ Inter := Inters;
+ while Inter /= Null_Iir loop
+ -- Create a copy of the interface. FIXME: is it really needed ?
+ Res := Create_Iir (Get_Kind (Inter));
+ Set_Location (Res, Instantiate_Loc);
+ Set_Parent (Res, Inst);
+ Set_Identifier (Res, Get_Identifier (Inter));
+ Set_Visible_Flag (Res, Get_Visible_Flag (Inter));
+
+ Set_Origin (Res, Inter);
+ Set_Instance (Inter, Res);
+
+ case Get_Kind (Res) is
+ when Iir_Kind_Interface_Constant_Declaration =>
+ Set_Type (Res, Get_Type (Inter));
+ Set_Subtype_Indication (Res, Get_Subtype_Indication (Inter));
+ Set_Mode (Res, Get_Mode (Inter));
+ Set_Lexical_Layout (Res, Get_Lexical_Layout (Inter));
+ Set_Expr_Staticness (Res, Get_Expr_Staticness (Inter));
+ Set_Name_Staticness (Res, Get_Name_Staticness (Inter));
+ when Iir_Kind_Interface_Package_Declaration =>
+ Set_Uninstantiated_Package_Name
+ (Res, Get_Uninstantiated_Package_Name (Inter));
+ when others =>
+ Error_Kind ("instantiate_generic_chain", Res);
+ end case;
+
+ -- Append
+ if First = Null_Iir then
+ First := Res;
+ else
+ Set_Chain (Last, Res);
+ end if;
+ Last := Res;
+
+ Inter := Get_Chain (Inter);
+ end loop;
+
+ return First;
+ end Instantiate_Generic_Chain;
+
+ procedure Set_Instance_On_Chain (Chain : Iir; Inst_Chain : Iir);
+ procedure Set_Instance_On_Iir_List (N : Iir_List; Inst : Iir_List);
+
+ procedure Set_Instance_On_Iir (N : Iir; Inst : Iir) is
+ begin
+ if N = Null_Iir then
+ pragma Assert (Inst = Null_Iir);
+ return;
+ end if;
+ pragma Assert (Inst /= Null_Iir);
+
+ declare
+ use Nodes_Meta;
+ Kind : constant Iir_Kind := Get_Kind (N);
+ Fields : constant Fields_Array := Get_Fields (Kind);
+ F : Fields_Enum;
+ begin
+ pragma Assert (Get_Kind (Inst) = Kind);
+
+ if Kind = Iir_Kind_Interface_Constant_Declaration
+ and then Get_Identifier (N) = Null_Identifier
+ then
+ -- Anonymous constant interface declarations are the only nodes
+ -- that can be shared. Handle that very special case.
+ return;
+ end if;
+
+ -- pragma Assert (Get_Instance (N) = Null_Iir);
+ Set_Instance (N, Inst);
+
+ for I in Fields'Range loop
+ F := Fields (I);
+
+ case Get_Field_Type (F) is
+ when Type_Iir =>
+ declare
+ S : constant Iir := Get_Iir (N, F);
+ S_Inst : constant Iir := Get_Iir (Inst, F);
+ begin
+ case Get_Field_Attribute (F) is
+ when Attr_None =>
+ Set_Instance_On_Iir (S, S_Inst);
+ when Attr_Ref =>
+ null;
+ when Attr_Maybe_Ref =>
+ if not Get_Is_Ref (N) then
+ Set_Instance_On_Iir (S, S_Inst);
+ end if;
+ when Attr_Chain =>
+ Set_Instance_On_Chain (S, S_Inst);
+ when Attr_Chain_Next =>
+ null;
+ when Attr_Of_Ref =>
+ -- Can only appear in list.
+ raise Internal_Error;
+ end case;
+ end;
+ when Type_Iir_List =>
+ declare
+ S : constant Iir_List := Get_Iir_List (N, F);
+ S_Inst : constant Iir_List := Get_Iir_List (Inst, F);
+ begin
+ case Get_Field_Attribute (F) is
+ when Attr_None =>
+ Set_Instance_On_Iir_List (S, S_Inst);
+ when Attr_Of_Ref
+ | Attr_Ref =>
+ null;
+ when others =>
+ -- Ref is specially handled in Instantiate_Iir.
+ -- Others cannot appear for lists.
+ raise Internal_Error;
+ end case;
+ end;
+ when others =>
+ null;
+ end case;
+ end loop;
+ end;
+ end Set_Instance_On_Iir;
+
+ procedure Set_Instance_On_Iir_List (N : Iir_List; Inst : Iir_List)
+ is
+ El : Iir;
+ El_Inst : Iir;
+ begin
+ case N is
+ when Null_Iir_List
+ | Iir_List_All
+ | Iir_List_Others =>
+ pragma Assert (Inst = N);
+ return;
+ when others =>
+ for I in Natural loop
+ El := Get_Nth_Element (N, I);
+ El_Inst := Get_Nth_Element (Inst, I);
+ exit when El = Null_Iir;
+ pragma Assert (El_Inst /= Null_Iir);
+
+ Set_Instance_On_Iir (El, El_Inst);
+ end loop;
+ pragma Assert (El_Inst = Null_Iir);
+ end case;
+ end Set_Instance_On_Iir_List;
+
+ procedure Set_Instance_On_Chain (Chain : Iir; Inst_Chain : Iir)
+ is
+ El : Iir;
+ Inst_El : Iir;
+ begin
+ El := Chain;
+ Inst_El := Inst_Chain;
+ while El /= Null_Iir loop
+ pragma Assert (Inst_El /= Null_Iir);
+ Set_Instance_On_Iir (El, Inst_El);
+ El := Get_Chain (El);
+ Inst_El := Get_Chain (Inst_El);
+ end loop;
+ pragma Assert (Inst_El = Null_Iir);
+ end Set_Instance_On_Chain;
+
+ -- In the instance, replace references (and inner references) to interface
+ -- package declaration to the associated package.
+ procedure Instantiate_Generic_Map_Chain (Inst : Iir; Pkg : Iir)
+ is
+ pragma Unreferenced (Pkg);
+ Assoc : Iir;
+ begin
+ Assoc := Get_Generic_Map_Aspect_Chain (Inst);
+ while Assoc /= Null_Iir loop
+ case Get_Kind (Assoc) is
+ when Iir_Kind_Association_Element_By_Expression
+ | Iir_Kind_Association_Element_By_Individual
+ | Iir_Kind_Association_Element_Open =>
+ null;
+ when Iir_Kind_Association_Element_Package =>
+ declare
+ Sub_Inst : constant Iir :=
+ Get_Named_Entity (Get_Actual (Assoc));
+ Sub_Pkg : constant Iir := Get_Associated_Interface (Assoc);
+ begin
+ Set_Instance (Sub_Pkg, Sub_Inst);
+ Set_Instance_On_Chain (Get_Generic_Chain (Sub_Pkg),
+ Get_Generic_Chain (Sub_Inst));
+ Set_Instance_On_Chain (Get_Declaration_Chain (Sub_Pkg),
+ Get_Declaration_Chain (Sub_Inst));
+ end;
+ when others =>
+ Error_Kind ("instantiate_generic_map_chain", Assoc);
+ end case;
+ Assoc := Get_Chain (Assoc);
+ end loop;
+ end Instantiate_Generic_Map_Chain;
+
procedure Instantiate_Package_Declaration (Inst : Iir; Pkg : Iir)
is
Header : constant Iir := Get_Package_Header (Pkg);
@@ -411,7 +625,8 @@ package body Sem_Inst is
Set_Origin (Pkg, Inst);
Set_Generic_Chain
- (Inst, Instantiate_Iir_Chain (Get_Generic_Chain (Header)));
+ (Inst, Instantiate_Generic_Chain (Inst, Get_Generic_Chain (Header)));
+ Instantiate_Generic_Map_Chain (Inst, Pkg);
Set_Declaration_Chain
(Inst, Instantiate_Iir_Chain (Get_Declaration_Chain (Pkg)));