ncal.pas:

* extend tcallnode with the ability to pass a tspecializationcontext so that tcallcandidates can do a final specialization
  * the final procdef is registered at the end of tcallnode.pass_typecheck

git-svn-id: trunk@31763 -
This commit is contained in:
svenbarth 2015-09-18 14:48:54 +00:00
parent 75b3ce2d2c
commit 529677cc79
16 changed files with 54 additions and 46 deletions

View File

@ -779,7 +779,7 @@ implementation
{ the nil as symtable signs firstcalln that this is
an overloaded operator }
t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
{ we already know the procdef to use, so it can
skip the overload choosing in callnode.pass_typecheck }
@ -958,7 +958,7 @@ implementation
{ the nil as symtable signs firstcalln that this is
an overloaded operator }
ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
{ we already know the procdef to use, so it can
skip the overload choosing in callnode.pass_typecheck }

View File

@ -241,7 +241,7 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
begin
finalizepi.code:=right;
foreachnodestatic(right,@copy_parasize,finalizepi);
right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[]);
right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
firstpass(right);
{ For implicit frames, no actual code is available at this time,
it is added later in assembler form. So store the nested procinfo

View File

@ -591,7 +591,7 @@ implementation
in theory do that, because the parameter nodes have already
been bound to the current procdef's parasyms }
remove_hidden_paras;
result:=ccallnode.create(left,tprocsym(sym),symtableproc,methodpointer,callnodeflags);
result:=ccallnode.create(left,tprocsym(sym),symtableproc,methodpointer,callnodeflags,nil);
result.flags:=flags;
left:=nil;
methodpointer:=nil;

View File

@ -524,7 +524,7 @@ implementation
with a single #0 }
result:=ccallnode.create(ccallparanode.create(left,nil),tprocsym(ps),
ps.owner,
cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[]);
cloadvmtaddrnode.create(ctypenode.create(java_ansistring)),[],nil);
include(result.flags,nf_isproperty);
result:=ctypeconvnode.create_explicit(result,resultdef);
{ reused }
@ -863,7 +863,7 @@ implementation
{ call the (static class) method to get the raw bits }
result:=ccallnode.create(ccallparanode.create(left,nil),
tprocsym(psym),psym.owner,
cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[]);
cloadvmtaddrnode.create(ctypenode.create(csym.typedef)),[],nil);
{ convert the result to the result type of this type conversion node }
inserttypeconv_explicit(result,resultdef);
{ left is reused }
@ -882,7 +882,7 @@ implementation
internalerror(2011062601);
result:=ccallnode.create(ccallparanode.create(left,nil),
tprocsym(psym),psym.owner,
cloadvmtaddrnode.create(ctypenode.create(todef.classdef)),[]);
cloadvmtaddrnode.create(ctypenode.create(todef.classdef)),[],nil);
{ convert the result to the result type of this type conversion node }
inserttypeconv_explicit(result,resultdef);
{ left is reused }
@ -899,7 +899,7 @@ implementation
if not assigned(psym) or
(psym.typ<>procsym) then
internalerror(2011062602);
result:=ccallnode.create(nil,tprocsym(psym),psym.owner,left,[]);
result:=ccallnode.create(nil,tprocsym(psym),psym.owner,left,[],nil);
{ convert the result to the result type of this type conversion node }
inserttypeconv_explicit(result,resultdef);
{ left is reused }
@ -1506,7 +1506,7 @@ implementation
if not assigned(ps) or
(ps.typ<>procsym) then
internalerror(2011041910);
call:=ccallnode.create(ccallparanode.create(node.left,nil),tprocsym(ps),ps.owner,ctypeconvnode.create_explicit(node.right,jlclass),[]);
call:=ccallnode.create(ccallparanode.create(node.left,nil),tprocsym(ps),ps.owner,ctypeconvnode.create_explicit(node.right,jlclass),[],nil);
node.left:=nil;
node.right:=nil;
firstpass(call);

View File

@ -595,7 +595,7 @@ implementation
internalerror(2011031403);
stringnonnull:=cassignmentnode.create(
ctemprefnode.create(lentemp),
ccallnode.create(nil,tprocsym(psym),psym.owner,stringtemp,[]));
ccallnode.create(nil,tprocsym(psym),psym.owner,stringtemp,[],nil));
{ else-path: length is 0 }
stringnull:=cassignmentnode.create(
ctemprefnode.create(lentemp),
@ -618,7 +618,7 @@ implementation
internalerror(2011052402);
result:=
ccallnode.create(nil,tprocsym(psym),psym.owner,
ctypeconvnode.create_explicit(caddrnode.create_internal(left),java_shortstring),[]);
ctypeconvnode.create_explicit(caddrnode.create_internal(left),java_shortstring),[],nil);
{ reused }
left:=nil;
end

