aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/nodes_gc.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/vhdl/nodes_gc.adb')
-rw-r--r--src/vhdl/nodes_gc.adb221
1 files changed, 123 insertions, 98 deletions
diff --git a/src/vhdl/nodes_gc.adb b/src/vhdl/nodes_gc.adb
index 99343222f..fde394e4e 100644
--- a/src/vhdl/nodes_gc.adb
+++ b/src/vhdl/nodes_gc.adb
@@ -38,6 +38,26 @@ package body Nodes_GC is
procedure Free is new Ada.Unchecked_Deallocation
(Marker_Array, Marker_Array_Acc);
+ procedure Report_Early_Reference (N : Iir; F : Nodes_Meta.Fields_Enum)
+ is
+ use Ada.Text_IO;
+ begin
+ Put ("early reference to ");
+ Put (Nodes_Meta.Get_Field_Image (F));
+ Put (" in ");
+ Disp_Tree.Disp_Tree (N, True);
+ Has_Error := True;
+ end Report_Early_Reference;
+
+ procedure Report_Already_Marked (N : Iir)
+ is
+ use Ada.Text_IO;
+ begin
+ Put ("Already marked ");
+ Disp_Tree.Disp_Tree (N, True);
+ Has_Error := True;
+ end Report_Already_Marked;
+
procedure Mark_Iir (N : Iir);
procedure Mark_Iir_List (N : Iir_List)
@@ -58,6 +78,26 @@ package body Nodes_GC is
end case;
end Mark_Iir_List;
+ procedure Mark_Iir_List_Ref (N : Iir_List; F : Fields_Enum)
+ is
+ El : Iir;
+ begin
+ case N is
+ when Null_Iir_List
+ | Iir_List_All
+ | Iir_List_Others =>
+ null;
+ when others =>
+ for I in Natural loop
+ El := Get_Nth_Element (N, I);
+ exit when El = Null_Iir;
+ if not Markers (El) then
+ Report_Early_Reference (El, F);
+ end if;
+ end loop;
+ end case;
+ end Mark_Iir_List_Ref;
+
procedure Mark_PSL_Node (N : PSL_Node) is
begin
null;
@@ -68,15 +108,6 @@ package body Nodes_GC is
null;
end Mark_PSL_NFA;
- procedure Report_Already_Marked (N : Iir)
- is
- use Ada.Text_IO;
- begin
- Put ("Already marked ");
- Disp_Tree.Disp_Tree (N, True);
- Has_Error := True;
- end Report_Already_Marked;
-
procedure Already_Marked (N : Iir) is
begin
-- An unused node mustn't be referenced.
@@ -101,17 +132,6 @@ package body Nodes_GC is
Report_Already_Marked (N);
end Already_Marked;
- procedure Report_Early_Reference (N : Iir; F : Nodes_Meta.Fields_Enum)
- is
- use Ada.Text_IO;
- begin
- Put ("early reference to ");
- Put (Nodes_Meta.Get_Field_Image (F));
- Put (" in ");
- Disp_Tree.Disp_Tree (N, True);
- Has_Error := True;
- end Report_Early_Reference;
-
procedure Mark_Chain (Head : Iir)
is
El : Iir;
@@ -129,36 +149,13 @@ package body Nodes_GC is
Has_Error := True;
end Report_Unreferenced_Node;
- procedure Mark_Iir_Ref_Field (N : Iir; F : Fields_Enum) is
+ procedure Mark_Iir_Ref_Field (N : Iir; F : Fields_Enum)
+ is
+ Nf : constant Iir := Get_Iir (N, F);
begin
- case Get_Field_Type (F) is
- when Type_Iir =>
- declare
- Nf : constant Iir := Get_Iir (N, F);
- begin
- if Is_Valid (Nf) and then not Markers (Nf) then
- Report_Early_Reference (N, F);
- end if;
- end;
- when Type_Iir_List =>
- declare
- Nl : constant Iir_List := Get_Iir_List (N, F);
- El : Iir;
- begin
- if Is_Null_List (Nl) or else Nl in Iir_Lists_All_Others then
- return;
- end if;
- for I in Natural loop
- El := Get_Nth_Element (Nl, I);
- exit when El = Null_Iir;
- if not Markers (El) then
- Report_Early_Reference (El, F);
- end if;
- end loop;
- end;
- when others =>
- raise Internal_Error;
- end case;
+ if Is_Valid (Nf) and then not Markers (Nf) then
+ Report_Early_Reference (N, F);
+ end if;
end Mark_Iir_Ref_Field;
procedure Mark_Iir (N : Iir) is
@@ -178,58 +175,79 @@ package body Nodes_GC is
begin
for I in Fields'Range loop
F := Fields (I);
- case Get_Field_Attribute (F) is
- when Attr_Ref =>
- Mark_Iir_Ref_Field (N, F);
- when Attr_Forward_Ref
- | Attr_Chain_Next =>
- null;
- when Attr_Maybe_Forward_Ref =>
- -- Only used for Named_Entity
- pragma Assert (F = Field_Named_Entity);
-
- -- Overload_List has to be handled specially, as it that
- -- case the Ref applies to the elements of the list.
- declare
- Nf : constant Iir := Get_Iir (N, F);
- begin
- if Nf /= Null_Iir then
- if Get_Is_Forward_Ref (N) then
- pragma Assert
- (Get_Kind (Nf) /= Iir_Kind_Overload_List);
- null;
- else
- if Get_Kind (Nf) = Iir_Kind_Overload_List then
- Mark_Iir (Nf);
- else
- Mark_Iir_Ref_Field (N, F);
+ case Get_Field_Type (F) is
+ when Type_Iir =>
+ case Get_Field_Attribute (F) is
+ when Attr_None =>
+ Mark_Iir (Get_Iir (N, F));
+ when Attr_Ref =>
+ Mark_Iir_Ref_Field (N, F);
+ when Attr_Forward_Ref
+ | Attr_Chain_Next =>
+ null;
+ when Attr_Maybe_Forward_Ref =>
+ -- Only used for Named_Entity
+ pragma Assert (F = Field_Named_Entity);
+
+ -- Overload_List has to be handled specially, as it
+ -- that case the Ref applies to the elements of the
+ -- list.
+ declare
+ Nf : constant Iir := Get_Iir (N, F);
+ begin
+ if Nf /= Null_Iir then
+ if Get_Is_Forward_Ref (N) then
+ pragma Assert
+ (Get_Kind (Nf) /= Iir_Kind_Overload_List);
+ null;
+ else
+ if Get_Kind (Nf) = Iir_Kind_Overload_List then
+ Mark_Iir (Nf);
+ else
+ Mark_Iir_Ref_Field (N, F);
+ end if;
+ end if;
end if;
+ end;
+ when Attr_Maybe_Ref =>
+ if Get_Is_Ref (N) then
+ Mark_Iir_Ref_Field (N, F);
+ else
+ Mark_Iir (Get_Iir (N, F));
end if;
+ when Attr_Chain =>
+ Mark_Chain (Get_Iir (N, F));
+ when Attr_Of_Ref | Attr_Of_Maybe_Ref =>
+ raise Internal_Error;
+ end case;
+ when Type_Iir_List =>
+ declare
+ Ref : Boolean;
+ begin
+ case Get_Field_Attribute (F) is
+ when Attr_None =>
+ Ref := False;
+ when Attr_Of_Ref =>
+ Ref := True;
+ when Attr_Of_Maybe_Ref =>
+ Ref := Get_Is_Ref (N);
+ when Attr_Ref =>
+ Ref := True;
+ when others =>
+ raise Internal_Error;
+ end case;
+ if Ref then
+ Mark_Iir_List_Ref (Get_Iir_List (N, F), F);
+ else
+ Mark_Iir_List (Get_Iir_List (N, F));
end if;
end;
- when Attr_Maybe_Ref =>
- if Get_Is_Ref (N) then
- Mark_Iir_Ref_Field (N, F);
- else
- Mark_Iir (Get_Iir (N, F));
- end if;
- when Attr_Chain =>
- Mark_Chain (Get_Iir (N, F));
- when Attr_None =>
- case Get_Field_Type (F) is
- when Type_Iir =>
- Mark_Iir (Get_Iir (N, F));
- when Type_Iir_List =>
- Mark_Iir_List (Get_Iir_List (N, F));
- when Type_PSL_Node =>
- Mark_PSL_Node (Get_PSL_Node (N, F));
- when Type_PSL_NFA =>
- Mark_PSL_NFA (Get_PSL_NFA (N, F));
- when others =>
- null;
- end case;
- when Attr_Of_Ref =>
- Mark_Iir_Ref_Field (N, F);
+ when Type_PSL_Node =>
+ Mark_PSL_Node (Get_PSL_Node (N, F));
+ when Type_PSL_NFA =>
+ Mark_PSL_NFA (Get_PSL_NFA (N, F));
+ when others =>
+ null;
end case;
end loop;
end;
@@ -245,7 +263,14 @@ package body Nodes_GC is
return;
end if;
- Markers (Get_Design_File (Unit)) := True;
+ -- Mark parents of UNIT.
+ declare
+ File : constant Iir := Get_Design_File (Unit);
+ Lib : constant Iir := Get_Library (File);
+ begin
+ Markers (File) := True;
+ Markers (Lib) := True;
+ end;
-- First mark dependences
List := Get_Dependence_List (Unit);