summaryrefslogtreecommitdiff
path: root/src/vhdl/sem_names.adb
diff options
context:
space:
mode:
authorTristan Gingold2015-05-16 16:18:48 +0200
committerTristan Gingold2015-05-16 16:18:48 +0200
commit9f82c87370ec57fce0fb9f7e95dd7edec1b66e01 (patch)
treee405d009588b69978993ad4078412d9e0083d473 /src/vhdl/sem_names.adb
parent915a588a02957fcadfeff7db15beab2b2948b37a (diff)
downloadghdl-9f82c87370ec57fce0fb9f7e95dd7edec1b66e01.tar.gz
ghdl-9f82c87370ec57fce0fb9f7e95dd7edec1b66e01.tar.bz2
ghdl-9f82c87370ec57fce0fb9f7e95dd7edec1b66e01.zip
Give priority to function calls without implicit conversion.
Fix ticket 64.
Diffstat (limited to 'src/vhdl/sem_names.adb')
-rw-r--r--src/vhdl/sem_names.adb93
1 files changed, 60 insertions, 33 deletions
diff --git a/src/vhdl/sem_names.adb b/src/vhdl/sem_names.adb
index a49a7c7..5d029aa 100644
--- a/src/vhdl/sem_names.adb
+++ b/src/vhdl/sem_names.adb
@@ -211,7 +211,8 @@ package body Sem_Names is
end if;
end Add_Result_List;
- -- Free interpretations of LIST except KEEP.
+ -- Free interpretations of LIST except KEEP (which can be Null_Iir to free
+ -- the whole list).
procedure Sem_Name_Free_Result (List : Iir; Keep : Iir)
is
procedure Sem_Name_Free (El : Iir) is
@@ -2209,10 +2210,12 @@ package body Sem_Names is
-- Sem parenthesis name when the prefix is a function declaration.
-- Can be either a function call (and the expression is the actual) or
-- a slice/index of the result of a call without actual.
- procedure Sem_Parenthesis_Function (Sub_Name : Iir) is
+ procedure Sem_Parenthesis_Function (Sub_Name : Iir)
+ is
Used : Boolean;
R : Iir;
Match : Compatibility_Level;
+ Call : Iir;
begin
Used := False;
if Get_Kind (Sub_Name) = Iir_Kind_Function_Declaration then
@@ -2220,9 +2223,10 @@ package body Sem_Names is
(Get_Interface_Declaration_Chain (Sub_Name),
Assoc_Chain, False, Missing_Parameter, Name, Match);
if Match /= Not_Compatible then
- Add_Result
- (Res,
- Sem_As_Function_Call (Prefix_Name, Sub_Name, Assoc_Chain));
+ Call := Sem_As_Function_Call
+ (Prefix_Name, Sub_Name, Assoc_Chain);
+ Set_Has_Implicit_Conversion (Call, Match = Via_Conversion);
+ Add_Result (Res, Call);
Used := True;
end if;
end if;
@@ -3532,38 +3536,61 @@ package body Sem_Names is
if A_Type /= Null_Iir then
-- Find the name returning A_TYPE.
- Res := Null_Iir;
- for I in Natural loop
- El := Get_Nth_Element (Expr_List, I);
- exit when El = Null_Iir;
- if Are_Basetypes_Compatible (Get_Base_Type (Get_Type (El)),
- A_Type)
- /= Not_Compatible
- then
- Add_Result (Res, El);
+ declare
+ Only_Calls : Boolean;
+ Full_Compat_Call : Iir;
+ Nbr_Full_Compat : Natural;
+ begin
+ Res := Null_Iir;
+ Only_Calls := True;
+ Full_Compat_Call := Null_Iir;
+ Nbr_Full_Compat := 0;
+ for I in Natural loop
+ El := Get_Nth_Element (Expr_List, I);
+ exit when El = Null_Iir;
+ if Are_Basetypes_Compatible (Get_Base_Type (Get_Type (El)),
+ A_Type)
+ /= Not_Compatible
+ then
+ if Get_Kind (El) = Iir_Kind_Function_Call then
+ if not Get_Has_Implicit_Conversion (El) then
+ Full_Compat_Call := El;
+ Nbr_Full_Compat := Nbr_Full_Compat + 1;
+ end if;
+ else
+ Only_Calls := False;
+ end if;
+ Add_Result (Res, El);
+ end if;
+ end loop;
+ if Res = Null_Iir then
+ Error_Not_Match (Name, A_Type, Name);
+ return Null_Iir;
+ elsif Is_Overload_List (Res) then
+ if Only_Calls and then Nbr_Full_Compat = 1 then
+ Free_Iir (Res);
+ Res := Full_Compat_Call;
+ else
+ Error_Overload (Name);
+ Disp_Overload_List (Get_Overload_List (Res), Name);
+ Free_Iir (Res);
+ return Null_Iir;
+ end if;
end if;
- end loop;
- if Res = Null_Iir then
- Error_Not_Match (Name, A_Type, Name);
- return Null_Iir;
- elsif Is_Overload_List (Res) then
- Error_Overload (Name);
- Disp_Overload_List (Get_Overload_List (Res), Name);
- return Null_Iir;
- else
- -- Free results
- Sem_Name_Free_Result (Expr, Res);
+ end;
- Ret_Type := Get_Type (Name);
- if Ret_Type /= Null_Iir then
- pragma Assert (Is_Overload_List (Ret_Type));
- Free_Overload_List (Ret_Type);
- end if;
+ -- Free results
+ Sem_Name_Free_Result (Expr, Res);
- Set_Named_Entity (Name, Res);
- Res := Finish_Sem_Name (Name);
- -- Fall through.
+ Ret_Type := Get_Type (Name);
+ if Ret_Type /= Null_Iir then
+ pragma Assert (Is_Overload_List (Ret_Type));
+ Free_Overload_List (Ret_Type);
end if;
+
+ Set_Named_Entity (Name, Res);
+ Res := Finish_Sem_Name (Name);
+ -- Fall through.
else
-- Create a list of type.
Ret_Type := Create_List_Of_Types (Expr_List);