aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-12-30 16:06:01 +0100
committerTristan Gingold <tgingold@free.fr>2019-12-30 16:06:01 +0100
commita79870e0fef0b94e7064c60b4672f74cddc15e95 (patch)
tree82471198a30800510d2220313ada4e81d97ca8fe
parent6f2290abd601ab96ab934a8503ed96e8312dd728 (diff)
downloadghdl-a79870e0fef0b94e7064c60b4672f74cddc15e95.tar.gz
ghdl-a79870e0fef0b94e7064c60b4672f74cddc15e95.tar.bz2
ghdl-a79870e0fef0b94e7064c60b4672f74cddc15e95.zip
ams-vhdl: improve error recovery
-rw-r--r--src/vhdl/vhdl-nodes.ads1
-rw-r--r--src/vhdl/vhdl-nodes_meta.adb3
-rw-r--r--src/vhdl/vhdl-parse.adb3
-rw-r--r--src/vhdl/vhdl-sem_decls.adb133
-rw-r--r--src/vhdl/vhdl-sem_stmts.adb7
-rw-r--r--src/vhdl/vhdl-sem_types.adb6
6 files changed, 92 insertions, 61 deletions
diff --git a/src/vhdl/vhdl-nodes.ads b/src/vhdl/vhdl-nodes.ads
index dd90d12d1..9a6e671e1 100644
--- a/src/vhdl/vhdl-nodes.ads
+++ b/src/vhdl/vhdl-nodes.ads
@@ -4617,6 +4617,7 @@ package Vhdl.Nodes is
-- Iir_Kind_Error (Short)
-- Can be used instead of an expression or a type.
-- Get/Set_Type (Field1)
+ -- Get/Set_Nature (Alias Field1)
--
-- Get/Set_Error_Origin (Field2)
--
diff --git a/src/vhdl/vhdl-nodes_meta.adb b/src/vhdl/vhdl-nodes_meta.adb
index de6b46488..206716ae7 100644
--- a/src/vhdl/vhdl-nodes_meta.adb
+++ b/src/vhdl/vhdl-nodes_meta.adb
@@ -8434,7 +8434,8 @@ package body Vhdl.Nodes_Meta is
function Has_Nature (K : Iir_Kind) return Boolean is
begin
case K is
- when Iir_Kind_Nature_Declaration
+ when Iir_Kind_Error
+ | Iir_Kind_Nature_Declaration
| Iir_Kind_Subnature_Declaration
| Iir_Kind_Nature_Element_Declaration
| Iir_Kind_Terminal_Declaration
diff --git a/src/vhdl/vhdl-parse.adb b/src/vhdl/vhdl-parse.adb
index 39dc4ee68..e17846618 100644
--- a/src/vhdl/vhdl-parse.adb
+++ b/src/vhdl/vhdl-parse.adb
@@ -9110,7 +9110,8 @@ package body Vhdl.Parse is
Expect_Scan (Tok_End);
-- Skip 'procedural'.
- Expect_Scan (Tok_Procedural);
+ Expect_Scan (Tok_Procedural, "missing 'procedural' after 'end'");
+ Set_End_Has_Reserved_Id (Res, True);
Check_End_Name (Res);
diff --git a/src/vhdl/vhdl-sem_decls.adb b/src/vhdl/vhdl-sem_decls.adb
index 23458bd35..d30fd6e85 100644
--- a/src/vhdl/vhdl-sem_decls.adb
+++ b/src/vhdl/vhdl-sem_decls.adb
@@ -2090,7 +2090,7 @@ package body Vhdl.Sem_Decls is
end if;
end Sem_Terminal_Declaration;
- procedure Sem_Branch_Quantity_Declaration (Decl : Iir; Last_Decl : Iir)
+ procedure Sem_Branch_Quantity_Declaration (Decl : Iir; Prev_Decl : Iir)
is
Plus_Name : Iir;
Minus_Name : Iir;
@@ -2106,9 +2106,15 @@ package body Vhdl.Sem_Decls is
if Plus_Name = Null_Iir then
-- List of identifier.
Is_Second := True;
- Plus_Name := Get_Plus_Terminal (Last_Decl);
- Minus_Name := Get_Minus_Terminal (Last_Decl);
- Value := Get_Default_Value (Last_Decl);
+ Plus_Name := Get_Plus_Terminal (Prev_Decl);
+ Minus_Name := Get_Minus_Terminal (Prev_Decl);
+ if Get_Kind (Decl) = Get_Kind (Prev_Decl) then
+ -- Keep the same default value for all across and all through.
+ Value := Get_Default_Value (Prev_Decl);
+ else
+ -- But do not use the across default value for through quantity.
+ Value := Get_Default_Value (Decl);
+ end if;
else
Is_Second := False;
Plus_Name := Sem_Terminal_Name (Plus_Name);
@@ -2129,68 +2135,79 @@ package body Vhdl.Sem_Decls is
--
-- GHDL: FIXME: isn't it self-referential with the definition of
-- the terminal nature ?
- Minus_Name := Get_Reference
- (Get_Nature_Simple_Nature (Get_Nature (Plus_Name)));
+ if Is_Error (Plus_Name) then
+ Minus_Name := Error_Mark;
+ else
+ Minus_Name := Get_Reference
+ (Get_Nature_Simple_Nature (Get_Nature (Plus_Name)));
+ end if;
end if;
Value := Get_Default_Value (Decl);
end if;
Set_Plus_Terminal (Decl, Plus_Name);
Set_Minus_Terminal (Decl, Minus_Name);
- declare
- Plus_Nature : constant Iir := Get_Nature (Plus_Name);
- Minus_Nature : constant Iir := Get_Nature (Minus_Name);
- Plus_Composite : constant Boolean :=
- Is_Composite_Nature (Plus_Nature);
- Minus_Composite : constant Boolean :=
- Is_Composite_Nature (Minus_Nature);
- begin
- -- AMS-LRM17 6.4.2.7 Quantity declarations
- -- If the terminals denoted by the terminal names of a terminal
- -- aspect are both of composite natures, then they shall be of the
- -- same nature, [and for each element of the plus terminal there
- -- shall be a matching element of the minus terminal.]
- -- If one terminal is a terminal of a composite nature and the
- -- other of a scalar nature, then the scalar nature nature shall be
- -- the nature of the scalar subelements of the composite terminal.
- if (Plus_Composite and Minus_Composite)
- or else (not Plus_Composite and not Minus_Composite)
- then
- if Get_Base_Nature (Plus_Nature) /= Get_Base_Nature (Minus_Nature)
- then
- Error_Msg_Sem
- (+Decl, "terminals must be of the same nature");
- end if;
- Nat := Plus_Nature;
- elsif Plus_Composite then
- pragma Assert (not Minus_Composite);
- if (Get_Nature_Simple_Nature (Plus_Nature)
- /= Get_Base_Nature (Minus_Nature))
- then
- Error_Msg_Sem
- (+Decl, "minus terminal must be of the nature of "
- & "plus subelements");
- end if;
- Nat := Plus_Nature;
- else
- pragma Assert (Minus_Composite and not Plus_Composite);
- if (Get_Nature_Simple_Nature (Minus_Nature)
- /= Get_Base_Nature (Plus_Nature))
+ if not Is_Error (Plus_Name) and then not Is_Error (Minus_Name) then
+ declare
+ Plus_Nature : constant Iir := Get_Nature (Plus_Name);
+ Minus_Nature : constant Iir := Get_Nature (Minus_Name);
+ Plus_Composite : constant Boolean :=
+ Is_Composite_Nature (Plus_Nature);
+ Minus_Composite : constant Boolean :=
+ Is_Composite_Nature (Minus_Nature);
+ begin
+ -- AMS-LRM17 6.4.2.7 Quantity declarations
+ -- If the terminals denoted by the terminal names of a terminal
+ -- aspect are both of composite natures, then they shall be of the
+ -- same nature, [and for each element of the plus terminal there
+ -- shall be a matching element of the minus terminal.]
+ -- If one terminal is a terminal of a composite nature and the
+ -- other of a scalar nature, then the scalar nature nature shall
+ -- be the nature of the scalar subelements of the composite
+ -- terminal.
+ if (Plus_Composite and Minus_Composite)
+ or else (not Plus_Composite and not Minus_Composite)
then
- Error_Msg_Sem
- (+Decl, "plus terminal must be of the nature of "
- & "minus subelements");
+ if (Get_Base_Nature (Plus_Nature)
+ /= Get_Base_Nature (Minus_Nature))
+ then
+ Error_Msg_Sem
+ (+Decl, "terminals must be of the same nature");
+ end if;
+ Nat := Plus_Nature;
+ elsif Plus_Composite then
+ pragma Assert (not Minus_Composite);
+ if (Get_Nature_Simple_Nature (Plus_Nature)
+ /= Get_Base_Nature (Minus_Nature))
+ then
+ Error_Msg_Sem
+ (+Decl, "minus terminal must be of the nature of "
+ & "plus subelements");
+ end if;
+ Nat := Plus_Nature;
+ else
+ pragma Assert (Minus_Composite and not Plus_Composite);
+ if (Get_Nature_Simple_Nature (Minus_Nature)
+ /= Get_Base_Nature (Plus_Nature))
+ then
+ Error_Msg_Sem
+ (+Decl, "plus terminal must be of the nature of "
+ & "minus subelements");
+ end if;
+ Nat := Minus_Nature;
end if;
- Nat := Minus_Nature;
- end if;
- end;
- case Iir_Kinds_Branch_Quantity_Declaration (Get_Kind (Decl)) is
- when Iir_Kind_Across_Quantity_Declaration =>
- Branch_Type := Get_Across_Type (Nat);
- when Iir_Kind_Through_Quantity_Declaration =>
- Branch_Type := Get_Through_Type (Nat);
- end case;
- pragma Assert (Branch_Type /= Null_Iir);
+ end;
+
+ case Iir_Kinds_Branch_Quantity_Declaration (Get_Kind (Decl)) is
+ when Iir_Kind_Across_Quantity_Declaration =>
+ Branch_Type := Get_Across_Type (Nat);
+ when Iir_Kind_Through_Quantity_Declaration =>
+ Branch_Type := Get_Through_Type (Nat);
+ end case;
+ pragma Assert (Branch_Type /= Null_Iir);
+ else
+ Branch_Type := Error_Mark;
+ end if;
Set_Type (Decl, Branch_Type);
Set_Name_Staticness (Decl, Locally);
diff --git a/src/vhdl/vhdl-sem_stmts.adb b/src/vhdl/vhdl-sem_stmts.adb
index e1cb740b6..98e01ccb3 100644
--- a/src/vhdl/vhdl-sem_stmts.adb
+++ b/src/vhdl/vhdl-sem_stmts.adb
@@ -2107,6 +2107,7 @@ package body Vhdl.Sem_Stmts is
procedure Sem_Simple_Simultaneous_Statement (Stmt : Iir)
is
Left, Right : Iir;
+ Left_Type, Right_Type : Iir;
Res_Type : Iir;
begin
Left := Get_Simultaneous_Left (Stmt);
@@ -2120,6 +2121,12 @@ package body Vhdl.Sem_Stmts is
return;
end if;
+ Left_Type := Get_Type (Left);
+ Right_Type := Get_Type (Right);
+ if Left_Type = Null_Iir or else Right_Type = Null_Iir then
+ return;
+ end if;
+
Res_Type := Search_Compatible_Type (Get_Type (Left), Get_Type (Right));
if Res_Type = Null_Iir then
Error_Msg_Sem
diff --git a/src/vhdl/vhdl-sem_types.adb b/src/vhdl/vhdl-sem_types.adb
index 6e9b87928..c02e682a8 100644
--- a/src/vhdl/vhdl-sem_types.adb
+++ b/src/vhdl/vhdl-sem_types.adb
@@ -2715,7 +2715,9 @@ package body Vhdl.Sem_Types is
function Is_Nature_Type (Dtype : Iir) return Boolean is
begin
- case Iir_Kinds_Type_And_Subtype_Definition (Get_Kind (Dtype)) is
+ case Get_Kind (Dtype) is
+ when Iir_Kind_Error =>
+ return True;
when Iir_Kind_Floating_Type_Definition
| Iir_Kind_Floating_Subtype_Definition =>
return True;
@@ -2751,6 +2753,8 @@ package body Vhdl.Sem_Types is
| Iir_Kind_Enumeration_Subtype_Definition
| Iir_Kind_Enumeration_Type_Definition =>
return False;
+ when others =>
+ Error_Kind ("is_nature_type", Dtype);
end case;
end Is_Nature_Type;