compiler: change ret_in_param to accept tabstractprocdef instead of tproccalloption to allow check more options (required for record constructor implementation)

git-svn-id: trunk@23394 -
This commit is contained in:
paul 2013-01-16 01:14:23 +00:00
parent 4c84febfae
commit 51825b6f2e
22 changed files with 58 additions and 60 deletions

View File

@ -38,7 +38,7 @@ unit cpupara;
function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
@ -195,7 +195,7 @@ unit cpupara;
end;
function taarch64paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
function taarch64paramanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
var
i: longint;
sym: tsym;
@ -271,7 +271,7 @@ unit cpupara;
else
result:=false
else
result:=inherited ret_in_param(def,calloption);
result:=inherited ret_in_param(def,pd);
end;
end;

View File

@ -37,7 +37,7 @@ unit cpupara;
function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
@ -201,7 +201,7 @@ unit cpupara;
end;
function tarmparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
function tarmparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
var
i: longint;
sym: tsym;
@ -277,7 +277,7 @@ unit cpupara;
else
result:=false
else
result:=inherited ret_in_param(def,calloption);
result:=inherited ret_in_param(def,pd);
end;
end;

View File

@ -37,7 +37,7 @@ unit cpupara;
function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override;
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
@ -180,7 +180,7 @@ unit cpupara;
end;
function tavrparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
function tavrparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
begin
case def.typ of
recorddef:
@ -188,14 +188,14 @@ unit cpupara;
ARM ABI standard compliant
}
result:=not((trecorddef(def).symtable.SymList.count=1) and
not(ret_in_param(tabstractvarsym(trecorddef(def).symtable.SymList[0]).vardef,calloption)));
not(ret_in_param(tabstractvarsym(trecorddef(def).symtable.SymList[0]).vardef,pd)));
{
objectdef
arraydef:
result:=not(def.size in [1,2,4]);
}
else
result:=inherited ret_in_param(def,calloption);
result:=inherited ret_in_param(def,pd);
end;
end;

View File

@ -1125,7 +1125,7 @@ implementation
if tabstractnormalvarsym(def.funcretsym).localloc.loc=LOC_REFERENCE then
begin
{ TODO: Need to add gdb support for ret in param register calling}
if paramanager.ret_in_param(def.returndef,def.proccalloption) then
if paramanager.ret_in_param(def.returndef,def) then
hs:='X*'
else
hs:='X';

View File

@ -4420,7 +4420,7 @@ implementation
is_managed_type(ressym.vardef) then
begin
{ was: don't do anything if funcretloc.loc in [LOC_INVALID,LOC_REFERENCE] }
if not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption) then
if not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef) then
gen_load_loc_cgpara(list,ressym.vardef,ressym.localloc,funcretloc);
end
else

View File

@ -375,7 +375,7 @@ unit cgcpu;
not ((current_procinfo.procdef.proccalloption = pocall_safecall) and
(tf_safecall_exceptions in target_info.flags)) and
paramanager.ret_in_param(current_procinfo.procdef.returndef,
current_procinfo.procdef.proccalloption) then
current_procinfo.procdef) then
list.concat(Taicpu.Op_const(A_RET,S_W,sizeof(aint)))
else
list.concat(Taicpu.Op_none(A_RET,S_NO));

View File