View File

@ -142,7 +142,7 @@ function tjvmassignmentnode.pass_1: tnode;
ccallnode.create(
ccallparanode.create(right,
ccallparanode.create(tvecnode(target).right,nil)),
tprocsym(psym),psym.owner,tvecnode(target).left,[]);
tprocsym(psym),psym.owner,tvecnode(target).left,[],nil);
right:=nil;
tvecnode(target).left:=nil;
tvecnode(target).right:=nil;

View File

@ -332,7 +332,7 @@ implementation
if not assigned(vs) or
(tsym(vs).typ<>procsym) then
internalerror(2011041901);
result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[]);
result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[],nil);
inserttypeconv_explicit(result,resultdef);
{ reused }
left:=nil;
@ -385,7 +385,7 @@ implementation
{ Pascal strings are 1-based, Java strings 0-based }
result:=ccallnode.create(ccallparanode.create(
caddnode.create(subn,right,genintconstnode(1)),nil),tprocsym(psym),
psym.owner,ctypeconvnode.create_explicit(left,stringclass),[]);
psym.owner,ctypeconvnode.create_explicit(left,stringclass),[],nil);
left:=nil;
right:=nil;
exit;

View File

@ -35,7 +35,8 @@ interface
{$ifdef state_tracking}
nstate,
{$endif state_tracking}
symbase,symtype,symsym,symdef,symtable;
symbase,symtype,symsym,symdef,symtable,
pgentype;
type
tcallnodeflag = (
@ -153,9 +154,11 @@ interface
typedef: tdef;
callnodeflags : tcallnodeflags;
spezcontext : tspecializationcontext;
{ only the processor specific nodes need to override this }
{ constructor }
constructor create(l:tnode; v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags);virtual;
constructor create(l:tnode; v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags;sc:tspecializationcontext);virtual;
constructor create_procvar(l,r:tnode);
constructor createintern(const name: string; params: tnode);
constructor createinternfromunit(const fromunit, procname: string; params: tnode);
@ -1412,9 +1415,10 @@ implementation
TCALLNODE
****************************************************************************}
constructor tcallnode.create(l:tnode;v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags);
constructor tcallnode.create(l:tnode;v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags;sc:tspecializationcontext);
begin
inherited create(calln,l,nil);
spezcontext:=sc;
symtableprocentry:=v;
symtableproc:=st;
callnodeflags:=callflags+[cnf_return_value_used];
@ -1440,7 +1444,7 @@ implementation
constructor tcallnode.create_procvar(l,r:tnode);
begin
create(l,nil,nil,nil,[]);
create(l,nil,nil,nil,[],nil);
right:=r;
end;
@ -1460,7 +1464,7 @@ implementation
if not assigned(srsym) or
(srsym.typ<>procsym) then
Message1(cg_f_unknown_compilerproc,name);
create(params,tprocsym(srsym),srsym.owner,nil,[]);
create(params,tprocsym(srsym),srsym.owner,nil,[],nil);
end;
@ -1473,7 +1477,7 @@ implementation
if not searchsym_in_named_module(fromunit,procname,srsym,srsymtable) or
(srsym.typ<>procsym) then
Message1(cg_f_unknown_compilerproc,fromunit+'.'+procname);
create(params,tprocsym(srsym),srsymtable,nil,[]);
create(params,tprocsym(srsym),srsymtable,nil,[],nil);
end;
@ -1530,7 +1534,7 @@ implementation
if not assigned(ps) or
(ps.typ<>procsym) then
internalerror(2011062806);
create(params,tprocsym(ps),ps.owner,mp,[]);
create(params,tprocsym(ps),ps.owner,mp,[],nil);
end;
@ -3442,7 +3446,7 @@ implementation
((m_delphi in current_settings.modeswitches) and (cnf_anon_inherited in callnodeflags));
candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility,
not(nf_isproperty in flags),cnf_objc_id_call in callnodeflags,cnf_unit_specified in callnodeflags,
callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags,nil);
callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags,spezcontext);
{ no procedures found? then there is something wrong
with the parameter size or the procedures are
@ -3543,6 +3547,10 @@ implementation
exit;
end;
{ if the final procedure definition is not yet owned,
ensure that it is }
procdefinition.register_def;
candidates.free;
end; { end of procedure to call determination }
end;

View File

@ -2227,7 +2227,7 @@ implementation
begin
include(current_procinfo.flags,pi_do_call);
addsymref(aprocdef.procsym);
hp:=ccallnode.create(ccallparanode.create(left,nil),Tprocsym(aprocdef.procsym),nil,nil,[]);
hp:=ccallnode.create(ccallparanode.create(left,nil),Tprocsym(aprocdef.procsym),nil,nil,[],nil);
{ tell explicitly which def we must use !! (PM) }
tcallnode(hp).procdefinition:=aprocdef;
left:=nil;
@ -3355,7 +3355,7 @@ implementation
{ constructor create(l:tnode; v : tprocsym;st : TSymtable; mp: tnode; callflags:tcallnodeflags); }
result:=ccallnode.create(nil,tprocsym(tpropertysym(implintf.implementsgetter).propaccesslist[palt_read].firstsym^.sym),
tprocsym(tpropertysym(implintf.implementsgetter).propaccesslist[palt_read].firstsym^.sym).owner,
left,[]);
left,[],nil);
addsymref(tpropertysym(implintf.implementsgetter).propaccesslist[palt_read].firstsym^.sym);
{ if it is a class, process it further in a similar way }
if not is_interface(result.resultdef) then

