From 4718c88f8d2f97a0bdda356edd8ee01c5c0d1fe0 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 9 Sep 2010 08:22:13 +0000 Subject: [PATCH] compiler: compare enumerator operator "current" return type with the loop variable while searching for enumerator git-svn-id: trunk@15953 - --- compiler/nflw.pas | 2 +- compiler/symsym.pas | 95 +++++++++++++++++++++++++------------------ compiler/symtable.pas | 6 +-- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/compiler/nflw.pas b/compiler/nflw.pas index 11170a8ef1..0d98dac871 100644 --- a/compiler/nflw.pas +++ b/compiler/nflw.pas @@ -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; diff --git a/compiler/symsym.pas b/compiler/symsym.pas index 4c6f50fe03..36d8950654 100644 --- a/compiler/symsym.pas +++ b/compiler/symsym.pas @@ -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 (paraidxtparavarsym(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 (paraidxbesteq 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; diff --git a/compiler/symtable.pas b/compiler/symtable.pas index f5cf48ed76..4f908ce183 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -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;