@ -34,7 +34,7 @@ unit cpupara;
type
ti386paramanager = class(tparamanager)
function param_use_paraloc(const cgpara:tcgpara):boolean;override;
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function get_para_align(calloption : tproccalloption):byte;override;
function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
@ -92,12 +92,12 @@ unit cpupara;
end;
function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
function ti386paramanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
var
size: longint;
begin
if (tf_safecall_exceptions in target_info.flags) and
(calloption=pocall_safecall) then
(pd.proccalloption=pocall_safecall) then
begin
result:=true;
exit;
@ -112,9 +112,9 @@ unit cpupara;
For stdcall and register we follow delphi instead of GCC which returns
only records of a size of 1,2 or 4 bytes in FUNCTION_RETURN_REG }
if ((calloption in [pocall_stdcall,pocall_register]) and
if ((pd.proccalloption in [pocall_stdcall,pocall_register]) and
(def.size in [1,2,4])) or
((calloption in [pocall_cdecl,pocall_cppdecl]) and
((pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
(def.size>0) and
(def.size<=8)) then
begin
@ -129,7 +129,7 @@ unit cpupara;
system_i386_darwin,
system_i386_iphonesim :
begin
if calloption in cdecl_pocalls then
if pd.proccalloption in cdecl_pocalls then
begin
case def.typ of
recorddef :
@ -153,7 +153,7 @@ unit cpupara;
end;
end;
end;
result:=inherited ret_in_param(def,calloption);
result:=inherited ret_in_param(def,pd);
end;

View File

@ -94,7 +94,7 @@ implementation
but this one is never put into a register (vs_nonregable set)
so funcret is always in EAX for register calling }
if (target_info.system = system_i386_win32) and
paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) and
paramanager.ret_in_param(procdefinition.returndef,procdefinition) and
not ((procdefinition.proccalloption=pocall_register) or
((procdefinition.proccalloption=pocall_internproc) and
(pocall_default=pocall_register))) then

View File

@ -48,7 +48,7 @@ interface
function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override;
function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override;
function param_use_paraloc(const cgpara: tcgpara): boolean; override;
function ret_in_param(def: tdef; calloption: tproccalloption): boolean; override;
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
function is_stack_paraloc(paraloc: pcgparalocation): boolean;override;
private
procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
@ -176,7 +176,7 @@ implementation
result:=true;
end;
function TJVMParaManager.ret_in_param(def: tdef; calloption: tproccalloption): boolean;
function TJVMParaManager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
begin
{ not as efficient as returning in param for jvmimplicitpointertypes,
but in the latter case the routines are harder to use from Java

View File

@ -1760,7 +1760,7 @@ unit cgcpu;
if current_procinfo.procdef.proccalloption in clearstack_pocalls then
begin
{ complex return values are removed from stack in C code PM }
if paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption) then
if paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef) then
list.concat(taicpu.op_const(A_RTD,S_NO,4))
else
list.concat(taicpu.op_none(A_RTS,S_NO));

View File

@ -211,7 +211,7 @@ implementation
retdef:=forcetempdef
else
retdef:=p.returndef;
if ret_in_param(retdef,p.proccalloption) and
if ret_in_param(retdef,p) and
is_abi_record(retdef) then
begin
if intparareg=0 then

View File

