compiler: compare enumerator operator "current" return type with the loop variable while searching for enumerator

git-svn-id: trunk@15953 -
This commit is contained in:
paul 2010-09-09 08:22:13 +00:00
parent 22b4860dd7
commit 4718c88f8d
3 changed files with 60 additions and 43 deletions

View File

@ -858,7 +858,7 @@ implementation
else
begin
// search for operator first
pd:=search_enumerator_operator(expr.resultdef);
pd:=search_enumerator_operator(expr.resultdef, hloopvar.resultdef);
// if there is no operator then search for class/object enumerator method
if (pd=nil) and (expr.resultdef.typ=objectdef) then
pd:=tobjectdef(expr.resultdef).search_enumerator_get;

View File

@ -105,7 +105,7 @@ interface
function find_procdef_byoptions(ops:tprocoptions): Tprocdef;
function find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
function find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
function find_procdef_enumerator_operator(typedef:tdef;var besteq:tequaltype):Tprocdef;
function find_procdef_enumerator_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
property ProcdefList:TFPObjectList read FProcdefList;
end;
@ -729,8 +729,7 @@ implementation
eq : tequaltype;
begin
{ This function will return the pprocdef of pprocsym that
is the best match for procvardef. When there are multiple
matches it returns nil.}
is the best match for fromdef and todef. }
result:=nil;
bestpd:=nil;
besteq:=te_incompatible;
@ -792,19 +791,19 @@ implementation
result:=bestpd;
end;
function Tprocsym.find_procdef_enumerator_operator(typedef:tdef;var besteq:tequaltype):Tprocdef;
function Tprocsym.find_procdef_enumerator_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
var
paraidx, realparamcount,
i, j : longint;
bestpd,
hpd,
pd : tprocdef;
current : tpropertysym;
convtyp : tconverttype;
eq : tequaltype;
begin
{ This function will return the pprocdef of pprocsym that
is the best match for procvardef. When there are multiple
matches it returns nil.}
is the best match for fromdef and todef. }
result:=nil;
bestpd:=nil;
besteq:=te_incompatible;
@ -813,41 +812,59 @@ implementation
pd:=tprocdef(ProcdefList[i]);
if (pd.owner.symtabletype=staticsymtable) and not pd.owner.iscurrentunit then
continue;
paraidx:=0;
{ ignore vs_hidden parameters }
while (paraidx<pd.paras.count) and
assigned(pd.paras[paraidx]) and
(vo_is_hidden_para in tparavarsym(pd.paras[paraidx]).varoptions) do
inc(paraidx);
realparamcount:=0;
for j := 0 to pd.paras.Count-1 do
if assigned(pd.paras[j]) and not (vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
inc(realparamcount);
if (paraidx<pd.paras.count) and
assigned(pd.paras[paraidx]) and
(realparamcount = 1) and
is_class_or_interface_or_object(pd.returndef) then
if not is_class_or_interface_or_object(pd.returndef) then
continue;
current := tpropertysym(tobjectdef(pd.returndef).search_enumerator_current);
if (current = nil) then
continue;
// compare current result def with the todef
if (equal_defs(todef, current.propdef) or
{ shortstrings of different lengths are ok as result }
(is_shortstring(todef) and is_shortstring(current.propdef))) and
{ the result type must be always really equal and not an alias,
if you mess with this code, check tw4093 }
((todef=current.propdef) or
(
not(df_unique in todef.defoptions) and
not(df_unique in current.propdef.defoptions)
)
) then
begin
eq:=compare_defs_ext(typedef,tparavarsym(pd.paras[paraidx]).vardef,nothingn,convtyp,hpd,[]);
{ alias? if yes, only l1 choice,
if you mess with this code, check tw4093 }
if (eq=te_exact) and
(typedef<>tparavarsym(pd.paras[paraidx]).vardef) and
((df_unique in typedef.defoptions) or
(df_unique in tparavarsym(pd.paras[paraidx]).vardef.defoptions)) then
eq:=te_convert_l1;
if eq=te_exact then
paraidx:=0;
{ ignore vs_hidden parameters }
while (paraidx<pd.paras.count) and
assigned(pd.paras[paraidx]) and
(vo_is_hidden_para in tparavarsym(pd.paras[paraidx]).varoptions) do
inc(paraidx);
realparamcount:=0;
for j := 0 to pd.paras.Count-1 do
if assigned(pd.paras[j]) and not (vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
inc(realparamcount);
if (paraidx<pd.paras.count) and
assigned(pd.paras[paraidx]) and
(realparamcount = 1) then
begin
besteq:=eq;
result:=pd;
exit;
end;
if eq>besteq then
begin
bestpd:=pd;
besteq:=eq;
eq:=compare_defs_ext(fromdef,tparavarsym(pd.paras[paraidx]).vardef,nothingn,convtyp,hpd,[]);
{ alias? if yes, only l1 choice,
if you mess with this code, check tw4093 }
if (eq=te_exact) and
(fromdef<>tparavarsym(pd.paras[paraidx]).vardef) and
((df_unique in fromdef.defoptions) or
(df_unique in tparavarsym(pd.paras[paraidx]).vardef.defoptions)) then
eq:=te_convert_l1;
if eq=te_exact then
begin
besteq:=eq;
result:=pd;
exit;
end;
if eq>besteq then
begin
bestpd:=pd;
besteq:=eq;
end;
end;
end;
end;

View File

@ -211,7 +211,7 @@ interface
function search_named_unit_globaltype(const unitname, typename: TIDString; throwerror: boolean): ttypesym;
function search_class_member(pd : tobjectdef;const s : string):tsym;
function search_assignment_operator(from_def,to_def:Tdef):Tprocdef;
function search_enumerator_operator(type_def:Tdef):Tprocdef;
function search_enumerator_operator(from_def,to_def:Tdef):Tprocdef;
function search_class_helper(pd : tobjectdef;const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
function search_objc_method(const s : string; out srsym: tsym; out srsymtable: tsymtable):boolean;
{Looks for macro s (must be given in upper case) in the macrosymbolstack, }
@ -2181,7 +2181,7 @@ implementation
end;
function search_enumerator_operator(type_def:Tdef): Tprocdef;
function search_enumerator_operator(from_def,to_def:Tdef): Tprocdef;
var
sym : Tprocsym;
hashedid : THashedIDString;
@ -2204,7 +2204,7 @@ implementation
internalerror(200910241);
{ if the source type is an alias then this is only the second choice,
if you mess with this code, check tw4093 }
currpd:=sym.find_procdef_enumerator_operator(type_def,curreq);
currpd:=sym.find_procdef_enumerator_operator(from_def,to_def,curreq);
if curreq>besteq then
begin
besteq:=curreq;