|
@@ -55,6 +55,13 @@ interface
|
|
|
{ idem for finalization }
|
|
|
class function force_final: boolean; virtual;
|
|
|
|
|
|
+ { if the funcretsym was moved to the parentfpstruct, use this method to
|
|
|
+ move its value back back into the funcretsym before the function exit, as
|
|
|
+ the code generator is hardcoded to use to use the funcretsym when loading
|
|
|
+ the value to be returned; replacing it with an absolutevarsym that
|
|
|
+ redirects to the field in the parentfpstruct doesn't work, as the code
|
|
|
+ generator cannot deal with such symbols }
|
|
|
+ class procedure load_parentfpstruct_nested_funcret(pd: tprocdef; var stat: tstatementnode);
|
|
|
{ called after parsing a routine with the code of the entire routine
|
|
|
as argument; can be used to modify the node tree. By default handles
|
|
|
insertion of code for systems that perform the typed constant
|
|
@@ -464,11 +471,26 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ class procedure tnodeutils.load_parentfpstruct_nested_funcret(pd: tprocdef; var stat: tstatementnode);
|
|
|
+ var
|
|
|
+ target: tnode;
|
|
|
+ begin
|
|
|
+ target:=cloadnode.create(pd.funcretsym, pd.funcretsym.owner);
|
|
|
+ { ensure the target of this assignment doesn't translate the
|
|
|
+ funcretsym also to its alias in the parentfpstruct }
|
|
|
+ include(target.flags, nf_internal);
|
|
|
+ addstatement(stat,
|
|
|
+ cassignmentnode.create(
|
|
|
+ target, cloadnode.create(pd.funcretsym, pd.funcretsym.owner)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
class function tnodeutils.wrap_proc_body(pd: tprocdef; n: tnode): tnode;
|
|
|
var
|
|
|
stat: tstatementnode;
|
|
|
- block,
|
|
|
- target: tnode;
|
|
|
+ block: tnode;
|
|
|
psym: tsym;
|
|
|
begin
|
|
|
result:=maybe_insert_trashing(pd,n);
|
|
@@ -541,26 +563,12 @@ implementation
|
|
|
end;
|
|
|
if target_info.system in systems_fpnestedstruct then
|
|
|
begin
|
|
|
- { if the funcretsym was moved to the parentfpstruct, move its value
|
|
|
- back into the funcretsym now, as the code generator is hardcoded
|
|
|
- to use the funcretsym when loading the value to be returned;
|
|
|
- replacing it with an absolutevarsym that redirects to the field in
|
|
|
- the parentfpstruct doesn't work, as the code generator cannot deal
|
|
|
- with such symbols }
|
|
|
if assigned(pd.funcretsym) and
|
|
|
tabstractnormalvarsym(pd.funcretsym).inparentfpstruct then
|
|
|
begin
|
|
|
block:=internalstatements(stat);
|
|
|
addstatement(stat,result);
|
|
|
- target:=cloadnode.create(pd.funcretsym,pd.funcretsym.owner);
|
|
|
- { ensure the target of this assignment doesn't translate the
|
|
|
- funcretsym also to its alias in the parentfpstruct }
|
|
|
- include(target.flags,nf_internal);
|
|
|
- addstatement(stat,
|
|
|
- cassignmentnode.create(
|
|
|
- target,cloadnode.create(pd.funcretsym,pd.funcretsym.owner)
|
|
|
- )
|
|
|
- );
|
|
|
+ load_parentfpstruct_nested_funcret(pd,stat);
|
|
|
result:=block;
|
|
|
end;
|
|
|
end;
|