summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--canon.adb12
-rw-r--r--sem_expr.adb39
-rw-r--r--sem_expr.ads5
-rw-r--r--sem_names.adb13
-rw-r--r--sem_names.ads16
-rw-r--r--sem_stmts.adb15
6 files changed, 91 insertions, 9 deletions
diff --git a/canon.adb b/canon.adb
index 32f0004..7848c5a 100644
--- a/canon.adb
+++ b/canon.adb
@@ -65,6 +65,7 @@ package body Canon is
procedure Canon_Block_Configuration (Top : Iir_Design_Unit;
Conf : Iir_Block_Configuration);
+ procedure Canon_Subtype_Indication (Def : Iir);
procedure Canon_Subtype_Indication_If_Anonymous (Def : Iir);
procedure Canon_Extract_Sensitivity_Aggregate
@@ -662,7 +663,13 @@ package body Canon is
when Iir_Kind_Allocator_By_Expression =>
Canon_Expression (Get_Expression (Expr));
when Iir_Kind_Allocator_By_Subtype =>
- null;
+ declare
+ Ind : constant Iir := Get_Expression (Expr);
+ begin
+ if Get_Kind (Ind) = Iir_Kind_Array_Subtype_Definition then
+ Canon_Subtype_Indication (Ind);
+ end if;
+ end;
when Iir_Kinds_Literal
| Iir_Kind_Simple_Aggregate
@@ -2163,8 +2170,7 @@ package body Canon is
case Get_Kind (Def) is
when Iir_Kind_Array_Subtype_Definition =>
declare
- Indexes : constant Iir_List :=
- Get_Index_Subtype_List (Def);
+ Indexes : constant Iir_List := Get_Index_Subtype_List (Def);
Index : Iir;
begin
for I in Natural loop
diff --git a/sem_expr.adb b/sem_expr.adb
index 33addfd..e29ce87 100644
--- a/sem_expr.adb
+++ b/sem_expr.adb
@@ -4000,6 +4000,45 @@ package body Sem_Expr is
return Res;
end Sem_Expression;
+ function Sem_Composite_Expression (Expr : Iir) return Iir
+ is
+ Res : Iir;
+ begin
+ Res := Sem_Expression_Ov (Expr, Null_Iir);
+ if Is_Overloaded (Res) then
+ declare
+ List : constant Iir_List := Get_Overload_List (Get_Type (Res));
+ Res_Type : Iir;
+ Atype : Iir;
+ begin
+ Res_Type := Null_Iir;
+ for I in Natural loop
+ Atype := Get_Nth_Element (List, I);
+ exit when Atype = Null_Iir;
+ if Is_Aggregate_Type (Atype) then
+ Add_Result (Res_Type, Atype);
+ end if;
+ end loop;
+
+ if Res_Type = Null_Iir then
+ Error_Overload (Expr);
+ return Null_Iir;
+ elsif Is_Overload_List (Res_Type) then
+ Error_Overload (Expr);
+ Disp_Overload_List (Get_Overload_List (Res_Type), Expr);
+ Free_Overload_List (Res_Type);
+ return Null_Iir;
+ else
+ return Sem_Expression_Ov (Expr, Res_Type);
+ end if;
+ end;
+ else
+ -- Either an error (already handled) or not overloaded. Type
+ -- matching will be done later (when the target is analyzed).
+ return Res;
+ end if;
+ end Sem_Composite_Expression;
+
function Sem_Expression_Universal (Expr : Iir) return Iir
is
Expr1 : Iir;
diff --git a/sem_expr.ads b/sem_expr.ads
index 3304923..d8c006b 100644
--- a/sem_expr.ads
+++ b/sem_expr.ads
@@ -69,6 +69,11 @@ package Sem_Expr is
-- A check is made that COND can be read.
function Sem_Condition (Cond : 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.
+ function Sem_Composite_Expression (Expr : Iir) return Iir;
+
-- Check EXPR can be read.
procedure Check_Read (Expr : Iir);
diff --git a/sem_names.adb b/sem_names.adb
index 45ce377..48f4d28 100644
--- a/sem_names.adb
+++ b/sem_names.adb
@@ -87,6 +87,16 @@ package body Sem_Names is
return Res;
end Create_Overload_List;
+ procedure Free_Overload_List (N : in out Iir_Overload_List)
+ is
+ List : Iir_List;
+ begin
+ List := Get_Overload_List (N);
+ Destroy_Iir_List (List);
+ Free_Iir (N);
+ N := Null_Iir;
+ end Free_Overload_List;
+
function Simplify_Overload_List (List : Iir_List) return Iir
is
Res : Iir;
@@ -144,9 +154,6 @@ package body Sem_Names is
return Simplify_Overload_List (Res_List);
end Create_List_Of_Types;
- -- Add new interpretation DECL to RES.
- -- Create an overload_list if necessary.
- -- Before the first call, RES should be set to NULL_IIR.
procedure Add_Result (Res : in out Iir; Decl : Iir)
is
Nres : Iir;
diff --git a/sem_names.ads b/sem_names.ads
index 8e9ffd0..75db2fc 100644
--- a/sem_names.ads
+++ b/sem_names.ads
@@ -64,20 +64,32 @@ package Sem_Names is
function Is_Overload_List (An_Iir: Iir) return Boolean;
pragma Inline (Is_Overload_List);
- -- Create an overload list.
- -- must be destroyed with free_iir.
+ -- Create an overload list, that must be destroyed by Destroy_Overload_List.
function Get_Overload_List return Iir_Overload_List;
pragma Inline (Get_Overload_List);
+
function Create_Overload_List (List : Iir_List) return Iir_Overload_List;
pragma Inline (Create_Overload_List);
+ -- Free the list node (and the list itself).
+ procedure Free_Overload_List (N : in out Iir_Overload_List);
+ pragma Unreferenced (Free_Overload_List);
+
+ -- Display an error message if the overload resolution for EXPR find more
+ -- than one interpretation.
procedure Error_Overload (Expr: Iir);
+ -- Disp the overload list LIST.
procedure Disp_Overload_List (List : Iir_List; Loc : Iir);
-- Convert a list to either Null_Iir, an element or an overload list.
function Simplify_Overload_List (List : Iir_List) return Iir;
+ -- Add new interpretation DECL to RES.
+ -- Create an overload_list if necessary.
+ -- Before the first call, RES should be set to NULL_IIR.
+ procedure Add_Result (Res : in out Iir; Decl : Iir);
+
-- Return TRUE iff TYPE1 and TYPE2 are closely related.
function Are_Types_Closely_Related (Type1, Type2 : Iir) return Boolean;
diff --git a/sem_stmts.adb b/sem_stmts.adb
index 864cec6..8067abb 100644
--- a/sem_stmts.adb
+++ b/sem_stmts.adb
@@ -687,18 +687,31 @@ package body Sem_Stmts is
-- Find the variable.
Target := Get_Target (Stmt);
Expr := Get_Expression (Stmt);
+
+ -- LRM93 8.5 Variable assignment statement
+ -- If the target of the variable assignment statement is in the form of
+ -- an aggregate, then the type of the aggregate must be determinable
+ -- from the context, excluding the aggregate itself but including the
+ -- fact that the type of the aggregate must be a composite type. The
+ -- base type of the expression on the right-hand side must be the
+ -- same as the base type of the aggregate.
+ --
+ -- GHDL: this means that the type can only be deduced from the
+ -- expression (and not from the target).
if Get_Kind (Target) = Iir_Kind_Aggregate then
if Get_Kind (Expr) = Iir_Kind_Aggregate then
Error_Msg_Sem ("can't determine type, use type qualifier", Expr);
return;
end if;
- Expr := Sem_Expression (Get_Expression (Stmt), Null_Iir);
+ Expr := Sem_Composite_Expression (Get_Expression (Stmt));
if Expr = Null_Iir then
return;
end if;
Check_Read (Expr);
Set_Expression (Stmt, Expr);
Target_Type := Get_Type (Expr);
+
+ -- FIXME: check elements are identified at most once.
else
Target_Type := Null_Iir;
end if;