mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 20:49:23 +02:00
* Delphi-mode calling without parenthesis
This commit is contained in:
parent
c3736810ac
commit
2cc621618a
@ -2157,7 +2157,10 @@ implementation
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
loadp:=p;
|
loadp:=p;
|
||||||
refp:=ctemprefnode.create(ptemp)
|
refp:=ctemprefnode.create(ptemp);
|
||||||
|
{ ensure that an invokable isn't called again }
|
||||||
|
if is_invokable(hdef) then
|
||||||
|
include(ttemprefnode(refp).flags,nf_load_procvar);
|
||||||
end;
|
end;
|
||||||
add_init_statement(ptemp);
|
add_init_statement(ptemp);
|
||||||
add_init_statement(cassignmentnode.create(
|
add_init_statement(cassignmentnode.create(
|
||||||
@ -3628,6 +3631,7 @@ implementation
|
|||||||
statements : tstatementnode;
|
statements : tstatementnode;
|
||||||
converted_result_data : ttempcreatenode;
|
converted_result_data : ttempcreatenode;
|
||||||
calltype: tdispcalltype;
|
calltype: tdispcalltype;
|
||||||
|
invokesym : tsym;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
candidates:=nil;
|
candidates:=nil;
|
||||||
@ -3664,6 +3668,17 @@ implementation
|
|||||||
if codegenerror then
|
if codegenerror then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
if is_invokable(right.resultdef) then
|
||||||
|
begin
|
||||||
|
procdefinition:=get_invoke_procdef(tobjectdef(right.resultdef));
|
||||||
|
if assigned(methodpointer) then
|
||||||
|
internalerror(2021041004);
|
||||||
|
methodpointer:=right;
|
||||||
|
{ don't convert again when this is used as the self parameter }
|
||||||
|
include(right.flags,nf_load_procvar);
|
||||||
|
right:=nil;
|
||||||
|
end
|
||||||
|
else
|
||||||
procdefinition:=tabstractprocdef(right.resultdef);
|
procdefinition:=tabstractprocdef(right.resultdef);
|
||||||
|
|
||||||
{ Compare parameters from right to left }
|
{ Compare parameters from right to left }
|
||||||
|
@ -2528,7 +2528,15 @@ implementation
|
|||||||
convert on the procvar value. This is used to access the
|
convert on the procvar value. This is used to access the
|
||||||
fields of a methodpointer }
|
fields of a methodpointer }
|
||||||
if not(nf_load_procvar in flags) and
|
if not(nf_load_procvar in flags) and
|
||||||
not(resultdef.typ in [procvardef,recorddef,setdef]) then
|
not(resultdef.typ in [procvardef,recorddef,setdef]) and
|
||||||
|
not is_invokable(resultdef) and
|
||||||
|
{ in case of interface assignments of invokables they'll be converted
|
||||||
|
to voidpointertype using an internal conversions; we must not call
|
||||||
|
the invokable in that case }
|
||||||
|
not (
|
||||||
|
(nf_internal in flags) and
|
||||||
|
is_invokable(left.resultdef)
|
||||||
|
) then
|
||||||
maybe_call_procvar(left,true);
|
maybe_call_procvar(left,true);
|
||||||
|
|
||||||
if target_specific_general_typeconv then
|
if target_specific_general_typeconv then
|
||||||
|
@ -334,6 +334,8 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
class procedure tnodeutils.sym_maybe_initialize(p: TObject; arg: pointer);
|
class procedure tnodeutils.sym_maybe_initialize(p: TObject; arg: pointer);
|
||||||
|
var
|
||||||
|
hp : tnode;
|
||||||
begin
|
begin
|
||||||
if ((tsym(p).typ = localvarsym) or
|
if ((tsym(p).typ = localvarsym) or
|
||||||
{ check staticvarsym for record management opeators and for objects
|
{ check staticvarsym for record management opeators and for objects
|
||||||
@ -358,7 +360,10 @@ implementation
|
|||||||
((m_iso in current_settings.modeswitches) and (tabstractvarsym(p).vardef.typ=filedef))
|
((m_iso in current_settings.modeswitches) and (tabstractvarsym(p).vardef.typ=filedef))
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
addstatement(tstatementnode(arg^),initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner),false));
|
hp:=cloadnode.create(tsym(p),tsym(p).owner);
|
||||||
|
{ ensure that a function reference is not converted to a call }
|
||||||
|
include(hp.flags,nf_load_procvar);
|
||||||
|
addstatement(tstatementnode(arg^),initialize_data_node(hp,false));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -431,6 +436,8 @@ implementation
|
|||||||
hp:=cloadnode.create(sym,sym.owner);
|
hp:=cloadnode.create(sym,sym.owner);
|
||||||
if (sym.typ=staticvarsym) and (vo_force_finalize in tstaticvarsym(sym).varoptions) then
|
if (sym.typ=staticvarsym) and (vo_force_finalize in tstaticvarsym(sym).varoptions) then
|
||||||
include(tloadnode(hp).loadnodeflags,loadnf_isinternal_ignoreconst);
|
include(tloadnode(hp).loadnodeflags,loadnf_isinternal_ignoreconst);
|
||||||
|
{ ensure that a function reference interface is not converted to a call }
|
||||||
|
include(hp.flags,nf_load_procvar);
|
||||||
addstatement(stat,finalize_data_node(hp));
|
addstatement(stat,finalize_data_node(hp));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -674,7 +674,8 @@ implementation
|
|||||||
|
|
||||||
{ tp procvar support, when we don't expect a procvar
|
{ tp procvar support, when we don't expect a procvar
|
||||||
then we need to call the procvar }
|
then we need to call the procvar }
|
||||||
if (left.resultdef.typ<>procvardef) then
|
if (left.resultdef.typ<>procvardef) and
|
||||||
|
not is_invokable(left.resultdef) then
|
||||||
maybe_call_procvar(right,true);
|
maybe_call_procvar(right,true);
|
||||||
|
|
||||||
{ assignments to formaldefs and open arrays aren't allowed }
|
{ assignments to formaldefs and open arrays aren't allowed }
|
||||||
@ -808,6 +809,7 @@ implementation
|
|||||||
when trying to assign the result of a procedure, so give
|
when trying to assign the result of a procedure, so give
|
||||||
a better error message, see also #19122 }
|
a better error message, see also #19122 }
|
||||||
if (left.resultdef.typ<>procvardef) and
|
if (left.resultdef.typ<>procvardef) and
|
||||||
|
not is_invokable(left.resultdef) and
|
||||||
(right.nodetype=calln) and is_void(right.resultdef) then
|
(right.nodetype=calln) and is_void(right.resultdef) then
|
||||||
CGMessage(type_e_procedures_return_no_value)
|
CGMessage(type_e_procedures_return_no_value)
|
||||||
else if nf_internal in flags then
|
else if nf_internal in flags then
|
||||||
|
@ -477,7 +477,18 @@ implementation
|
|||||||
hp : tnode;
|
hp : tnode;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
if (p1.resultdef.typ<>procvardef) or
|
if not (p1.resultdef.typ in [procvardef,objectdef]) or
|
||||||
|
(
|
||||||
|
(p1.resultdef.typ=objectdef) and
|
||||||
|
(
|
||||||
|
not is_invokable(p1.resultdef) or
|
||||||
|
(nf_load_procvar in p1.flags) or
|
||||||
|
not (
|
||||||
|
is_funcref(p1.resultdef) or
|
||||||
|
invokable_has_argless_invoke(tobjectdef(p1.resultdef))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) or
|
||||||
(tponly and
|
(tponly and
|
||||||
not(m_tp_procvar in current_settings.modeswitches)) then
|
not(m_tp_procvar in current_settings.modeswitches)) then
|
||||||
exit;
|
exit;
|
||||||
|
@ -984,6 +984,9 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
p1:=load_self_node;
|
p1:=load_self_node;
|
||||||
|
{ don't try to call the invokable again }
|
||||||
|
if is_invokable(tdef(st.defowner)) then
|
||||||
|
include(p1.flags,nf_load_procvar);
|
||||||
{ We are calling a member }
|
{ We are calling a member }
|
||||||
maybe_load_methodpointer:=true;
|
maybe_load_methodpointer:=true;
|
||||||
end;
|
end;
|
||||||
@ -2790,6 +2793,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if not searchsym_in_class(tobjectdef(p1.resultdef),tobjectdef(p1.resultdef),method_name_funcref_invoke_find,srsym,srsymtable,[]) then
|
if not searchsym_in_class(tobjectdef(p1.resultdef),tobjectdef(p1.resultdef),method_name_funcref_invoke_find,srsym,srsymtable,[]) then
|
||||||
internalerror(2021040202);
|
internalerror(2021040202);
|
||||||
|
include(p1.flags,nf_load_procvar);
|
||||||
do_proc_call(srsym,srsymtable,tabstractrecorddef(p1.resultdef),false,again,p1,[],nil);
|
do_proc_call(srsym,srsymtable,tabstractrecorddef(p1.resultdef),false,again,p1,[],nil);
|
||||||
end
|
end
|
||||||
else if assigned(p1.resultdef) and
|
else if assigned(p1.resultdef) and
|
||||||
|
Loading…
Reference in New Issue
Block a user