@ -1145,8 +1145,8 @@ implementation
pd:=tprocdef(symtableprocentry.ProcdefList[0]);
{ both the normal and specified resultdef either have to be returned via a }
{ parameter or not, but no mixing (JM) }
if paramanager.ret_in_param(typedef,pd.proccalloption) xor
paramanager.ret_in_param(pd.returndef,pd.proccalloption) then
if paramanager.ret_in_param(typedef,pd) xor
paramanager.ret_in_param(pd.returndef,pd) then
internalerror(2001082911);
end;
@ -1161,8 +1161,8 @@ implementation
pd:=tprocdef(symtableprocentry.ProcdefList[0]);
{ both the normal and specified resultdef either have to be returned via a }
{ parameter or not, but no mixing (JM) }
if paramanager.ret_in_param(typedef,pd.proccalloption) xor
paramanager.ret_in_param(pd.returndef,pd.proccalloption) then
if paramanager.ret_in_param(typedef,pd) xor
paramanager.ret_in_param(pd.returndef,pd) then
internalerror(200108291);
end;
@ -1990,7 +1990,7 @@ implementation
{ A) set the appropriate objc_msgSend* variant to call }
{ record returned via implicit pointer }
if paramanager.ret_in_param(resultdef,procdefinition.proccalloption) then
if paramanager.ret_in_param(resultdef,procdefinition) then
begin
if not(cnf_inherited in callnodeflags) then
msgsendname:='OBJC_MSGSEND_STRET'
@ -2287,7 +2287,7 @@ implementation
{ when it is not passed in a parameter it will only be used after the
function call }
if not paramanager.ret_in_param(resultdef,procdefinition.proccalloption) then
if not paramanager.ret_in_param(resultdef,procdefinition) then
begin
result:=true;
exit;
@ -2363,7 +2363,7 @@ implementation
(
(cnf_do_inline in callnodeflags) or
is_managed_type(resultdef) or
paramanager.ret_in_param(resultdef,procdefinition.proccalloption)
paramanager.ret_in_param(resultdef,procdefinition)
) then
begin
{ Optimize calls like x:=f() where we can use x directly as
@ -2395,8 +2395,8 @@ implementation
{ if a managed type is returned by reference, assigning something
to the result on the caller side will take care of decreasing
the reference count }
if paramanager.ret_in_param(resultdef,procdefinition.proccalloption) then
include(ttempcreatenode(temp).tempinfo^.flags,ti_nofini);
if paramanager.ret_in_param(resultdef,procdefinition) then
include(temp.tempinfo^.flags,ti_nofini);
add_init_statement(temp);
{ When the function result is not used in an inlined function
we need to delete the temp. This can currently only be done by
@ -3583,7 +3583,7 @@ implementation
{ get a register for the return value }
if (not is_void(resultdef)) then
begin
if paramanager.ret_in_param(resultdef,procdefinition.proccalloption) then
if paramanager.ret_in_param(resultdef,procdefinition) then
begin
expectloc:=LOC_REFERENCE;
end

View File

@ -372,7 +372,7 @@ implementation
{ Check that the return location is set when the result is passed in
a parameter }
if (procdefinition.proctypeoption<>potype_constructor) and
paramanager.ret_in_param(resultdef,procdefinition.proccalloption) then
paramanager.ret_in_param(resultdef,procdefinition) then
begin
{ self.location is set near the end of secondcallparan so it
refers to the implicit result parameter }
@ -938,7 +938,7 @@ implementation
c-side, so the funcret has to be pop'ed normally. }
if not ((procdefinition.proccalloption=pocall_safecall) and
(tf_safecall_exceptions in target_info.flags)) and
paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
paramanager.ret_in_param(procdefinition.returndef,procdefinition) then
dec(pop_size,sizeof(pint));
{ Remove parameters/alignment from the stack }
pop_parasize(pop_size);

View File

@ -1389,7 +1389,7 @@ implementation
if current_procinfo.procdef.proccalloption in clearstack_pocalls then
begin
parasize:=0;
if paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption) then
if paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef) then
inc(parasize,sizeof(pint));
end
else

View File

@ -44,10 +44,8 @@ unit paramgr;
tparamanager = class
{ true if the location in paraloc can be reused as localloc }
function param_use_paraloc(const cgpara:tcgpara):boolean;virtual;
{# Returns true if the return value is actually a parameter
pointer.
}
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;virtual;
{ Returns true if the return value is actually a parameter pointer }
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;virtual;
function push_high_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
function keep_para_array_range(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;virtual;
@ -168,10 +166,10 @@ implementation
{ true if uses a parameter as return value }
function tparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
function tparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
begin
if (tf_safecall_exceptions in target_info.flags) and
(calloption=pocall_safecall) then
(pd.proccalloption=pocall_safecall) then
begin
result:=true;
exit;
@ -559,7 +557,7 @@ implementation
end;
retloc.size:=retcgsize;
{ Return is passed as var parameter }
if ret_in_param(retloc.def,p.proccalloption) then
if ret_in_param(retloc.def,p) then
begin
retloc.def:=getpointerdef(retloc.def);
paraloc:=retloc.add_location;

View File

@ -52,7 +52,7 @@ implementation
if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and
not is_void(pd.returndef) and
not (df_generic in pd.defoptions) and
paramanager.ret_in_param(pd.returndef,pd.proccalloption) then
paramanager.ret_in_param(pd.returndef,pd) then
begin
storepos:=current_tokenpos;
if pd.typ=procdef then
@ -78,7 +78,7 @@ implementation
{ Generate result variable accessing function result }
vs:=tparavarsym.create('$result',paranr,vs_var,pd.returndef,[vo_is_funcret,vo_is_hidden_para]);
pd.parast.insert(vs);
{ Store the this symbol as funcretsym for procedures }
{ Store this symbol as funcretsym for procedures }
if pd.typ=procdef then
tprocdef(pd).funcretsym:=vs;
@ -250,7 +250,7 @@ implementation
the creation of a result symbol in insert_funcret_para, but we need
a valid funcretsym }
if (df_generic in pd.defoptions) or
not paramanager.ret_in_param(pd.returndef,pd.proccalloption) then
not paramanager.ret_in_param(pd.returndef,pd) then
begin
vs:=tlocalvarsym.create('$result',vs_value,pd.returndef,[vo_is_funcret]);
pd.localst.insert(vs);

