aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl/sem.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/vhdl/sem.adb')
-rw-r--r--src/vhdl/sem.adb139
1 files changed, 136 insertions, 3 deletions
diff --git a/src/vhdl/sem.adb b/src/vhdl/sem.adb
index b1d1015e2..e4790bd92 100644
--- a/src/vhdl/sem.adb
+++ b/src/vhdl/sem.adb
@@ -38,7 +38,7 @@ with Xrefs; use Xrefs;
package body Sem is
-- Forward declarations.
- procedure Sem_Context_Clauses (Design_Unit: Iir_Design_Unit);
+ procedure Sem_Context_Clauses (Unit: Iir);
procedure Sem_Block_Configuration
(Block_Conf : Iir_Block_Configuration; Father: Iir);
procedure Sem_Component_Configuration
@@ -2721,18 +2721,66 @@ package body Sem is
end if;
end Sem_Library_Clause;
+ -- LRM08 13.4 Context clauses.
+ procedure Sem_One_Context_Reference (Ref : Iir)
+ is
+ Name : Iir;
+ Ent : Iir;
+ begin
+ Name := Get_Selected_Name (Ref);
+ if Get_Kind (Name) /= Iir_Kind_Selected_Name then
+ Error_Msg_Sem
+ ("context reference only allows selected names", Name);
+ return;
+ end if;
+
+ Name := Sem_Denoting_Name (Name);
+ Set_Selected_Name (Ref, Name);
+ Ent := Get_Named_Entity (Name);
+ if Is_Error (Ent) then
+ return;
+ end if;
+
+ -- LRM08 13.4 Context clauses
+ -- It is an error if a selected name in a context reference does not
+ -- denote a context declaration.
+ if Get_Kind (Ent) /= Iir_Kind_Context_Declaration then
+ Error_Msg_Sem ("name must denote a context declaration", Name);
+ Set_Named_Entity (Name, Null_Iir);
+ return;
+ end if;
+ end Sem_One_Context_Reference;
+
+ -- LRM08 13.4 Context clauses.
+ procedure Sem_Context_Reference (Ctxt : Iir)
+ is
+ Ref : Iir;
+ begin
+ Ref := Ctxt;
+ loop
+ Sem_One_Context_Reference (Ref);
+ Ref := Get_Context_Reference_Chain (Ref);
+ exit when Ref = Null_Iir;
+ end loop;
+
+ -- FIXME: must be done clause after clause ?
+ Add_Context_Reference (Ctxt);
+ end Sem_Context_Reference;
+
-- LRM 11.3 Context Clauses.
- procedure Sem_Context_Clauses (Design_Unit: Iir_Design_Unit)
+ procedure Sem_Context_Clauses (Unit: Iir)
is
El: Iir;
begin
- El := Get_Context_Items (Design_Unit);
+ El := Get_Context_Items (Unit);
while El /= Null_Iir loop
case Get_Kind (El) is
when Iir_Kind_Use_Clause =>
Sem_Use_Clause (El);
when Iir_Kind_Library_Clause =>
Sem_Library_Clause (El);
+ when Iir_Kind_Context_Reference =>
+ Sem_Context_Reference (El);
when others =>
Error_Kind ("sem_context_clauses", El);
end case;
@@ -2740,6 +2788,89 @@ package body Sem is
end loop;
end Sem_Context_Clauses;
+ -- LRM08 13.3 Context declarations
+ procedure Sem_Context_Declaration (Decl: Iir)
+ is
+ -- Return TRUE iff the first prefix of NAME denotes library WORK.
+ function Has_Work_Library_Prefix (Name : Iir) return Boolean
+ is
+ Prefix : Iir;
+ begin
+ Prefix := Name;
+ while Get_Kind (Prefix) = Iir_Kind_Selected_Name
+ or else Get_Kind (Prefix) = Iir_Kind_Selected_By_All_Name
+ loop
+ Prefix := Get_Prefix (Prefix);
+ end loop;
+ return Get_Kind (Prefix) = Iir_Kind_Simple_Name
+ and then Get_Identifier (Prefix) = Std_Names.Name_Work
+ and then (Get_Kind (Get_Named_Entity (Prefix))
+ = Iir_Kind_Library_Declaration);
+ end Has_Work_Library_Prefix;
+
+ procedure Error_Work_Prefix (Loc : Iir) is
+ begin
+ Error_Msg_Sem
+ ("'work' not allowed as prefix in context declaration", Loc);
+ end Error_Work_Prefix;
+
+ El : Iir;
+ El1 : Iir;
+ begin
+ Sem_Scopes.Add_Name (Decl);
+ Xref_Decl (Decl);
+
+ Sem_Context_Clauses (Decl);
+
+ El := Get_Context_Items (Decl);
+ while El /= Null_Iir loop
+ case Get_Kind (El) is
+ when Iir_Kind_Library_Clause =>
+ -- LRM08 13.3 Context declarations
+ -- It is an error if a library clause in a context declaration
+ -- defines the library logical name WORK, [...]
+ if Get_Identifier (El) = Std_Names.Name_Work then
+ Error_Msg_Sem
+ ("'library work' not allowed in context declaration", El);
+ end if;
+ when Iir_Kind_Use_Clause =>
+ -- LRM08 13.3 Context declarations
+ -- [...] or if a selected name in a use clause [or a context
+ -- reference] in a context declaration has the library logic
+ -- name WORK as a prefix.
+ El1 := El;
+ while El1 /= Null_Iir loop
+ if Has_Work_Library_Prefix (Get_Selected_Name (El1)) then
+ Error_Work_Prefix (El1);
+ exit;
+ end if;
+ El1 := Get_Use_Clause_Chain (El1);
+ end loop;
+ when Iir_Kind_Context_Reference =>
+ -- LRM08 13.3 Context declarations
+ -- [...] or if a selected name in [a use clause or] a context
+ -- reference in a context declaration has the library logic
+ -- name WORK as a prefix.
+ El1 := El;
+ while El1 /= Null_Iir loop
+ if Has_Work_Library_Prefix (Get_Selected_Name (El1)) then
+ Error_Work_Prefix (El1);
+ exit;
+ end if;
+ El1 := Get_Context_Reference_Chain (El1);
+ end loop;
+ when others =>
+ raise Internal_Error;
+ end case;
+ El := Get_Chain (El);
+ end loop;
+
+ -- GHDL: forbid self-reference by making declaration visible at the end.
+ -- This violates LRM08 12.3 Visibility: A declaration is visible only
+ -- within a certain part of its scope; ...
+ Set_Visible_Flag (Decl, True);
+ end Sem_Context_Declaration;
+
-- Access to the current design unit. This is set, saved, restored, cleared
-- by the procedure semantic.
Current_Design_Unit: Iir_Design_Unit := Null_Iir;
@@ -2827,6 +2958,8 @@ package body Sem is
Sem_Configuration_Declaration (El);
when Iir_Kind_Package_Instantiation_Declaration =>
Sem_Package_Instantiation_Declaration (El);
+ when Iir_Kind_Context_Declaration =>
+ Sem_Context_Declaration (El);
when others =>
Error_Kind ("semantic", El);
end case;