From 3e14b70c1f1decc36cecabe909c5cb2c3464f7d3 Mon Sep 17 00:00:00 2001
From: Tristan Gingold
Date: Sun, 10 Jan 2016 07:24:30 +0100
Subject: vhdl08: maybe insert implicit condition operator in concurrent
 statement.

---
 src/vhdl/sem_expr.adb | 32 ++++++++++++++++++++++++--------
 src/vhdl/sem_expr.ads |  4 ++++
 src/vhdl/sem_psl.adb  | 32 +++++++++++++++++++++-----------
 3 files changed, 49 insertions(+), 19 deletions(-)

(limited to 'src/vhdl')

diff --git a/src/vhdl/sem_expr.adb b/src/vhdl/sem_expr.adb
index 7500a55..bbd68d4 100644
--- a/src/vhdl/sem_expr.adb
+++ b/src/vhdl/sem_expr.adb
@@ -4420,10 +4420,32 @@ package body Sem_Expr is
       return Sem_Expression_Ov (Expr1, Get_Base_Type (Res));
    end Sem_Case_Expression;
 
+   function Insert_Condition_Operator (Cond : Iir) return Iir
+   is
+      Op : Iir;
+      Res : Iir;
+   begin
+      Op := Create_Iir (Iir_Kind_Condition_Operator);
+      Location_Copy (Op, Cond);
+      Set_Operand (Op, Cond);
+
+      Res := Sem_Operator (Op, Boolean_Type_Definition, 1);
+      Check_Read (Res);
+      return Res;
+   end Insert_Condition_Operator;
+
+   function Maybe_Insert_Condition_Operator (Expr : Iir) return Iir is
+   begin
+      if Get_Base_Type (Get_Type (Expr)) = Boolean_Type_Definition then
+         return Expr;
+      else
+         return Insert_Condition_Operator (Expr);
+      end if;
+   end Maybe_Insert_Condition_Operator;
+
    function Sem_Condition (Cond : Iir) return Iir
    is
       Res : Iir;
-      Op : Iir;
    begin
       if Vhdl_Std < Vhdl_08 then
          Res := Sem_Expression (Cond, Boolean_Type_Definition);
@@ -4493,13 +4515,7 @@ package body Sem_Expr is
          --  type of the expresion with the implicit application shall be
          --  BOOLEAN defined in package STANDARD.
 
-         Op := Create_Iir (Iir_Kind_Condition_Operator);
-         Location_Copy (Op, Res);
-         Set_Operand (Op, Res);
-
-         Res := Sem_Operator (Op, Boolean_Type_Definition, 1);
-         Check_Read (Res);
-         return Res;
+         return Insert_Condition_Operator (Res);
       end if;
    end Sem_Condition;
 
diff --git a/src/vhdl/sem_expr.ads b/src/vhdl/sem_expr.ads
index 5d84902..523ace9 100644
--- a/src/vhdl/sem_expr.ads
+++ b/src/vhdl/sem_expr.ads
@@ -69,6 +69,10 @@ package Sem_Expr is
    --  A check is made that COND can be read.
    function Sem_Condition (Cond : Iir) return Iir;
 
+   --  Insert an implicit condition operator for EXPR.  Use only when EXPR
+   --  is fully analyzed, otherwise use Sem_Condition.
+   function Maybe_Insert_Condition_Operator (Expr : Iir) return Iir;
+
    --  Same as Sem_Expression but knowing that the type of EXPR must be a
    --  composite type.  Used for expressions in assignment statement when the
    --  target is an aggregate.
diff --git a/src/vhdl/sem_psl.adb b/src/vhdl/sem_psl.adb
index 8811a0c..0a1bf1c 100644
--- a/src/vhdl/sem_psl.adb
+++ b/src/vhdl/sem_psl.adb
@@ -478,6 +478,23 @@ package body Sem_Psl is
       Close_Declarative_Region;
    end Sem_Psl_Declaration;
 
+   function Rewrite_As_Concurrent_Assertion (Stmt : Iir) return Iir
+   is
+      Res : Iir;
+      Cond : Iir;
+   begin
+      Res := Create_Iir (Iir_Kind_Concurrent_Assertion_Statement);
+      Set_Location (Res, Get_Location (Stmt));
+      Cond := Get_HDL_Node (Get_Psl_Property (Stmt));
+      Cond := Sem_Expr.Maybe_Insert_Condition_Operator (Cond);
+      Set_Assertion_Condition (Res, Cond);
+      Set_Label (Res, Get_Label (Stmt));
+      Set_Severity_Expression (Res, Get_Severity_Expression (Stmt));
+      Set_Report_Expression (Res, Get_Report_Expression (Stmt));
+      Set_Postponed_Flag (Res, False);
+      return Res;
+   end Rewrite_As_Concurrent_Assertion;
+
    function Sem_Psl_Assert_Statement (Stmt : Iir) return Iir
    is
       Prop : Node;
@@ -486,7 +503,7 @@ package body Sem_Psl is
    begin
       Prop := Get_Psl_Property (Stmt);
       Prop := Sem_Property (Prop, True);
-      Extract_Clock (Prop, Clk);
+      Set_Psl_Property (Stmt, Prop);
 
       --  Sem report and severity expressions.
       Sem_Report_Statement (Stmt);
@@ -496,21 +513,13 @@ package body Sem_Psl is
       then
          --  This is a simple assertion.  Convert to a non-PSL statement, as
          --  the handling is simpler (and the assertion doesn't need a clock).
-         Res := Create_Iir (Iir_Kind_Concurrent_Assertion_Statement);
-         Set_Location (Res, Get_Location (Stmt));
-         Set_Assertion_Condition (Res, Get_HDL_Node (Prop));
-         Set_Label (Res, Get_Label (Stmt));
-         Set_Severity_Expression (Res, Get_Severity_Expression (Stmt));
-         Set_Report_Expression (Res, Get_Report_Expression (Stmt));
-         Set_Postponed_Flag (Res, False);
+         Res := Rewrite_As_Concurrent_Assertion (Stmt);
          Free_Iir (Stmt);
-         pragma Assert (Clk = Null_Node);
          return Res;
-      else
-         Set_Psl_Property (Stmt, Prop);
       end if;
 
       --  Properties must be clocked.
+      Extract_Clock (Prop, Clk);
       if Clk = Null_Node then
          if Current_Psl_Default_Clock = Null_Iir then
             Error_Msg_Sem ("no clock for PSL assert", Stmt);
@@ -520,6 +529,7 @@ package body Sem_Psl is
          end if;
       end if;
       Set_PSL_Clock (Stmt, Clk);
+      Set_Psl_Property (Stmt, Prop);
 
       --  Check simple subset restrictions.
       PSL.Subsets.Check_Simple (Prop);
-- 
cgit