aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/sem_decls.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/vhdl/sem_decls.adb')
-rw-r--r--src/vhdl/sem_decls.adb124
1 files changed, 87 insertions, 37 deletions
diff --git a/src/vhdl/sem_decls.adb b/src/vhdl/sem_decls.adb
index 517d69c6c..d8f4c7543 100644
--- a/src/vhdl/sem_decls.adb
+++ b/src/vhdl/sem_decls.adb
@@ -47,13 +47,14 @@ package body Sem_Decls is
-- Region that can declare signals. Used to add implicit declarations.
Current_Signals_Region : Implicit_Signal_Declaration_Type :=
- (Null_Iir, False, Null_Iir, Null_Iir);
+ (Null_Iir, Null_Iir, Null_Iir, False, Null_Iir);
procedure Push_Signals_Declarative_Part
(Cell: out Implicit_Signal_Declaration_Type; Decls_Parent : Iir) is
begin
Cell := Current_Signals_Region;
- Current_Signals_Region := (Decls_Parent, False, Null_Iir, Null_Iir);
+ Current_Signals_Region :=
+ (Decls_Parent, Null_Iir, Null_Iir, False, Null_Iir);
end Push_Signals_Declarative_Part;
procedure Pop_Signals_Declarative_Part
@@ -62,30 +63,95 @@ package body Sem_Decls is
Current_Signals_Region := Cell;
end Pop_Signals_Declarative_Part;
- procedure Add_Declaration_For_Implicit_Signal (Sig : Iir) is
+ -- Insert the implicit signal declaration after LAST_DECL.
+ procedure Insert_Implicit_Signal (Last_Decl : Iir) is
begin
+ if Last_Decl = Null_Iir then
+ Set_Declaration_Chain (Current_Signals_Region.Decls_Parent,
+ Current_Signals_Region.Implicit_Decl);
+ else
+ Set_Chain (Last_Decl, Current_Signals_Region.Implicit_Decl);
+ end if;
+ end Insert_Implicit_Signal;
+
+ -- Add SIG as an implicit declaration in the current region.
+ procedure Add_Declaration_For_Implicit_Signal (Sig : Iir)
+ is
+ Decl : Iir;
+ begin
+ -- We deal only with signal attribute.
+ pragma Assert (Get_Kind (Sig) in Iir_Kinds_Signal_Attribute);
+
-- There must be a declarative part for implicit signals.
pragma Assert (Current_Signals_Region.Decls_Parent /= Null_Iir);
- -- Chain must be empty.
- pragma Assert (Get_Chain (Sig) = Null_Iir);
+ -- Attr_Chain must be empty.
+ pragma Assert (Get_Attr_Chain (Sig) = Null_Iir);
- if Current_Signals_Region.Decls_Analyzed then
- -- Just append.
- if Current_Signals_Region.Last_Implicit_Decl = Null_Iir then
- -- No declarations.
- Set_Declaration_Chain (Current_Signals_Region.Decls_Parent, Sig);
- else
- -- Append to the last declaration.
- Set_Chain (Current_Signals_Region.Last_Implicit_Decl, Sig);
+ if Current_Signals_Region.Implicit_Decl = Null_Iir then
+ -- Create the signal_attribute_declaration to hold all the implicit
+ -- signals.
+ Decl := Create_Iir (Iir_Kind_Signal_Attribute_Declaration);
+ Location_Copy (Decl, Sig);
+ Set_Parent (Decl, Current_Signals_Region.Decls_Parent);
+
+ -- Save the implicit declaration.
+ Current_Signals_Region.Implicit_Decl := Decl;
+
+ -- Append SIG (this is the first one).
+ Set_Signal_Attribute_Chain (Decl, Sig);
+
+ if Current_Signals_Region.Decls_Analyzed then
+ -- Declarative region was completely analyzed. Just append DECL
+ -- at the end of declarations.
+ Insert_Implicit_Signal (Current_Signals_Region.Last_Decl);
end if;
- Current_Signals_Region.Last_Implicit_Decl := Sig;
else
- Sub_Chain_Append (Current_Signals_Region.First_Implicit_Decl,
- Current_Signals_Region.Last_Implicit_Decl, Sig);
+ -- Append SIG.
+ Set_Attr_Chain (Current_Signals_Region.Last_Attribute_Signal, Sig);
end if;
+ Current_Signals_Region.Last_Attribute_Signal := Sig;
+
+ Set_Signal_Attribute_Declaration
+ (Sig, Current_Signals_Region.Implicit_Decl);
end Add_Declaration_For_Implicit_Signal;
+ -- Insert pending implicit declarations after the last analyzed LAST_DECL,
+ -- and update it. Then the caller has to insert the declaration which
+ -- created the implicit declarations.
+ procedure Insert_Pending_Implicit_Declarations
+ (Parent : Iir; Last_Decl : in out Iir) is
+ begin
+ if Current_Signals_Region.Decls_Parent = Parent
+ and then Current_Signals_Region.Implicit_Decl /= Null_Iir
+ then
+ pragma Assert (not Current_Signals_Region.Decls_Analyzed);
+
+ -- Add pending implicit declarations before the current one.
+ Insert_Implicit_Signal (Last_Decl);
+ Last_Decl := Current_Signals_Region.Implicit_Decl;
+
+ -- Detach the implicit declaration.
+ Current_Signals_Region.Implicit_Decl := Null_Iir;
+ Current_Signals_Region.Last_Attribute_Signal := Null_Iir;
+ end if;
+ end Insert_Pending_Implicit_Declarations;
+
+ -- Mark the end of declaration analysis. New implicit declarations will
+ -- simply be appended to the last declaration.
+ procedure End_Of_Declarations_For_Implicit_Declarations
+ (Parent : Iir; Last_Decl : Iir) is
+ begin
+ if Current_Signals_Region.Decls_Parent = Parent then
+ pragma Assert (not Current_Signals_Region.Decls_Analyzed);
+
+ -- All declarations have been analyzed, new implicit declarations
+ -- will be appended.
+ Current_Signals_Region.Decls_Analyzed := True;
+ Current_Signals_Region.Last_Decl := Last_Decl;
+ end if;
+ end End_Of_Declarations_For_Implicit_Declarations;
+
-- Emit an error if the type of DECL is a file type, access type,
-- protected type or if a subelement of DECL is an access type.
procedure Check_Signal_Type (Decl : Iir)
@@ -2980,21 +3046,9 @@ package body Sem_Decls is
Check_Post_Attribute_Specification (Attr_Spec_Chain, Decl);
end if;
- if Current_Signals_Region.Decls_Parent = Parent
- and then Current_Signals_Region.First_Implicit_Decl /= Null_Iir
- then
- -- Add pending implicit declarations before the current one.
- if Last_Decl = Null_Iir then
- Set_Declaration_Chain
- (Parent, Current_Signals_Region.First_Implicit_Decl);
- else
- Set_Chain
- (Last_Decl, Current_Signals_Region.First_Implicit_Decl);
- end if;
- Last_Decl := Current_Signals_Region.Last_Implicit_Decl;
- Sub_Chain_Init (Current_Signals_Region.First_Implicit_Decl,
- Current_Signals_Region.Last_Implicit_Decl);
- end if;
+ -- Insert *before* DECL pending implicit signal declarations created
+ -- for DECL after LAST_DECL. This updates LAST_DECL.
+ Insert_Pending_Implicit_Declarations (Parent, Last_Decl);
if Last_Decl = Null_Iir then
-- Append now to handle expand names.
@@ -3006,12 +3060,8 @@ package body Sem_Decls is
Decl := Get_Chain (Decl);
end loop;
- if Current_Signals_Region.Decls_Parent = Parent then
- -- All declarations have been analyzed, new implicit declarations
- -- will be appended.
- Current_Signals_Region.Decls_Analyzed := True;
- Current_Signals_Region.Last_Implicit_Decl := Last_Decl;
- end if;
+ -- Keep the point of insertion for implicit signal declarations.
+ End_Of_Declarations_For_Implicit_Declarations (Parent, Last_Decl);
end Sem_Declaration_Chain;
procedure Check_Full_Declaration (Decls_Parent : Iir; Decl: Iir)