|
@@ -26,7 +26,7 @@ unit htypechk;
|
|
interface
|
|
interface
|
|
|
|
|
|
uses
|
|
uses
|
|
- tokens,cpuinfo,
|
|
|
|
|
|
+ cclasses,tokens,cpuinfo,
|
|
node,globtype,
|
|
node,globtype,
|
|
symconst,symtype,symdef,symsym,symbase;
|
|
symconst,symtype,symdef,symsym,symbase;
|
|
|
|
|
|
@@ -58,16 +58,20 @@ interface
|
|
|
|
|
|
tcallcandidates = class
|
|
tcallcandidates = class
|
|
private
|
|
private
|
|
- FProcSym : tprocsym;
|
|
|
|
- FProcs : pcandidate;
|
|
|
|
- FProcVisibleCnt,
|
|
|
|
|
|
+ FProcsym : tprocsym;
|
|
|
|
+ FProcsymtable : tsymtable;
|
|
|
|
+ FOperator : ttoken;
|
|
|
|
+ FCandidateProcs : pcandidate;
|
|
FProcCnt : integer;
|
|
FProcCnt : integer;
|
|
FParaNode : tnode;
|
|
FParaNode : tnode;
|
|
FParaLength : smallint;
|
|
FParaLength : smallint;
|
|
FAllowVariant : boolean;
|
|
FAllowVariant : boolean;
|
|
- function proc_add(ps:tprocsym;pd:tprocdef):pcandidate;
|
|
|
|
|
|
+ procedure collect_overloads_in_class(ProcdefOverloadList:TFPObjectList);
|
|
|
|
+ procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList);
|
|
|
|
+ procedure create_candidate_list(ignorevisibility:boolean);
|
|
|
|
+ function proc_add(ps:tprocsym;pd:tprocdef):pcandidate;
|
|
public
|
|
public
|
|
- constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;isprop,ignorevis : boolean);
|
|
|
|
|
|
+ constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility:boolean);
|
|
constructor create_operator(op:ttoken;ppn:tnode);
|
|
constructor create_operator(op:ttoken;ppn:tnode);
|
|
destructor destroy;override;
|
|
destructor destroy;override;
|
|
procedure list(all:boolean);
|
|
procedure list(all:boolean);
|
|
@@ -78,7 +82,6 @@ interface
|
|
function choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
|
|
function choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
|
|
procedure find_wrong_para;
|
|
procedure find_wrong_para;
|
|
property Count:integer read FProcCnt;
|
|
property Count:integer read FProcCnt;
|
|
- property VisibleCount:integer read FProcVisibleCnt;
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
type
|
|
type
|
|
@@ -165,7 +168,7 @@ implementation
|
|
uses
|
|
uses
|
|
sysutils,
|
|
sysutils,
|
|
systems,constexp,globals,
|
|
systems,constexp,globals,
|
|
- cutils,cclasses,verbose,
|
|
|
|
|
|
+ cutils,verbose,
|
|
symtable,
|
|
symtable,
|
|
defutil,defcmp,
|
|
defutil,defcmp,
|
|
nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,ncon,
|
|
nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,ncon,
|
|
@@ -1582,235 +1585,130 @@ implementation
|
|
TCallCandidates
|
|
TCallCandidates
|
|
****************************************************************************}
|
|
****************************************************************************}
|
|
|
|
|
|
- constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;isprop,ignorevis : boolean);
|
|
|
|
- var
|
|
|
|
- j : integer;
|
|
|
|
- pd : tprocdef;
|
|
|
|
- hp : pcandidate;
|
|
|
|
- found,
|
|
|
|
- has_overload_directive : boolean;
|
|
|
|
- topclassh : tobjectdef;
|
|
|
|
- srsymtable : TSymtable;
|
|
|
|
- srprocsym : tprocsym;
|
|
|
|
- pt : tcallparanode;
|
|
|
|
- checkstack : psymtablestackitem;
|
|
|
|
- hashedid : THashedIDString;
|
|
|
|
|
|
+ constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility:boolean);
|
|
begin
|
|
begin
|
|
if not assigned(sym) then
|
|
if not assigned(sym) then
|
|
internalerror(200411015);
|
|
internalerror(200411015);
|
|
-
|
|
|
|
- FProcSym:=sym;
|
|
|
|
- FProcs:=nil;
|
|
|
|
- FProccnt:=0;
|
|
|
|
- FProcvisiblecnt:=0;
|
|
|
|
|
|
+ FOperator:=NOTOKEN;
|
|
|
|
+ FProcsym:=sym;
|
|
|
|
+ FProcsymtable:=st;
|
|
FParanode:=ppn;
|
|
FParanode:=ppn;
|
|
- FAllowVariant:=true;
|
|
|
|
-
|
|
|
|
- { determine length of parameter list }
|
|
|
|
- pt:=tcallparanode(ppn);
|
|
|
|
- FParalength:=0;
|
|
|
|
- while assigned(pt) do
|
|
|
|
- begin
|
|
|
|
- inc(FParalength);
|
|
|
|
- pt:=tcallparanode(pt.right);
|
|
|
|
- end;
|
|
|
|
|
|
+ create_candidate_list(ignorevisibility);
|
|
|
|
+ end;
|
|
|
|
|
|
- { when the definition has overload directive set, we search for
|
|
|
|
- overloaded definitions in the class, this only needs to be done once
|
|
|
|
- for class entries as the tree keeps always the same }
|
|
|
|
- if (not sym.overloadchecked) and
|
|
|
|
- (sym.owner.symtabletype=ObjectSymtable) and
|
|
|
|
- (po_overload in tprocdef(sym.ProcdefList[0]).procoptions) then
|
|
|
|
- search_class_overloads(sym);
|
|
|
|
|
|
|
|
- { when the class passed is defined in this unit we
|
|
|
|
- need to use the scope of that class. This is a trick
|
|
|
|
- that can be used to access protected members in other
|
|
|
|
- units. At least kylix supports it this way (PFV) }
|
|
|
|
- if assigned(st) and
|
|
|
|
- (
|
|
|
|
- (st.symtabletype=ObjectSymtable) or
|
|
|
|
- ((st.symtabletype=withsymtable) and
|
|
|
|
- (st.defowner.typ=objectdef))
|
|
|
|
- ) and
|
|
|
|
- (st.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
|
|
- st.defowner.owner.iscurrentunit then
|
|
|
|
- topclassh:=tobjectdef(st.defowner)
|
|
|
|
- else
|
|
|
|
- topclassh:=current_objectdef;
|
|
|
|
-
|
|
|
|
- { link all procedures which have the same # of parameters }
|
|
|
|
- for j:=0 to sym.ProcdefList.Count-1 do
|
|
|
|
- begin
|
|
|
|
- pd:=tprocdef(sym.ProcdefList[j]);
|
|
|
|
- { Is the procdef visible? This needs to be checked on
|
|
|
|
- procdef level since a symbol can contain both private and
|
|
|
|
- public declarations. But the check should not be done
|
|
|
|
- when the callnode is generated by a property
|
|
|
|
|
|
+ constructor tcallcandidates.create_operator(op:ttoken;ppn:tnode);
|
|
|
|
+ begin
|
|
|
|
+ FOperator:=op;
|
|
|
|
+ FProcsym:=nil;
|
|
|
|
+ FProcsymtable:=nil;
|
|
|
|
+ FParanode:=ppn;
|
|
|
|
+ create_candidate_list(false);
|
|
|
|
+ end;
|
|
|
|
|
|
- inherited overrides invisible anonymous inherited (FK) }
|
|
|
|
|
|
|
|
- if isprop or ignorevis or
|
|
|
|
- (pd.owner.symtabletype<>ObjectSymtable) or
|
|
|
|
- pd.is_visible_for_object(topclassh,nil) then
|
|
|
|
- begin
|
|
|
|
- { we have at least one procedure that is visible }
|
|
|
|
- inc(FProcvisiblecnt);
|
|
|
|
- { only when the # of parameter are supported by the
|
|
|
|
- procedure }
|
|
|
|
- if (FParalength>=pd.minparacount) and
|
|
|
|
- ((po_varargs in pd.procoptions) or { varargs }
|
|
|
|
- (FParalength<=pd.maxparacount)) then
|
|
|
|
- proc_add(sym,pd);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
|
|
+ destructor tcallcandidates.destroy;
|
|
|
|
+ var
|
|
|
|
+ hpnext,
|
|
|
|
+ hp : pcandidate;
|
|
|
|
+ begin
|
|
|
|
+ hp:=FCandidateProcs;
|
|
|
|
+ while assigned(hp) do
|
|
|
|
+ begin
|
|
|
|
+ hpnext:=hp^.next;
|
|
|
|
+ dispose(hp);
|
|
|
|
+ hp:=hpnext;
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
|
|
- { remember if the procedure is declared with the overload directive,
|
|
|
|
- it's information is still needed also after all procs are removed }
|
|
|
|
- has_overload_directive:=(po_overload in tprocdef(sym.ProcdefList[0]).procoptions);
|
|
|
|
|
|
|
|
- { when the definition has overload directive set, we search for
|
|
|
|
- overloaded definitions in the symtablestack. The found
|
|
|
|
- entries are only added to the procs list and not the procsym, because
|
|
|
|
- the list can change in every situation }
|
|
|
|
- if has_overload_directive and
|
|
|
|
- (sym.owner.symtabletype<>ObjectSymtable) then
|
|
|
|
- begin
|
|
|
|
- srsymtable:=sym.owner;
|
|
|
|
- checkstack:=symtablestack.stack;
|
|
|
|
- while assigned(checkstack) and
|
|
|
|
- (checkstack^.symtable<>srsymtable) do
|
|
|
|
- checkstack:=checkstack^.next;
|
|
|
|
- { we've already processed the current symtable, start with
|
|
|
|
- the next symtable in the stack }
|
|
|
|
- if assigned(checkstack) then
|
|
|
|
- checkstack:=checkstack^.next;
|
|
|
|
- hashedid.id:=sym.name;
|
|
|
|
- while assigned(checkstack) do
|
|
|
|
|
|
+ procedure tcallcandidates.collect_overloads_in_class(ProcdefOverloadList:TFPObjectList);
|
|
|
|
+ var
|
|
|
|
+ j : integer;
|
|
|
|
+ pd : tprocdef;
|
|
|
|
+ srsym : tsym;
|
|
|
|
+ objdef : tobjectdef;
|
|
|
|
+ hashedid : THashedIDString;
|
|
|
|
+ hasoverload : boolean;
|
|
|
|
+ begin
|
|
|
|
+ objdef:=tobjectdef(fprocsym.owner.defowner);
|
|
|
|
+ hashedid.id:=fprocsym.name;
|
|
|
|
+ hasoverload:=false;
|
|
|
|
+ while assigned(objdef) do
|
|
|
|
+ begin
|
|
|
|
+ srsym:=tprocsym(objdef.symtable.FindWithHash(hashedid));
|
|
|
|
+ if assigned(srsym) then
|
|
begin
|
|
begin
|
|
- srsymtable:=checkstack^.symtable;
|
|
|
|
- if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
|
|
|
|
- begin
|
|
|
|
- srprocsym:=tprocsym(srsymtable.FindWithHash(hashedid));
|
|
|
|
- if assigned(srprocsym) and
|
|
|
|
- (srprocsym.typ=procsym) then
|
|
|
|
- begin
|
|
|
|
- { if this visible procedure doesn't have overload we can stop
|
|
|
|
- searching }
|
|
|
|
- if not(po_overload in tprocdef(srprocsym.ProcdefList[0]).procoptions) and
|
|
|
|
- tprocdef(srprocsym.ProcdefList[0]).is_visible_for_object(topclassh,nil) then
|
|
|
|
- break;
|
|
|
|
- { process all overloaded definitions }
|
|
|
|
- for j:=0 to srprocsym.ProcdefList.Count-1 do
|
|
|
|
- begin
|
|
|
|
- pd:=tprocdef(srprocsym.ProcdefList[j]);
|
|
|
|
- { only visible procedures need to be added }
|
|
|
|
- if pd.is_visible_for_object(topclassh,nil) then
|
|
|
|
- begin
|
|
|
|
- { only when the # of parameter are supported by the
|
|
|
|
- procedure }
|
|
|
|
- if (FParalength>=pd.minparacount) and
|
|
|
|
- ((po_varargs in pd.procoptions) or { varargs }
|
|
|
|
- (FParalength<=pd.maxparacount)) then
|
|
|
|
- begin
|
|
|
|
- found:=false;
|
|
|
|
- hp:=FProcs;
|
|
|
|
- while assigned(hp) do
|
|
|
|
- begin
|
|
|
|
- { Only compare visible parameters for the user }
|
|
|
|
- if compare_paras(hp^.data.paras,pd.paras,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
|
|
|
|
- begin
|
|
|
|
- found:=true;
|
|
|
|
- break;
|
|
|
|
- end;
|
|
|
|
- hp:=hp^.next;
|
|
|
|
- end;
|
|
|
|
- if not found then
|
|
|
|
- proc_add(srprocsym,pd);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- checkstack:=checkstack^.next;
|
|
|
|
|
|
+ if (srsym.typ<>procsym) then
|
|
|
|
+ internalerror(200111022);
|
|
|
|
+ { add all definitions }
|
|
|
|
+ hasoverload:=false;
|
|
|
|
+ for j:=0 to tprocsym(srsym).ProcdefList.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ pd:=tprocdef(tprocsym(srsym).ProcdefList[j]);
|
|
|
|
+ if po_overload in pd.procoptions then
|
|
|
|
+ hasoverload:=true;
|
|
|
|
+ ProcdefOverloadList.Add(tprocsym(srsym).ProcdefList[j]);
|
|
|
|
+ end;
|
|
|
|
+ { when there is no explicit overload we stop searching }
|
|
|
|
+ if not hasoverload then
|
|
|
|
+ break;
|
|
end;
|
|
end;
|
|
- end;
|
|
|
|
|
|
+ { next parent }
|
|
|
|
+ objdef:=objdef.childof;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- constructor tcallcandidates.create_operator(op:ttoken;ppn:tnode);
|
|
|
|
|
|
+ procedure tcallcandidates.collect_overloads_in_units(ProcdefOverloadList:TFPObjectList);
|
|
var
|
|
var
|
|
j : integer;
|
|
j : integer;
|
|
pd : tprocdef;
|
|
pd : tprocdef;
|
|
- hp : pcandidate;
|
|
|
|
- found : boolean;
|
|
|
|
srsymtable : TSymtable;
|
|
srsymtable : TSymtable;
|
|
- srprocsym : tprocsym;
|
|
|
|
- pt : tcallparanode;
|
|
|
|
|
|
+ srsym : tsym;
|
|
checkstack : psymtablestackitem;
|
|
checkstack : psymtablestackitem;
|
|
hashedid : THashedIDString;
|
|
hashedid : THashedIDString;
|
|
|
|
+ hasoverload : boolean;
|
|
begin
|
|
begin
|
|
- FProcSym:=nil;
|
|
|
|
- FProcs:=nil;
|
|
|
|
- FProccnt:=0;
|
|
|
|
- FProcvisiblecnt:=0;
|
|
|
|
- FParanode:=ppn;
|
|
|
|
- FAllowVariant:=false;
|
|
|
|
-
|
|
|
|
- { determine length of parameter list }
|
|
|
|
- pt:=tcallparanode(ppn);
|
|
|
|
- FParalength:=0;
|
|
|
|
- while assigned(pt) do
|
|
|
|
- begin
|
|
|
|
- if pt.resultdef.typ=variantdef then
|
|
|
|
- FAllowVariant:=true;
|
|
|
|
- inc(FParalength);
|
|
|
|
- pt:=tcallparanode(pt.right);
|
|
|
|
- end;
|
|
|
|
-
|
|
|
|
{ we search all overloaded operator definitions in the symtablestack. The found
|
|
{ we search all overloaded operator definitions in the symtablestack. The found
|
|
entries are only added to the procs list and not the procsym, because
|
|
entries are only added to the procs list and not the procsym, because
|
|
the list can change in every situation }
|
|
the list can change in every situation }
|
|
- hashedid.id:=overloaded_names[op];
|
|
|
|
|
|
+ if FOperator<>NOTOKEN then
|
|
|
|
+ hashedid.id:=overloaded_names[FOperator]
|
|
|
|
+ else
|
|
|
|
+ hashedid.id:=FProcsym.name;
|
|
|
|
+
|
|
checkstack:=symtablestack.stack;
|
|
checkstack:=symtablestack.stack;
|
|
|
|
+ if assigned(FProcsymtable) then
|
|
|
|
+ begin
|
|
|
|
+ while assigned(checkstack) and
|
|
|
|
+ (checkstack^.symtable<>FProcsymtable) do
|
|
|
|
+ checkstack:=checkstack^.next;
|
|
|
|
+ end;
|
|
while assigned(checkstack) do
|
|
while assigned(checkstack) do
|
|
begin
|
|
begin
|
|
srsymtable:=checkstack^.symtable;
|
|
srsymtable:=checkstack^.symtable;
|
|
if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
|
|
if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
|
|
begin
|
|
begin
|
|
- srprocsym:=tprocsym(srsymtable.FindWithHash(hashedid));
|
|
|
|
- if assigned(srprocsym) and
|
|
|
|
- (srprocsym.typ=procsym) then
|
|
|
|
|
|
+ srsym:=tprocsym(srsymtable.FindWithHash(hashedid));
|
|
|
|
+ if assigned(srsym) and
|
|
|
|
+ (srsym.typ=procsym) then
|
|
begin
|
|
begin
|
|
{ Store first procsym found }
|
|
{ Store first procsym found }
|
|
if not assigned(FProcsym) then
|
|
if not assigned(FProcsym) then
|
|
- FProcsym:=srprocsym;
|
|
|
|
-
|
|
|
|
- { process all overloaded definitions }
|
|
|
|
- for j:=0 to srprocsym.ProcdefList.Count-1 do
|
|
|
|
|
|
+ FProcsym:=tprocsym(srsym);
|
|
|
|
+ { add all definitions }
|
|
|
|
+ hasoverload:=false;
|
|
|
|
+ for j:=0 to tprocsym(srsym).ProcdefList.Count-1 do
|
|
begin
|
|
begin
|
|
- pd:=tprocdef(srprocsym.ProcdefList[j]);
|
|
|
|
- { only when the # of parameter are supported by the
|
|
|
|
- procedure }
|
|
|
|
- if (FParalength>=pd.minparacount) and
|
|
|
|
- (FParalength<=pd.maxparacount) then
|
|
|
|
- begin
|
|
|
|
- found:=false;
|
|
|
|
- hp:=FProcs;
|
|
|
|
- while assigned(hp) do
|
|
|
|
- begin
|
|
|
|
- { Only compare visible parameters for the user }
|
|
|
|
- if compare_paras(hp^.data.paras,pd.paras,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
|
|
|
|
- begin
|
|
|
|
- found:=true;
|
|
|
|
- break;
|
|
|
|
- end;
|
|
|
|
- hp:=hp^.next;
|
|
|
|
- end;
|
|
|
|
- if not found then
|
|
|
|
- proc_add(srprocsym,pd);
|
|
|
|
- end;
|
|
|
|
|
|
+ pd:=tprocdef(tprocsym(srsym).ProcdefList[j]);
|
|
|
|
+ if po_overload in pd.procoptions then
|
|
|
|
+ hasoverload:=true;
|
|
|
|
+ ProcdefOverloadList.Add(tprocsym(srsym).ProcdefList[j]);
|
|
end;
|
|
end;
|
|
|
|
+ { when there is no explicit overload we stop searching }
|
|
|
|
+ if not hasoverload then
|
|
|
|
+ break;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
checkstack:=checkstack^.next;
|
|
checkstack:=checkstack^.next;
|
|
@@ -1818,18 +1716,92 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- destructor tcallcandidates.destroy;
|
|
|
|
|
|
+ procedure tcallcandidates.create_candidate_list(ignorevisibility:boolean);
|
|
var
|
|
var
|
|
- hpnext,
|
|
|
|
- hp : pcandidate;
|
|
|
|
|
|
+ j : integer;
|
|
|
|
+ pd : tprocdef;
|
|
|
|
+ hp : pcandidate;
|
|
|
|
+ pt : tcallparanode;
|
|
|
|
+ found : boolean;
|
|
|
|
+ contextobjdef : tobjectdef;
|
|
|
|
+ ProcdefOverloadList : TFPObjectList;
|
|
begin
|
|
begin
|
|
- hp:=FProcs;
|
|
|
|
- while assigned(hp) do
|
|
|
|
- begin
|
|
|
|
- hpnext:=hp^.next;
|
|
|
|
- dispose(hp);
|
|
|
|
- hp:=hpnext;
|
|
|
|
- end;
|
|
|
|
|
|
+ FCandidateProcs:=nil;
|
|
|
|
+
|
|
|
|
+ { Find all available overloads for this procsym }
|
|
|
|
+ ProcdefOverloadList:=TFPObjectList.Create(false);
|
|
|
|
+ if (FOperator=NOTOKEN) and
|
|
|
|
+ (FProcsym.owner.symtabletype=objectsymtable) then
|
|
|
|
+ collect_overloads_in_class(ProcdefOverloadList)
|
|
|
|
+ else
|
|
|
|
+ collect_overloads_in_units(ProcdefOverloadList);
|
|
|
|
+
|
|
|
|
+ { determine length of parameter list.
|
|
|
|
+ for operators also enable the variant-operators if
|
|
|
|
+ a variant parameter is passed }
|
|
|
|
+ FParalength:=0;
|
|
|
|
+ FAllowVariant:=(FOperator=NOTOKEN);
|
|
|
|
+ pt:=tcallparanode(FParaNode);
|
|
|
|
+ while assigned(pt) do
|
|
|
|
+ begin
|
|
|
|
+ if (pt.resultdef.typ=variantdef) then
|
|
|
|
+ FAllowVariant:=true;
|
|
|
|
+ inc(FParalength);
|
|
|
|
+ pt:=tcallparanode(pt.right);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ { when the class passed is defined in this unit we
|
|
|
|
+ need to use the scope of that class. This is a trick
|
|
|
|
+ that can be used to access protected members in other
|
|
|
|
+ units. At least kylix supports it this way (PFV) }
|
|
|
|
+ if assigned(FProcSymtable) and
|
|
|
|
+ (
|
|
|
|
+ (FProcSymtable.symtabletype=ObjectSymtable) or
|
|
|
|
+ ((FProcSymtable.symtabletype=withsymtable) and
|
|
|
|
+ (FProcSymtable.defowner.typ=objectdef))
|
|
|
|
+ ) and
|
|
|
|
+ (FProcSymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
|
|
+ FProcSymtable.defowner.owner.iscurrentunit then
|
|
|
|
+ contextobjdef:=tobjectdef(FProcSymtable.defowner)
|
|
|
|
+ else
|
|
|
|
+ contextobjdef:=current_objectdef;
|
|
|
|
+
|
|
|
|
+ { Process all found overloads }
|
|
|
|
+ for j:=0 to ProcdefOverloadList.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ pd:=tprocdef(ProcdefOverloadList[j]);
|
|
|
|
+
|
|
|
|
+ { only when the # of parameter are supported by the procedure and
|
|
|
|
+ it is visible }
|
|
|
|
+ if (FParalength>=pd.minparacount) and
|
|
|
|
+ (
|
|
|
|
+ (FParalength<=pd.maxparacount) or
|
|
|
|
+ (po_varargs in pd.procoptions)
|
|
|
|
+ ) and
|
|
|
|
+ (
|
|
|
|
+ ignorevisibility or
|
|
|
|
+ (pd.owner.symtabletype<>objectsymtable) or
|
|
|
|
+ pd.is_visible_for_object(contextobjdef,nil)
|
|
|
|
+ ) then
|
|
|
|
+ begin
|
|
|
|
+ { don't add duplicates, only compare visible parameters for the user }
|
|
|
|
+ found:=false;
|
|
|
|
+ hp:=FCandidateProcs;
|
|
|
|
+ while assigned(hp) do
|
|
|
|
+ begin
|
|
|
|
+ if compare_paras(hp^.data.paras,pd.paras,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
|
|
|
|
+ begin
|
|
|
|
+ found:=true;
|
|
|
|
+ break;
|
|
|
|
+ end;
|
|
|
|
+ hp:=hp^.next;
|
|
|
|
+ end;
|
|
|
|
+ if not found then
|
|
|
|
+ proc_add(fprocsym,pd);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ ProcdefOverloadList.Free;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1841,8 +1813,8 @@ implementation
|
|
new(result);
|
|
new(result);
|
|
fillchar(result^,sizeof(tcandidate),0);
|
|
fillchar(result^,sizeof(tcandidate),0);
|
|
result^.data:=pd;
|
|
result^.data:=pd;
|
|
- result^.next:=FProcs;
|
|
|
|
- FProcs:=result;
|
|
|
|
|
|
+ result^.next:=FCandidateProcs;
|
|
|
|
+ FCandidateProcs:=result;
|
|
inc(FProccnt);
|
|
inc(FProccnt);
|
|
{ Find last parameter, skip all default parameters
|
|
{ Find last parameter, skip all default parameters
|
|
that are not passed. Ignore this skipping for varargs }
|
|
that are not passed. Ignore this skipping for varargs }
|
|
@@ -1871,7 +1843,7 @@ implementation
|
|
var
|
|
var
|
|
hp : pcandidate;
|
|
hp : pcandidate;
|
|
begin
|
|
begin
|
|
- hp:=FProcs;
|
|
|
|
|
|
+ hp:=FCandidateProcs;
|
|
while assigned(hp) do
|
|
while assigned(hp) do
|
|
begin
|
|
begin
|
|
if all or
|
|
if all or
|
|
@@ -1904,8 +1876,8 @@ implementation
|
|
begin
|
|
begin
|
|
if not CheckVerbosity(lvl) then
|
|
if not CheckVerbosity(lvl) then
|
|
exit;
|
|
exit;
|
|
- Comment(lvl+V_LineInfo,'Overloaded callnode: '+FProcSym.name+'('+ParaTreeStr(tcallparanode(FParaNode))+')');
|
|
|
|
- hp:=FProcs;
|
|
|
|
|
|
+ Comment(lvl+V_LineInfo,'Overloaded callnode: '+FProcsym.name+'('+ParaTreeStr(tcallparanode(FParaNode))+')');
|
|
|
|
+ hp:=FCandidateProcs;
|
|
while assigned(hp) do
|
|
while assigned(hp) do
|
|
begin
|
|
begin
|
|
Comment(lvl,' '+hp^.data.fullprocname(false));
|
|
Comment(lvl,' '+hp^.data.fullprocname(false));
|
|
@@ -1968,7 +1940,7 @@ implementation
|
|
if FAllowVariant then
|
|
if FAllowVariant then
|
|
include(cdoptions,cdo_allow_variant);
|
|
include(cdoptions,cdo_allow_variant);
|
|
{ process all procs }
|
|
{ process all procs }
|
|
- hp:=FProcs;
|
|
|
|
|
|
+ hp:=FCandidateProcs;
|
|
while assigned(hp) do
|
|
while assigned(hp) do
|
|
begin
|
|
begin
|
|
{ We compare parameters in reverse order (right to left),
|
|
{ We compare parameters in reverse order (right to left),
|
|
@@ -2517,15 +2489,15 @@ implementation
|
|
}
|
|
}
|
|
{ Setup the first procdef as best, only count it as a result
|
|
{ Setup the first procdef as best, only count it as a result
|
|
when it is valid }
|
|
when it is valid }
|
|
- bestpd:=FProcs^.data;
|
|
|
|
- if FProcs^.invalid then
|
|
|
|
|
|
+ bestpd:=FCandidateProcs^.data;
|
|
|
|
+ if FCandidateProcs^.invalid then
|
|
cntpd:=0
|
|
cntpd:=0
|
|
else
|
|
else
|
|
cntpd:=1;
|
|
cntpd:=1;
|
|
- if assigned(FProcs^.next) then
|
|
|
|
|
|
+ if assigned(FCandidateProcs^.next) then
|
|
begin
|
|
begin
|
|
- besthpstart:=FProcs;
|
|
|
|
- hp:=FProcs^.next;
|
|
|
|
|
|
+ besthpstart:=FCandidateProcs;
|
|
|
|
+ hp:=FCandidateProcs^.next;
|
|
while assigned(hp) do
|
|
while assigned(hp) do
|
|
begin
|
|
begin
|
|
if not singlevariant then
|
|
if not singlevariant then
|
|
@@ -2572,7 +2544,7 @@ implementation
|
|
wrongpara : tparavarsym;
|
|
wrongpara : tparavarsym;
|
|
begin
|
|
begin
|
|
{ Only process the first overloaded procdef }
|
|
{ Only process the first overloaded procdef }
|
|
- hp:=FProcs;
|
|
|
|
|
|
+ hp:=FCandidateProcs;
|
|
{ Find callparanode corresponding to the argument }
|
|
{ Find callparanode corresponding to the argument }
|
|
pt:=tcallparanode(FParanode);
|
|
pt:=tcallparanode(FParanode);
|
|
currparanr:=FParalength;
|
|
currparanr:=FParalength;
|