View File

@ -402,7 +402,7 @@ implementation
if not assigned(sym) or
(sym.typ<>procsym) then
internalerror(2010061901);
hp:=ccallnode.create(hp,tprocsym(sym),sym.owner,ctemprefnode.create(expressiontemp),[]);
hp:=ccallnode.create(hp,tprocsym(sym),sym.owner,ctemprefnode.create(expressiontemp),[],nil);
addstatement(outerloopbodystatement,cassignmentnode.create(
ctemprefnode.create(currentamount),hp));
{ if currentamount = 0, bail out (use copy of hloopvar, because we
@ -750,12 +750,12 @@ implementation
if enumerator_get.proctypeoption=potype_operator then
begin
enum_get_params:=ccallparanode.create(expr.getcopy,nil);
enum_get:=ccallnode.create(enum_get_params, tprocsym(enumerator_get.procsym), nil, nil, []);
enum_get:=ccallnode.create(enum_get_params, tprocsym(enumerator_get.procsym), nil, nil, [],nil);
tcallnode(enum_get).procdefinition:=enumerator_get;
addsymref(enumerator_get.procsym);
end
else
enum_get:=ccallnode.create(nil, tprocsym(enumerator_get.procsym), enumerator_get.owner, expr.getcopy, []);
enum_get:=ccallnode.create(nil, tprocsym(enumerator_get.procsym), enumerator_get.owner, expr.getcopy, [],nil);
addstatement(loopstatement,
cassignmentnode.create(
@ -778,7 +778,7 @@ implementation
procsym :
begin
{ generate the method call }
enum_current:=ccallnode.create(nil,tprocsym(propaccesslist.firstsym^.sym),enumerator_current.owner,ctemprefnode.create(enumvar),[]);
enum_current:=ccallnode.create(nil,tprocsym(propaccesslist.firstsym^.sym),enumerator_current.owner,ctemprefnode.create(enumvar),[],nil);
include(enum_current.flags,nf_isproperty);
end
else
@ -797,7 +797,7 @@ implementation
{ add the actual statement to the loop }
addstatement(loopbodystatement,hloopbody);
enum_move:=ccallnode.create(nil, tprocsym(enumerator_move.procsym), enumerator_move.owner, ctemprefnode.create(enumvar), []);
enum_move:=ccallnode.create(nil, tprocsym(enumerator_move.procsym), enumerator_move.owner, ctemprefnode.create(enumvar), [],nil);
whileloopnode:=cwhilerepeatnode.create(enum_move,loopbody,true,false);
if enumerator_is_class then
@ -809,7 +809,7 @@ implementation
whileloopnode:=ctryfinallynode.create(
whileloopnode, // try node
ccallnode.create(nil,tprocsym(enumerator_destructor.procsym), // finally node
enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[]));
enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[],nil));
end;
{ if getenumerator <> nil then do the loop }
whileloopnode:=cifnode.create(
@ -828,7 +828,7 @@ implementation
begin
addstatement(loopstatement,
ccallnode.create(nil,tprocsym(enumerator_destructor.procsym),
enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[]));
enumerator_destructor.procsym.owner,ctemprefnode.create(enumvar),[],nil));
end;
end;

View File

@ -146,7 +146,7 @@ implementation
caddnode.create(unequaln,
load_vmt_pointer_node,
cnilnode.create)),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
nil));
end
else
@ -353,7 +353,7 @@ implementation
(tprocsym(psym).procdeflist.count<>1) then
internalerror(2011040301);
addstatement(stat,ccallnode.create(nil,tprocsym(psym),
pd.struct.symtable,nil,[]));
pd.struct.symtable,nil,[],nil));
end;
addstatement(stat,result);
result:=block

