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 else
begin begin
// search for operator first // 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 there is no operator then search for class/object enumerator method
if (pd=nil) and (expr.resultdef.typ=objectdef) then if (pd=nil) and (expr.resultdef.typ=objectdef) then
pd:=tobjectdef(expr.resultdef).search_enumerator_get; pd:=tobjectdef(expr.resultdef).search_enumerator_get;

View File

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

View File

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