View File

@ -1395,7 +1395,7 @@ implementation
(not assigned(current_procinfo.procdef.funcretsym) or
(tabstractvarsym(current_procinfo.procdef.funcretsym).refs<=1)) and
not (df_generic in current_procinfo.procdef.defoptions) and
not(paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption)) then
not(paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef)) then
begin
{ Only need to set the framepointer, the locals will
be inserted with the correct reference in tcgasmnode.pass_generate_code }
@ -1409,7 +1409,7 @@ implementation
}
if assigned(current_procinfo.procdef.funcretsym) and
not (df_generic in current_procinfo.procdef.defoptions) and
(not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption)) then
(not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef)) then
tabstractvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_initialised;
{ because the END is already read we need to get the

View File

@ -636,7 +636,7 @@ implementation
{ must be the return value finalized before reraising the exception? }
if (not is_void(current_procinfo.procdef.returndef)) and
is_managed_type(current_procinfo.procdef.returndef) and
(not paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption)) and
(not paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef)) and
(not is_class(current_procinfo.procdef.returndef)) then
addstatement(newstatement,cnodeutils.finalize_data_node(load_result_node));
end;

View File

@ -692,7 +692,7 @@ begin
begin
if (m_tp7 in current_settings.modeswitches) and
not (df_generic in defoptions) and
(not paramanager.ret_in_param(returndef,proccalloption)) then
(not paramanager.ret_in_param(returndef,current_procinfo.procdef)) then
begin
message(asmr_e_cannot_use_RESULT_here);
exit;

View File

@ -1303,7 +1303,7 @@ implementation
var
hr : treference;
begin
if paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef.proccalloption) then
if paramanager.ret_in_param(current_procinfo.procdef.returndef,current_procinfo.procdef) then
begin
reference_reset(hr,sizeof(pint));
hr.offset:=12;

View File

@ -46,7 +46,7 @@ implementation
procedure tsparccallnode.extra_post_call_code;
begin
if paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
if paramanager.ret_in_param(procdefinition.returndef,procdefinition) then
current_asmdata.CurrAsmList.concat(taicpu.op_const(A_UNIMP,procdefinition.returndef.size and $fff));
end;

View File

@ -40,7 +40,7 @@ unit cpupara;
public
function param_use_paraloc(const cgpara:tcgpara):boolean;override;
function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override;
function ret_in_param(def:tdef;pd:tabstractprocdef):boolean;override;
procedure getintparaloc(pd : tabstractprocdef; nr : longint; var cgpara : tcgpara);override;
function get_volatile_registers_int(calloption : tproccalloption):tcpuregisterset;override;
function get_volatile_registers_mm(calloption : tproccalloption):tcpuregisterset;override;
@ -618,16 +618,16 @@ unit cpupara;
end;
function tx86_64paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean;
function tx86_64paramanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
var
classes: tx64paraclasses;
numclasses: longint;
begin
if (tf_safecall_exceptions in target_info.flags) and
(calloption=pocall_safecall) then
(pd.proccalloption=pocall_safecall) then
begin
result := true;
exit;
result:=true;
exit;
end;
case def.typ of
{ for records it depends on their contents and size }
@ -639,7 +639,7 @@ unit cpupara;
result:=(numclasses=0);
end;
else
result:=inherited ret_in_param(def,calloption);
result:=inherited ret_in_param(def,pd);
end;
end;