mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-24 20:49:16 +02:00
* keep track of static symbols that a global function references, as those must now be exported from a dynamic package as well if the function can potentially be inlined
git-svn-id: trunk@43544 -
This commit is contained in:
parent
2e259ee3cc
commit
0a915e883e
@ -857,7 +857,7 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
addsymref(operpd.procsym);
|
addsymref(operpd.procsym,operpd);
|
||||||
|
|
||||||
{ the nil as symtable signs firstcalln that this is
|
{ the nil as symtable signs firstcalln that this is
|
||||||
an overloaded operator }
|
an overloaded operator }
|
||||||
@ -1052,7 +1052,7 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
addsymref(operpd.procsym);
|
addsymref(operpd.procsym,operpd);
|
||||||
|
|
||||||
{ the nil as symtable signs firstcalln that this is
|
{ the nil as symtable signs firstcalln that this is
|
||||||
an overloaded operator }
|
an overloaded operator }
|
||||||
|
@ -3787,7 +3787,7 @@ implementation
|
|||||||
{ add reference to corresponding procsym; may not be the one
|
{ add reference to corresponding procsym; may not be the one
|
||||||
originally found/passed to the constructor because of overloads }
|
originally found/passed to the constructor because of overloads }
|
||||||
if procdefinition.typ = procdef then
|
if procdefinition.typ = procdef then
|
||||||
addsymref(tprocdef(procdefinition).procsym);
|
addsymref(tprocdef(procdefinition).procsym,procdefinition);
|
||||||
|
|
||||||
{ add needed default parameters }
|
{ add needed default parameters }
|
||||||
if (paralength<procdefinition.maxparacount) then
|
if (paralength<procdefinition.maxparacount) then
|
||||||
|
@ -2513,7 +2513,7 @@ implementation
|
|||||||
te_convert_operator :
|
te_convert_operator :
|
||||||
begin
|
begin
|
||||||
include(current_procinfo.flags,pi_do_call);
|
include(current_procinfo.flags,pi_do_call);
|
||||||
addsymref(aprocdef.procsym);
|
addsymref(aprocdef.procsym,aprocdef);
|
||||||
hp:=ccallnode.create(ccallparanode.create(left,nil),Tprocsym(aprocdef.procsym),nil,nil,[],nil);
|
hp:=ccallnode.create(ccallparanode.create(left,nil),Tprocsym(aprocdef.procsym),nil,nil,[],nil);
|
||||||
{ tell explicitly which def we must use !! (PM) }
|
{ tell explicitly which def we must use !! (PM) }
|
||||||
tcallnode(hp).procdefinition:=aprocdef;
|
tcallnode(hp).procdefinition:=aprocdef;
|
||||||
|
@ -793,7 +793,7 @@ implementation
|
|||||||
enum_get_params:=ccallparanode.create(expr.getcopy,nil);
|
enum_get_params:=ccallparanode.create(expr.getcopy,nil);
|
||||||
enum_get:=ccallnode.create(enum_get_params, tprocsym(enumerator_get.procsym), nil, nil, [],nil);
|
enum_get:=ccallnode.create(enum_get_params, tprocsym(enumerator_get.procsym), nil, nil, [],nil);
|
||||||
tcallnode(enum_get).procdefinition:=enumerator_get;
|
tcallnode(enum_get).procdefinition:=enumerator_get;
|
||||||
addsymref(enumerator_get.procsym);
|
addsymref(enumerator_get.procsym,enumerator_get);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
enum_get:=ccallnode.create(nil, tprocsym(enumerator_get.procsym), enumerator_get.owner, expr.getcopy, [],nil);
|
enum_get:=ccallnode.create(nil, tprocsym(enumerator_get.procsym), enumerator_get.owner, expr.getcopy, [],nil);
|
||||||
|
@ -88,7 +88,10 @@ implementation
|
|||||||
(symtable.symtabletype in [globalsymtable,recordsymtable,objectsymtable]) or
|
(symtable.symtabletype in [globalsymtable,recordsymtable,objectsymtable]) or
|
||||||
(
|
(
|
||||||
(symtable.symtabletype=staticsymtable) and
|
(symtable.symtabletype=staticsymtable) and
|
||||||
([po_public,po_has_public_name]*pd.procoptions<>[])
|
(
|
||||||
|
([po_public,po_has_public_name]*pd.procoptions<>[]) or
|
||||||
|
(df_has_global_ref in pd.defoptions)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
@ -217,7 +220,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
staticvarsym:
|
staticvarsym:
|
||||||
begin
|
begin
|
||||||
if publiconly and not (vo_is_public in tstaticvarsym(sym).varoptions) then
|
if publiconly and ([vo_is_public,vo_has_global_ref]*tstaticvarsym(sym).varoptions=[]) then
|
||||||
exit;
|
exit;
|
||||||
varexport(tsym(sym).mangledname);
|
varexport(tsym(sym).mangledname);
|
||||||
end;
|
end;
|
||||||
|
@ -140,6 +140,11 @@ unit procinfo;
|
|||||||
need to be checked explicitly like on RISC-V or certain ARM architectures }
|
need to be checked explicitly like on RISC-V or certain ARM architectures }
|
||||||
FPUExceptionCheckNeeded : Boolean;
|
FPUExceptionCheckNeeded : Boolean;
|
||||||
|
|
||||||
|
{ local symbols and defs referenced by global functions; these need
|
||||||
|
to be exported in case the function gets inlined }
|
||||||
|
localrefsyms : tfpobjectlist;
|
||||||
|
localrefdefs : tfpobjectlist;
|
||||||
|
|
||||||
constructor create(aparent:tprocinfo);virtual;
|
constructor create(aparent:tprocinfo);virtual;
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
|
|
||||||
@ -170,6 +175,11 @@ unit procinfo;
|
|||||||
function has_nestedprocs: boolean;
|
function has_nestedprocs: boolean;
|
||||||
function get_normal_proc: tprocinfo;
|
function get_normal_proc: tprocinfo;
|
||||||
|
|
||||||
|
procedure add_local_ref_sym(sym:tsym);
|
||||||
|
procedure export_local_ref_syms;
|
||||||
|
procedure add_local_ref_def(def:tdef);
|
||||||
|
procedure export_local_ref_defs;
|
||||||
|
|
||||||
function create_for_outlining(const basesymname: string; astruct: tabstractrecorddef; potype: tproctypeoption; resultdef: tdef; entrynodeinfo: tnode): tprocinfo;
|
function create_for_outlining(const basesymname: string; astruct: tabstractrecorddef; potype: tproctypeoption; resultdef: tdef; entrynodeinfo: tnode): tprocinfo;
|
||||||
|
|
||||||
{ Add to parent's list of nested procedures even if parent is a 'main' procedure }
|
{ Add to parent's list of nested procedures even if parent is a 'main' procedure }
|
||||||
@ -203,7 +213,7 @@ unit procinfo;
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
globals,cutils,systems,
|
globals,cutils,systems,verbose,
|
||||||
procdefutil;
|
procdefutil;
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
@ -244,6 +254,8 @@ implementation
|
|||||||
nestedprocs.free;
|
nestedprocs.free;
|
||||||
aktproccode.free;
|
aktproccode.free;
|
||||||
aktlocaldata.free;
|
aktlocaldata.free;
|
||||||
|
localrefsyms.free;
|
||||||
|
localrefdefs.free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure tprocinfo.destroy_tree;
|
procedure tprocinfo.destroy_tree;
|
||||||
@ -288,6 +300,54 @@ implementation
|
|||||||
result:=result.parent;
|
result:=result.parent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure tprocinfo.add_local_ref_sym(sym:tsym);
|
||||||
|
begin
|
||||||
|
if not assigned(localrefsyms) then
|
||||||
|
localrefsyms:=tfpobjectlist.create(false);
|
||||||
|
if localrefsyms.indexof(sym)<0 then
|
||||||
|
localrefsyms.add(sym);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure tprocinfo.export_local_ref_syms;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
sym : tsym;
|
||||||
|
begin
|
||||||
|
if not assigned(localrefsyms) then
|
||||||
|
exit;
|
||||||
|
for i:=0 to localrefsyms.count-1 do
|
||||||
|
begin
|
||||||
|
sym:=tsym(localrefsyms[i]);
|
||||||
|
if sym.typ<>staticvarsym then
|
||||||
|
internalerror(2019110901);
|
||||||
|
include(tstaticvarsym(sym).varoptions,vo_has_global_ref);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure tprocinfo.add_local_ref_def(def:tdef);
|
||||||
|
begin
|
||||||
|
if not assigned(localrefdefs) then
|
||||||
|
localrefdefs:=tfpobjectlist.create(false);
|
||||||
|
if localrefdefs.indexof(def)<0 then
|
||||||
|
localrefdefs.add(def);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure tprocinfo.export_local_ref_defs;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
def : tdef;
|
||||||
|
begin
|
||||||
|
if not assigned(localrefdefs) then
|
||||||
|
exit;
|
||||||
|
for i:=0 to localrefdefs.count-1 do
|
||||||
|
begin
|
||||||
|
def:=tdef(localrefdefs[i]);
|
||||||
|
if def.typ<>symconst.procdef then
|
||||||
|
internalerror(2019111801);
|
||||||
|
include(tprocdef(def).defoptions,df_has_global_ref);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
function tprocinfo.create_for_outlining(const basesymname: string; astruct: tabstractrecorddef; potype: tproctypeoption; resultdef: tdef; entrynodeinfo: tnode): tprocinfo;
|
function tprocinfo.create_for_outlining(const basesymname: string; astruct: tabstractrecorddef; potype: tproctypeoption; resultdef: tdef; entrynodeinfo: tnode): tprocinfo;
|
||||||
begin
|
begin
|
||||||
result:=cprocinfo.create(self);
|
result:=cprocinfo.create(self);
|
||||||
|
@ -1384,6 +1384,8 @@ implementation
|
|||||||
if procdef.inlininginfo^.code.nodetype=blockn then
|
if procdef.inlininginfo^.code.nodetype=blockn then
|
||||||
include(procdef.inlininginfo^.code.flags,nf_block_with_exit);
|
include(procdef.inlininginfo^.code.flags,nf_block_with_exit);
|
||||||
procdef.has_inlininginfo:=true;
|
procdef.has_inlininginfo:=true;
|
||||||
|
export_local_ref_syms;
|
||||||
|
export_local_ref_defs;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure searchthreadvar(p: TObject; arg: pointer);
|
procedure searchthreadvar(p: TObject; arg: pointer);
|
||||||
|
@ -232,7 +232,9 @@ type
|
|||||||
because we have to access this information in the symtable unit }
|
because we have to access this information in the symtable unit }
|
||||||
df_llvm_no_struct_packing,
|
df_llvm_no_struct_packing,
|
||||||
{ internal def that's not for any export }
|
{ internal def that's not for any export }
|
||||||
df_internal
|
df_internal,
|
||||||
|
{ the local def is referenced from a public function }
|
||||||
|
df_has_global_ref
|
||||||
);
|
);
|
||||||
tdefoptions=set of tdefoption;
|
tdefoptions=set of tdefoption;
|
||||||
|
|
||||||
@ -607,7 +609,9 @@ type
|
|||||||
sections }
|
sections }
|
||||||
vo_is_default_var,
|
vo_is_default_var,
|
||||||
{ i8086 'external far' (can only be used in combination with vo_is_external) }
|
{ i8086 'external far' (can only be used in combination with vo_is_external) }
|
||||||
vo_is_far
|
vo_is_far,
|
||||||
|
{ a static symbol that is referenced from a global function }
|
||||||
|
vo_has_global_ref
|
||||||
);
|
);
|
||||||
tvaroptions=set of tvaroption;
|
tvaroptions=set of tvaroption;
|
||||||
|
|
||||||
|
@ -334,7 +334,8 @@ interface
|
|||||||
procedure write_system_parameter_lists(const name:string);
|
procedure write_system_parameter_lists(const name:string);
|
||||||
|
|
||||||
{*** Search ***}
|
{*** Search ***}
|
||||||
procedure addsymref(sym:tsym);
|
procedure addsymref(sym:tsym);inline;
|
||||||
|
procedure addsymref(sym:tsym;def:tdef);
|
||||||
function is_owned_by(nesteddef,ownerdef:tdef):boolean;
|
function is_owned_by(nesteddef,ownerdef:tdef):boolean;
|
||||||
function sym_is_owned_by(childsym:tsym;symtable:tsymtable):boolean;
|
function sym_is_owned_by(childsym:tsym;symtable:tsymtable):boolean;
|
||||||
function defs_belong_to_same_generic(def1,def2:tdef):boolean;
|
function defs_belong_to_same_generic(def1,def2:tdef):boolean;
|
||||||
@ -474,7 +475,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
{ global }
|
{ global }
|
||||||
verbose,globals,
|
verbose,globals,systems,
|
||||||
{ symtable }
|
{ symtable }
|
||||||
symutil,defutil,defcmp,objcdef,
|
symutil,defutil,defcmp,objcdef,
|
||||||
{ module }
|
{ module }
|
||||||
@ -3029,9 +3030,9 @@ implementation
|
|||||||
Search
|
Search
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
procedure addsymref(sym:tsym);
|
procedure addsymref(sym:tsym;def:tdef);
|
||||||
var
|
var
|
||||||
owner: tsymtable;
|
owner,procowner : tsymtable;
|
||||||
begin
|
begin
|
||||||
{ for symbols used in preprocessor expressions, we don't want to
|
{ for symbols used in preprocessor expressions, we don't want to
|
||||||
increase references count (for smaller final binaries) }
|
increase references count (for smaller final binaries) }
|
||||||
@ -3063,8 +3064,47 @@ implementation
|
|||||||
{ symbol is imported from another unit }
|
{ symbol is imported from another unit }
|
||||||
current_module.addimportedsym(sym);
|
current_module.addimportedsym(sym);
|
||||||
end;
|
end;
|
||||||
|
{ static symbols that are used in public functions must be exported
|
||||||
|
for packages as well }
|
||||||
|
if ([tf_supports_packages,tf_supports_hidden_symbols]<=target_info.flags) and
|
||||||
|
(owner.symtabletype=staticsymtable) and
|
||||||
|
assigned(current_procinfo) and
|
||||||
|
(
|
||||||
|
(
|
||||||
|
(sym.typ=staticvarsym) and
|
||||||
|
([vo_is_public,vo_has_global_ref]*tstaticvarsym(sym).varoptions=[])
|
||||||
|
) or (
|
||||||
|
(sym.typ=localvarsym) and
|
||||||
|
assigned(tlocalvarsym(sym).defaultconstsym) and
|
||||||
|
([vo_is_public,vo_has_global_ref]*tstaticvarsym(tlocalvarsym(sym).defaultconstsym).varoptions=[])
|
||||||
|
) or (
|
||||||
|
(sym.typ=procsym) and
|
||||||
|
assigned(def) and
|
||||||
|
(def.typ=procdef) and
|
||||||
|
not (df_has_global_ref in def.defoptions) and
|
||||||
|
not (po_public in tprocdef(def).procoptions)
|
||||||
|
)
|
||||||
|
) then
|
||||||
|
begin
|
||||||
|
procowner:=current_procinfo.procdef.owner;
|
||||||
|
while procowner.symtabletype in [objectsymtable,recordsymtable] do
|
||||||
|
procowner:=tdef(procowner.defowner).owner;
|
||||||
|
if procowner.symtabletype=globalsymtable then
|
||||||
|
begin
|
||||||
|
if sym.typ=procsym then
|
||||||
|
current_procinfo.add_local_ref_def(def)
|
||||||
|
else if sym.typ=staticvarsym then
|
||||||
|
current_procinfo.add_local_ref_sym(sym)
|
||||||
|
else
|
||||||
|
current_procinfo.add_local_ref_sym(tlocalvarsym(sym).defaultconstsym);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure addsymref(sym:tsym);
|
||||||
|
begin
|
||||||
|
addsymref(sym,nil);
|
||||||
|
end;
|
||||||
|
|
||||||
function is_owned_by(nesteddef,ownerdef:tdef):boolean;
|
function is_owned_by(nesteddef,ownerdef:tdef):boolean;
|
||||||
begin
|
begin
|
||||||
|
@ -2729,7 +2729,8 @@ const
|
|||||||
{ this should never happen for defs stored to a ppu file }
|
{ this should never happen for defs stored to a ppu file }
|
||||||
(mask:df_not_registered_no_free; str:'Unregistered/No free (invalid)'),
|
(mask:df_not_registered_no_free; str:'Unregistered/No free (invalid)'),
|
||||||
(mask:df_llvm_no_struct_packing; str:'LLVM unpacked struct'),
|
(mask:df_llvm_no_struct_packing; str:'LLVM unpacked struct'),
|
||||||
(mask:df_internal; str:'Internal')
|
(mask:df_internal; str:'Internal'),
|
||||||
|
(mask:df_has_global_ref; str:'Has Global Ref')
|
||||||
);
|
);
|
||||||
defstate : array[1..ord(high(tdefstate))] of tdefstateinfo=(
|
defstate : array[1..ord(high(tdefstate))] of tdefstateinfo=(
|
||||||
(mask:ds_vmt_written; str:'VMT Written'),
|
(mask:ds_vmt_written; str:'VMT Written'),
|
||||||
@ -3068,7 +3069,8 @@ const
|
|||||||
(mask:vo_has_section; str:'HasSection'),
|
(mask:vo_has_section; str:'HasSection'),
|
||||||
(mask:vo_force_finalize; str:'ForceFinalize'),
|
(mask:vo_force_finalize; str:'ForceFinalize'),
|
||||||
(mask:vo_is_default_var; str:'DefaultIntrinsicVar'),
|
(mask:vo_is_default_var; str:'DefaultIntrinsicVar'),
|
||||||
(mask:vo_is_far; str:'IsFar')
|
(mask:vo_is_far; str:'IsFar'),
|
||||||
|
(mask:vo_has_global_ref; str:'HasGlobalRef')
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
tvaraccessdesc=record
|
tvaraccessdesc=record
|
||||||
|
Loading…
Reference in New Issue
Block a user