diff options
author | Tristan Gingold <tgingold@free.fr> | 2014-01-08 04:22:40 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2014-01-08 04:22:40 +0100 |
commit | 19211ffc421560405aee966ee742ae849c73a31c (patch) | |
tree | 1036f20b80fd8133c94fccb8e4ff6a9cc226818d /sem_expr.adb | |
parent | 429a5e4a2d7714915b45b33869f06f954c29a316 (diff) | |
download | ghdl-19211ffc421560405aee966ee742ae849c73a31c.tar.gz ghdl-19211ffc421560405aee966ee742ae849c73a31c.tar.bz2 ghdl-19211ffc421560405aee966ee742ae849c73a31c.zip |
Rework literal typing (and initial work for condition operator).
Diffstat (limited to 'sem_expr.adb')
-rw-r--r-- | sem_expr.adb | 622 |
1 files changed, 285 insertions, 337 deletions
diff --git a/sem_expr.adb b/sem_expr.adb index 47c29f87b..ebe7679b1 100644 --- a/sem_expr.adb +++ b/sem_expr.adb @@ -88,10 +88,12 @@ package body Sem_Expr is Set_Type (Target, A_Type); end Replace_Type; - -- Return true if ID is overloaded, ie has several meanings. - function Is_Overloaded (Id: Iir) return Boolean is + -- Return true if EXPR is overloaded, ie has several meanings. + function Is_Overloaded (Expr : Iir) return Boolean + is + Expr_Type : constant Iir := Get_Type (Expr); begin - return Is_Overload_List (Get_Type (Id)); + return Expr_Type = Null_Iir or else Is_Overload_List (Expr_Type); end Is_Overloaded; -- Return the common type of base types LEFT and RIGHT. @@ -148,6 +150,163 @@ package body Sem_Expr is return Are_Types_Compatible (Get_Type (Left), Get_Type (Right)); end Are_Nodes_Compatible; + -- Return TRUE iif LEFT_TYPE and RIGHT_TYPES are compatible. RIGHT_TYPES + -- may be an overload list. + function Compatibility_Types1 (Left_Type : Iir; Right_Types : Iir) + return Boolean + is + El : Iir; + Right_List : Iir_List; + begin + pragma Assert (not Is_Overload_List (Left_Type)); + + if Is_Overload_List (Right_Types) then + Right_List := Get_Overload_List (Right_Types); + for I in Natural loop + El := Get_Nth_Element (Right_List, I); + exit when El = Null_Iir; + if Are_Types_Compatible (Left_Type, El) then + return True; + end if; + end loop; + return False; + else + return Are_Types_Compatible (Left_Type, Right_Types); + end if; + end Compatibility_Types1; + + -- Return compatibility for nodes LEFT and RIGHT. + -- LEFT is expected to be an interface of a function definition. + -- Type of RIGHT can be an overload_list + -- RIGHT might be implicitly converted to LEFT. + function Compatibility_Nodes (Left : Iir; Right : Iir) + return Boolean + is + Left_Type, Right_Type : Iir; + begin + Left_Type := Get_Base_Type (Get_Type (Left)); + Right_Type := Get_Type (Right); + + -- Check. + case Get_Kind (Left_Type) is + when Iir_Kind_Floating_Type_Definition + | Iir_Kind_Enumeration_Type_Definition + | Iir_Kind_Integer_Type_Definition + | Iir_Kind_Record_Type_Definition + | Iir_Kind_File_Type_Definition + | Iir_Kind_Physical_Type_Definition + | Iir_Kind_Access_Type_Definition + | Iir_Kind_Array_Type_Definition => + null; + when others => + Error_Kind ("are_node_compatible_ov", Left_Type); + end case; + + return Compatibility_Types1 (Left_Type, Right_Type); + end Compatibility_Nodes; + + -- Return TRUE iff A_TYPE can be the type of string or bit string literal + -- EXPR. EXPR is needed to distinguish between string and bit string + -- for VHDL87 rule about the type of a bit string. + function Is_String_Literal_Type (A_Type : Iir; Expr : Iir) return Boolean + is + Base_Type : constant Iir := Get_Base_Type (A_Type); + El_Bt : Iir; + begin + -- LRM 7.3.1 + -- [...] the type of the literal must be a one-dimensional array ... + if not Is_Unidim_Array_Type (Base_Type) then + return False; + end if; + -- LRM 7.3.1 + -- ... of a character type ... + El_Bt := Get_Base_Type (Get_Element_Subtype (Base_Type)); + if Get_Kind (El_Bt) /= Iir_Kind_Enumeration_Type_Definition then + return False; + end if; + -- LRM87 7.3.1 + -- ... (for string literals) or of type BIT (for bit string literals). + if Flags.Vhdl_Std = Vhdl_87 + and then Get_Kind (Expr) = Iir_Kind_Bit_String_Literal + and then El_Bt /= Bit_Type_Definition + then + return False; + end if; + return True; + end Is_String_Literal_Type; + + -- Return TRUE iff A_TYPE can be the type of an aggregate. + function Is_Aggregate_Type (A_Type : Iir) return Boolean is + begin + -- LRM 7.3.2 Aggregates + -- [...] the type of the aggregate must be a composite type. + case Get_Kind (Get_Base_Type (A_Type)) is + when Iir_Kind_Array_Type_Definition + | Iir_Kind_Record_Type_Definition => + return True; + when others => + return False; + end case; + end Is_Aggregate_Type; + + -- Return TRUE iff A_TYPE can be the type of a null literal. + function Is_Null_Literal_Type (A_Type : Iir) return Boolean is + begin + -- LRM 7.3.1 Literals + -- The literal NULL represents the null access value for any access + -- type. + return + Get_Kind (Get_Base_Type (A_Type)) = Iir_Kind_Access_Type_Definition; + end Is_Null_Literal_Type; + + -- Return TRUE iff A_TYPE can be the type of allocator EXPR. Note that + -- the allocator must have been analyzed. + function Is_Allocator_Type (A_Type : Iir; Expr : Iir) return Boolean + is + Base_Type : constant Iir := Get_Base_Type (A_Type); + Designated_Type : Iir; + begin + -- LRM 7.3.6 Allocators + -- [...] the value returned is of an access type having the named + -- designated type. + + if Get_Kind (Base_Type) /= Iir_Kind_Access_Type_Definition then + return False; + end if; + Designated_Type := Get_Allocator_Designated_Type (Expr); + pragma Assert (Designated_Type /= Null_Iir); + -- Cheat: there is no allocators on universal types. + return Get_Base_Type (Get_Designated_Type (Base_Type)) + = Get_Base_Type (Designated_Type); + end Is_Allocator_Type; + + -- Return TRUE iff the type of EXPR is compatible with A_TYPE + function Is_Expr_Compatible (A_Type : Iir; Expr : Iir) return Boolean + is + Expr_Type : constant Iir := Get_Type (Expr); + begin + if Expr_Type /= Null_Iir then + return Compatibility_Types1 (A_Type, Expr_Type); + end if; + + case Get_Kind (Expr) is + when Iir_Kind_Aggregate => + return Is_Aggregate_Type (A_Type); + when Iir_Kind_String_Literal + | Iir_Kind_Bit_String_Literal => + return Is_String_Literal_Type (A_Type, Expr); + when Iir_Kind_Null_Literal => + return Is_Null_Literal_Type (A_Type); + when Iir_Kind_Allocator_By_Expression + | Iir_Kind_Allocator_By_Subtype => + return Is_Allocator_Type (A_Type, Expr); + when others => + -- Error while EXPR was typed. FIXME: should create an ERROR + -- node? + return False; + end case; + end Is_Expr_Compatible; + function Check_Is_Expression (Expr : Iir; Loc : Iir) return Iir is begin @@ -335,103 +494,6 @@ package body Sem_Expr is end if; end Search_Compatible_Type; - -- Return compatibility for type nodes LEFT and RIGHT. - function Compatibility (Left_Type, Right_Type : Iir) - return Boolean - is - Right_Base_Type : Iir; - Left_Base_Type : Iir; - begin - Right_Base_Type := Get_Base_Type (Right_Type); - Left_Base_Type := Get_Base_Type (Left_Type); - if Right_Base_Type = Left_Base_Type then - return True; - end if; - if Get_Kind (Left_Base_Type) = Iir_Kind_Integer_Type_Definition - and then Right_Base_Type = Convertible_Integer_Type_Definition - then - return True; - end if; - if Get_Kind (Left_Base_Type) = Iir_Kind_Floating_Type_Definition - and then Right_Base_Type = Convertible_Real_Type_Definition - then - return True; - end if; - return False; - end Compatibility; - - function Compatibility_Types1 (Left_Type : Iir; Right_Types : Iir) - return Boolean - is - El : Iir; - Right_List : Iir_List; - begin - if Is_Overload_List (Right_Types) then - Right_List := Get_Overload_List (Right_Types); - for I in Natural loop - El := Get_Nth_Element (Right_List, I); - exit when El = Null_Iir; - if Compatibility (Left_Type, El) then - return True; - end if; - end loop; - return False; - else - return Compatibility (Left_Type, Right_Types); - end if; - end Compatibility_Types1; - - -- Return compatibility for nodes LEFT and RIGHT. - -- LEFT is expected to be an interface of a function definition. - -- Type of RIGHT can be an overload_list - -- RIGHT might be implicitly converted to LEFT. - function Compatibility_Nodes (Left : Iir; Right : Iir) - return Boolean - is - Left_Type, Right_Type : Iir; - begin - Left_Type := Get_Base_Type (Get_Type (Left)); - Right_Type := Get_Type (Right); - - -- Check. - case Get_Kind (Left_Type) is - when Iir_Kind_Floating_Type_Definition - | Iir_Kind_Enumeration_Type_Definition - | Iir_Kind_Integer_Type_Definition - | Iir_Kind_Record_Type_Definition - | Iir_Kind_File_Type_Definition - | Iir_Kind_Physical_Type_Definition - | Iir_Kind_Access_Type_Definition - | Iir_Kind_Array_Type_Definition => - null; - when others => - Error_Kind ("are_node_compatible_ov", Left_Type); - end case; - - return Compatibility_Types1 (Left_Type, Right_Type); - end Compatibility_Nodes; - - function Compatibility_Types (Left_Types : Iir; Right_Types : Iir) - return Boolean - is - El : Iir; - Left_List : Iir_List; - begin - if Is_Overload_List (Left_Types) then - Left_List := Get_Overload_List (Left_Types); - for I in Natural loop - El := Get_Nth_Element (Left_List, I); - exit when El = Null_Iir; - if Compatibility_Types1 (El, Right_Types) then - return True; - end if; - end loop; - return False; - else - return Compatibility_Types1 (Left_Types, Right_Types); - end if; - end Compatibility_Types; - -- Semantize the range expression EXPR. -- If A_TYPE is not null_iir, EXPR is expected to be of type A_TYPE. -- LRM93 3.2.1.1 @@ -1528,7 +1590,7 @@ package body Sem_Expr is Set_Type (Expr, Get_Return_Type (Decl)); Interface_Chain := Get_Interface_Declaration_Chain (Decl); Err := False; - if Is_Overload_List (Get_Type (Left)) then + if Is_Overloaded (Left) then Left := Sem_Expression_Ov (Left, Get_Base_Type (Get_Type (Interface_Chain))); if Left = Null_Iir then @@ -1543,7 +1605,7 @@ package body Sem_Expr is end if; Check_Read (Left); if Arity = 2 then - if Is_Overload_List (Get_Type (Right)) then + if Is_Overloaded (Right) then Right := Sem_Expression_Ov (Right, Get_Base_Type (Get_Type (Get_Chain (Interface_Chain)))); @@ -1626,7 +1688,8 @@ package body Sem_Expr is -- Check return type. if Res_Type /= Null_Iir - and then not Compatibility (Res_Type, Get_Return_Type (Decl)) + and then + not Are_Types_Compatible (Res_Type, Get_Return_Type (Decl)) then goto Next; end if; @@ -1634,16 +1697,26 @@ package body Sem_Expr is Interface_Chain := Get_Interface_Declaration_Chain (Decl); -- Check arity. + + -- LRM93 2.5.2 Operator overloading + -- The subprogram specification of a unary operator must have + -- a single parameter [...] + -- The subprogram specification of a binary operator must have + -- two parameters [...] + -- + -- GHDL: So even in presence of default expression in a parameter, + -- a unary operation has to match with a binary operator. if Iir_Chains.Get_Chain_Length (Interface_Chain) /= Arity then goto Next; end if; -- Check operands. - if not Compatibility_Nodes (Interface_Chain, Left) then + if not Is_Expr_Compatible (Get_Type (Interface_Chain), Left) then goto Next; end if; if Arity = 2 then - if not Compatibility_Nodes (Get_Chain (Interface_Chain), Right) + if not Is_Expr_Compatible + (Get_Type (Get_Chain (Interface_Chain)), Right) then goto Next; end if; @@ -1740,7 +1813,7 @@ package body Sem_Expr is Decl := Get_Nth_Element (Overload_List, I); exit when Decl = Null_Iir; -- FIXME: wrong: compatibilty with return type and args. - if Compatibility (Get_Return_Type (Decl), Res_Type) then + if Are_Types_Compatible (Get_Return_Type (Decl), Res_Type) then if Full_Compat /= Null_Iir then Error_Operator_Overload (Overload_List); return Null_Iir; @@ -1754,37 +1827,6 @@ package body Sem_Expr is end if; end Sem_Operator; - -- Create a subtype for a string literal. - -- The literal must have been typed, with a type or a subtype. - -- FIXME: not general at all! - function Check_Type_For_String_Literal (A_Type : Iir; Expr : Iir) - return Boolean - is - Base_Type : constant Iir := Get_Base_Type (A_Type); - El_Bt : Iir; - begin - -- LRM 7.3.1 - -- [...] the type of the literal must be a one-dimensional array ... - if not Is_Unidim_Array_Type (Base_Type) then - return False; - end if; - -- LRM 7.3.1 - -- ... of a character type ... - El_Bt := Get_Base_Type (Get_Element_Subtype (Base_Type)); - if Get_Kind (El_Bt) /= Iir_Kind_Enumeration_Type_Definition then - return False; - end if; - -- LRM87 7.3.1 - -- ... (for string literals) or of type BIT (for bit string literals). - if Flags.Vhdl_Std = Vhdl_87 - and then Get_Kind (Expr) = Iir_Kind_Bit_String_Literal - and then El_Bt /= Bit_Type_Definition - then - return False; - end if; - return True; - end Check_Type_For_String_Literal; - -- Semantize LIT whose elements must be of type EL_TYPE, and return -- the length. -- FIXME: the errors are reported, but there is no mark of that. @@ -2135,7 +2177,7 @@ package body Sem_Expr is end if; end Sem_String_Choices_Range; - function Is_Name (Name : Iir) return Boolean + function Is_Choice_Name (Name : Iir) return Boolean is begin case Get_Kind (Name) is @@ -2147,7 +2189,7 @@ package body Sem_Expr is when others => return False; end case; - end Is_Name; + end Is_Choice_Name; procedure Sem_Choices_Range (Choice_Chain : in out Iir; @@ -2193,7 +2235,7 @@ package body Sem_Expr is Expr := Get_Expression (El); if Get_Kind (El) = Iir_Kind_Choice_By_Range then Expr := Sem_Discrete_Range_Expression (Expr, Sub_Type, True); - elsif Is_Name (Expr) then + elsif Is_Choice_Name (Expr) then declare Name : Iir; N_Choice : Iir; @@ -3388,96 +3430,74 @@ package body Sem_Expr is begin Arg := Get_Expression (Expr); Set_Expr_Staticness (Expr, None); - if Get_Type (Expr) = Null_Iir then - if Get_Kind (Expr) = Iir_Kind_Allocator_By_Expression then - if Get_Kind (Arg) /= Iir_Kind_Qualified_Expression then - raise Internal_Error; - end if; - Arg := Sem_Expression (Arg, Null_Iir); - if Arg = Null_Iir then - return Null_Iir; - end if; - Check_Read (Arg); - Arg_Type := Get_Type (Arg); - else - Arg := Sem_Types.Sem_Subtype_Indication (Arg); - if Arg = Null_Iir then - return Null_Iir; - end if; - -- LRM93 §7.3.6 - -- If an allocator includes a subtype indication and if the - -- type of the object created is an array type, then the - -- subtype indication must either denote a constrained - -- subtype or include an explicit index constraint. - if not Is_Fully_Constrained_Type (Arg) then - Error_Msg_Sem ("allocator of unconstrained " & - Disp_Node (Arg) & " is not allowed", Expr); - end if; - -- LRM93 7.3.6 - -- A subtype indication that is part of an allocator must - -- not include a resolution function. - if Is_Anonymous_Type_Definition (Arg) - and then Get_Resolution_Function (Arg) /= Null_Iir - then - Error_Msg_Sem ("subtype indication must not include" - & " a resolution function", Expr); - end if; - Arg_Type := Arg; - end if; + + Arg_Type := Get_Allocator_Designated_Type (Expr); + + if Arg_Type = Null_Iir then + -- Expression was not analyzed. + case Iir_Kinds_Allocator (Get_Kind (Expr)) is + when Iir_Kind_Allocator_By_Expression => + if Get_Kind (Arg) /= Iir_Kind_Qualified_Expression then + raise Internal_Error; + end if; + Arg := Sem_Expression (Arg, Null_Iir); + if Arg = Null_Iir then + return Null_Iir; + end if; + Check_Read (Arg); + Arg_Type := Get_Type (Arg); + when Iir_Kind_Allocator_By_Subtype => + Arg := Sem_Types.Sem_Subtype_Indication (Arg); + if Arg = Null_Iir then + return Null_Iir; + end if; + -- LRM93 §7.3.6 + -- If an allocator includes a subtype indication and if the + -- type of the object created is an array type, then the + -- subtype indication must either denote a constrained + -- subtype or include an explicit index constraint. + if not Is_Fully_Constrained_Type (Arg) then + Error_Msg_Sem + ("allocator of unconstrained " & + Disp_Node (Arg) & " is not allowed", Expr); + end if; + -- LRM93 7.3.6 + -- A subtype indication that is part of an allocator must + -- not include a resolution function. + if Is_Anonymous_Type_Definition (Arg) + and then Get_Resolution_Function (Arg) /= Null_Iir + then + Error_Msg_Sem ("subtype indication must not include" + & " a resolution function", Expr); + end if; + Arg_Type := Arg; + end case; Set_Expression (Expr, Arg); - else - if Get_Kind (Expr) = Iir_Kind_Allocator_By_Expression then - Arg_Type := Get_Type (Arg); - else - Arg_Type := Arg; - end if; + Set_Allocator_Designated_Type (Expr, Arg_Type); end if; + -- LRM 7.3.6 Allocators + -- The type of the access value returned by an allocator must be + -- determinable solely from the context, but using the fact that the + -- value returned is of an access type having the named designated + -- type. if A_Type = Null_Iir then - -- Pass 1. - -- LRM 7.3.6 Allocators - -- The type of the access value returned by an allocator must be - -- determinable solely from the context, but using the fact that the - -- value returned is of an access type having the named designated - -- type. - declare - Index : Visible_Type_Index_Type; - Vtype : Iir; - Btype : Iir; - Dtype : Iir; - List : Iir_List; - begin - List := Create_Iir_List; - Index := Get_First_Visible_Type; - while Index /= No_Visible_Type_Index loop - Vtype := Get_Visible_Type_Decl (Index); - Btype := Get_Base_Type (Get_Type (Vtype)); - if Get_Kind (Btype) = Iir_Kind_Access_Type_Definition then - Dtype := Get_Base_Type (Get_Designated_Type (Btype)); - if Dtype = Get_Base_Type (Arg_Type) then - Add_Element (List, Dtype); - end if; - end if; - Index := Get_Next_Visible_Type (Index); - end loop; - Set_Type (Expr, Simplify_Overload_List (List)); - end; + -- Type of the context is not yet known. + return Expr; else - if Get_Kind (A_Type) /= Iir_Kind_Access_Type_Definition then - if Get_Kind (A_Type) /= Iir_Kind_Error then - Error_Msg_Sem ("expected type is not an access type", Expr); + if not Is_Allocator_Type (A_Type, Expr) then + if Get_Kind (A_Type) /= Iir_Kind_Access_Type_Definition then + if Get_Kind (A_Type) /= Iir_Kind_Error then + Error_Msg_Sem ("expected type is not an access type", Expr); + end if; + else + Not_Match (Expr, A_Type); end if; return Null_Iir; end if; - if not Are_Types_Compatible (Arg_Type, Get_Designated_Type (A_Type)) - then - Not_Match (Expr, A_Type); - return Null_Iir; - end if; - Free_Old_Iir (Get_Type (Expr)); Set_Type (Expr, A_Type); + return Expr; end if; - return Expr; end Sem_Allocator; procedure Check_Read_Aggregate (Aggr : Iir) @@ -3810,87 +3830,31 @@ package body Sem_Expr is when Iir_Kind_String_Literal | Iir_Kind_Bit_String_Literal => - if A_Type /= Null_Iir then - if not Check_Type_For_String_Literal (A_Type, Expr) then - Not_Match (Expr, A_Type); - return Null_Iir; - end if; - -- It is enough ? - -- FIXME: check against LRM. + -- LRM93 7.3.1 Literals + -- The type of a string or bit string literal must be + -- determinable solely from the context in whcih the literal + -- appears, excluding the literal itself [...] + if A_Type = Null_Iir then + return Expr; + end if; + + if not Is_String_Literal_Type (A_Type, Expr) then + Not_Match (Expr, A_Type); + return Null_Iir; + else Replace_Type (Expr, A_Type); Sem_String_Literal (Expr); return Expr; end if; - -- Look on every visible declaration of unidimensional array. - declare - Vt: Visible_Type_Index_Type; - Vt_Type : Iir; - Decl: Iir; - List: Iir_List; - begin - Vt := Get_First_Visible_Type; - List := Create_Iir_List; - while Vt /= No_Visible_Type_Index loop - Vt_Type := Get_Type (Get_Visible_Type_Decl (Vt)); - Decl := Get_Base_Type (Vt_Type); - if Check_Type_For_String_Literal (Decl, Expr) then - Append_Element (List, Decl); - end if; - Vt := Get_Next_Visible_Type (Vt); - end loop; - case Get_Nbr_Elements (List) is - when 0 => - Destroy_Iir_List (List); - Error_Msg_Sem - ("no character type for string literal", Expr); - return Null_Iir; - when 1 => - Set_Type (Expr, Get_First_Element (List)); - Destroy_Iir_List (List); - Sem_String_Literal (Expr); - return Expr; - when others => - Set_Type (Expr, Create_Overload_List (List)); - return Expr; - end case; - end; - when Iir_Kind_Null_Literal => Set_Expr_Staticness (Expr, Locally); + -- GHDL: the LRM doesn't explain how the type of NULL is + -- determined. Use the same rule as string or aggregates. if A_Type = Null_Iir then - declare - Vt: Visible_Type_Index_Type; - Vt_Type : Iir; - Decl: Iir; - List: Iir_List; - begin - Vt := Get_First_Visible_Type; - List := Create_Iir_List; - while Vt /= No_Visible_Type_Index loop - Vt_Type := Get_Type (Get_Visible_Type_Decl (Vt)); - Decl := Get_Base_Type (Vt_Type); - if Get_Kind (Decl) = Iir_Kind_Access_Type_Definition then - Append_Element (List, Decl); - end if; - Vt := Get_Next_Visible_Type (Vt); - end loop; - case Get_Nbr_Elements (List) is - when 0 => - Error_Msg_Sem - ("no visible access type for null literal", Expr); - Destroy_Iir_List (List); - return Null_Iir; - when 1 => - Set_Type (Expr, Get_First_Element (List)); - Destroy_Iir_List (List); - return Expr; - when others => - Set_Type (Expr, Create_Overload_List (List)); - return Expr; - end case; - end; - elsif Get_Kind (A_Type) /= Iir_Kind_Access_Type_Definition then + return Expr; + end if; + if not Is_Null_Literal_Type (A_Type) then Error_Msg_Sem ("null literal can only be access type", Expr); return Null_Iir; else @@ -3898,6 +3862,17 @@ package body Sem_Expr is return Expr; end if; + when Iir_Kind_Aggregate => + -- LRM93 7.3.2 Aggregates + -- The type of an aggregate must be determinable solely from the + -- context in which the aggregate appears, excluding the aggregate + -- itself but [...] + if A_Type = Null_Iir then + return Expr; + else + return Sem_Aggregate (Expr, A_Type); + end if; + when Iir_Kind_Qualified_Expression => declare N_Type: Iir; @@ -3931,48 +3906,6 @@ package body Sem_Expr is | Iir_Kind_Allocator_By_Subtype => return Sem_Allocator (Expr, A_Type); - when Iir_Kind_Aggregate => - if A_Type = Null_Iir then - declare - Vt: Visible_Type_Index_Type; - Vt_Type : Iir; - Decl: Iir; - List: Iir_List; - Res : Iir; - begin - Vt := Get_First_Visible_Type; - List := Create_Iir_List; - while Vt /= No_Visible_Type_Index loop - Vt_Type := Get_Type (Get_Visible_Type_Decl (Vt)); - Decl := Get_Base_Type (Vt_Type); - case Get_Kind (Decl) is - when Iir_Kind_Array_Type_Definition - | Iir_Kind_Record_Type_Definition => - Append_Element (List, Decl); - when others => - null; - end case; - Vt := Get_Next_Visible_Type (Vt); - end loop; - case Get_Nbr_Elements (List) is - when 0 => - Destroy_Iir_List (List); - Error_Msg_Sem - ("no visible composite type for aggregate", Expr); - return Null_Iir; - when 1 => - Res := Sem_Aggregate (Expr, Get_First_Element (List)); - Destroy_Iir_List (List); - return Res; - when others => - Set_Type (Expr, Create_Overload_List (List)); - return Expr; - end case; - end; - else - return Sem_Aggregate (Expr, A_Type); - end if; - when Iir_Kinds_Procedure_Declaration => Error_Msg_Sem (Disp_Node (Expr) & " cannot be used as an expression", Expr); @@ -4027,7 +3960,7 @@ package body Sem_Expr is if A_Type = Null_Iir then Res := Sem_Expression_Ov (Expr, Null_Iir); else - if not Check_Type_For_String_Literal (A_Type, Expr) then + if not Is_String_Literal_Type (A_Type, Expr) then Not_Match (Expr, A_Type); return Null_Iir; end if; @@ -4040,8 +3973,12 @@ package body Sem_Expr is end case; if Res /= Null_Iir and then Is_Overloaded (Res) then + -- FIXME: clarify between overload and not determinable from the + -- context. Error_Overload (Expr); - Disp_Overload_List (Get_Overload_List (Get_Type (Res)), Expr); + if Get_Type (Res) /= Null_Iir then + Disp_Overload_List (Get_Overload_List (Get_Type (Res)), Expr); + end if; return Null_Iir; end if; return Res; @@ -4104,6 +4041,17 @@ package body Sem_Expr is return Null_Iir; end if; Expr_Type := Get_Type (Expr1); + if Expr_Type = Null_Iir then + -- Possible only if the type cannot be determined without the + -- context (aggregate or string literal). + Error_Msg_Sem + ("cannot determine the type of choice expression", Expr); + if Get_Kind (Expr1) = Iir_Kind_Aggregate then + Error_Msg_Sem + ("(use a qualified expression of the form T'(xxx).)", Expr); + end if; + return Null_Iir; + end if; if not Is_Overload_List (Expr_Type) then return Expr1; end if; |