View File

@ -293,7 +293,7 @@ implementation
(vs.typ<>procsym) then
internalerror(2011080601);
{ can't reuse "self", because it will be freed when we return }
result:=ccallnode.create(nil,tprocsym(vs),vs.owner,self.getcopy,[]);
result:=ccallnode.create(nil,tprocsym(vs),vs.owner,self.getcopy,[],nil);
end;
end;

View File

@ -1056,10 +1056,10 @@ implementation
begin
if not (st.symtabletype in [ObjectSymtable,recordsymtable]) then
internalerror(200310031);
p1:=ccallnode.create(para,tprocsym(sym),obj.symtable,p1,callflags);
p1:=ccallnode.create(para,tprocsym(sym),obj.symtable,p1,callflags,nil);
end
else
p1:=ccallnode.create(para,tprocsym(sym),st,p1,callflags);
p1:=ccallnode.create(para,tprocsym(sym),st,p1,callflags,nil);
end;
afterassignment:=prevafterassn;
end;
@ -1146,7 +1146,7 @@ implementation
membercall:=maybe_load_methodpointer(st,p1);
if membercall then
include(callflags,cnf_member_call);
p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags);
p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags,nil);
addsymref(sym);
paras:=nil;
consume(_ASSIGNMENT);
@ -1207,7 +1207,7 @@ implementation
membercall:=maybe_load_methodpointer(st,p1);
if membercall then
include(callflags,cnf_member_call);
p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags);
p1:=ccallnode.create(paras,tprocsym(sym),st,p1,callflags,nil);
paras:=nil;
include(p1.flags,nf_isproperty);
include(p1.flags,nf_no_lvalue);

View File

@ -245,7 +245,7 @@ implementation
do_member_read(classh,false,sym,p2,again,[callflag])
else
begin
p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2,[callflag]);
p2:=ccallnode.create(nil,tprocsym(sym),sym.owner,p2,[callflag],nil);
{ support dispose(p,done()); }
if try_to_consume(_LKLAMMER) then
begin

View File

@ -480,7 +480,7 @@ implementation
voidpointertype),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,
ctypeconvnode.create_internal(load_self_pointer_node,cclassrefdef.create(current_structdef)),
[])),
[],nil)),
nil));
end
else
@ -527,7 +527,7 @@ implementation
if assigned(srsym) and
(srsym.typ=procsym) then
begin
call:=ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[cnf_inherited]);
call:=ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[cnf_inherited],nil);
exclude(tcallnode(call).callnodeflags,cnf_return_value_used);
addstatement(newstatement,call);
end
@ -569,7 +569,7 @@ implementation
load_vmt_pointer_node,ptrsinttype),
ctypeconvnode.create_internal(
cnilnode.create,ptrsinttype)),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
nil));
end
else
@ -620,7 +620,7 @@ implementation
load_vmt_pointer_node,
voidpointertype),
cpointerconstnode.create(0,voidpointertype))),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
nil));
end
else
@ -766,7 +766,7 @@ implementation
caddnode.create(unequaln,
load_vmt_pointer_node,
cnilnode.create)),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[],nil),
nil));
tocode:=afterconstructionblock;
end
@ -794,7 +794,7 @@ implementation
load_vmt_pointer_node,
cnilnode.create),
{ cnf_create_failed -> don't call BeforeDestruction }
ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node,[cnf_create_failed]),
ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node,[cnf_create_failed],nil),
nil))
else
{ object without destructor, call 'fail' helper }

View File

@ -211,7 +211,7 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
begin
finalizepi.code:=right;
foreachnodestatic(right,@copy_parasize,finalizepi);
right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[]);
right:=ccallnode.create(nil,tprocsym(finalizepi.procdef.procsym),nil,nil,[],nil);
firstpass(right);
{ For implicit frames, no actual code is available at this time,
it is added later in assembler form. So store the nested procinfo