mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-01 04:02:40 +02:00
* emit the correct declaration for procdefs used to force a procname in LLVM
o fixes lazarus startup on macOS/AArch64 when compiled with the LLVM cg git-svn-id: trunk@46675 -
This commit is contained in:
parent
27fbf8c91e
commit
453bfcd370
@ -600,10 +600,10 @@ implementation
|
||||
result:=inherited pass_1;
|
||||
if assigned(result) then
|
||||
exit;
|
||||
{ set fforcedprocname so that even virtual method calls will be
|
||||
{ set foverrideprocnamedef so that even virtual method calls will be
|
||||
name-based (instead of based on VMT entry numbers) }
|
||||
if procdefinition.typ=procdef then
|
||||
fforcedprocname:=tprocdef(procdefinition).mangledname
|
||||
foverrideprocnamedef:=tprocdef(procdefinition)
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -39,6 +39,7 @@ interface
|
||||
function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; override;
|
||||
function can_call_ref(var ref: treference): boolean; override;
|
||||
procedure pushparas; override;
|
||||
procedure pass_generate_code; override;
|
||||
end;
|
||||
|
||||
|
||||
@ -46,6 +47,7 @@ implementation
|
||||
|
||||
uses
|
||||
verbose,
|
||||
aasmbase,aasmdata,aasmllvm,
|
||||
symconst,symdef;
|
||||
|
||||
{*****************************************************************************
|
||||
@ -104,6 +106,30 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tllvmcallnode.pass_generate_code;
|
||||
var
|
||||
asmsym: tasmsymbol;
|
||||
begin
|
||||
inherited;
|
||||
if assigned(overrideprocnamedef) and
|
||||
not overrideprocnamedef.in_currentunit then
|
||||
begin
|
||||
{ insert an llvm declaration for this def if it's not defined in
|
||||
the current unit, because otherwise we will define it in the
|
||||
LLVM IR using the def for which this procdef's name is used
|
||||
first, which may be something completely different from the original
|
||||
def. LLVM can take the original def into account to load certain
|
||||
registers, so if we use a wrong def this can result in wrong code
|
||||
generation. }
|
||||
asmsym:=current_asmdata.RefAsmSymbol(overrideprocnamedef.mangledname,AT_FUNCTION);
|
||||
if not asmsym.declared then
|
||||
begin
|
||||
current_asmdata.AsmLists[al_imports].Concat(taillvmdecl.createdecl(asmsym,overrideprocnamedef,nil,sec_code,overrideprocnamedef.alignment));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
ccallnode:=tllvmcallnode;
|
||||
end.
|
||||
|
@ -67,7 +67,7 @@ interface
|
||||
private
|
||||
{ number of parameters passed from the source, this does not include the hidden parameters }
|
||||
paralength : smallint;
|
||||
function getforcedprocname: TSymStr;
|
||||
function getoverrideprocnamedef: tprocdef; inline;
|
||||
function is_simple_para_load(p:tnode; may_be_in_reg: boolean):boolean;
|
||||
procedure maybe_load_in_temp(var p:tnode);
|
||||
function gen_high_tree(var p:tnode;paradef:tdef):tnode;
|
||||
@ -90,6 +90,7 @@ interface
|
||||
function pass1_normal:tnode;
|
||||
procedure register_created_object_types;
|
||||
function get_expect_loc: tcgloc;
|
||||
|
||||
protected
|
||||
function safe_call_self_node: tnode;
|
||||
procedure load_in_temp(var p:tnode);
|
||||
@ -124,12 +125,8 @@ interface
|
||||
to ppu, is set while processing the node). Also used on the JVM
|
||||
target for calling virtual methods, as this is name-based and not
|
||||
based on VMT entry locations }
|
||||
{$ifdef symansistr}
|
||||
fforcedprocname: TSymStr;
|
||||
{$else symansistr}
|
||||
fforcedprocname: pshortstring;
|
||||
{$endif symansistr}
|
||||
property forcedprocname: TSymStr read getforcedprocname;
|
||||
foverrideprocnamedef: tprocdef;
|
||||
property overrideprocnamedef: tprocdef read getoverrideprocnamedef;
|
||||
public
|
||||
{ the symbol containing the definition of the procedure }
|
||||
{ to call }
|
||||
@ -1656,9 +1653,6 @@ implementation
|
||||
call_vmt_node.free;
|
||||
vmt_entry.free;
|
||||
spezcontext.free;
|
||||
{$ifndef symansistr}
|
||||
stringdispose(fforcedprocname);
|
||||
{$endif symansistr}
|
||||
inherited destroy;
|
||||
end;
|
||||
|
||||
@ -1844,14 +1838,7 @@ implementation
|
||||
end
|
||||
else
|
||||
n.varargsparas:=nil;
|
||||
{$ifdef symansistr}
|
||||
n.fforcedprocname:=fforcedprocname;
|
||||
{$else symansistr}
|
||||
if assigned(fforcedprocname) then
|
||||
n.fforcedprocname:=stringdup(fforcedprocname^)
|
||||
else
|
||||
n.fforcedprocname:=nil;
|
||||
{$endif symansistr}
|
||||
n.foverrideprocnamedef:=foverrideprocnamedef;
|
||||
result:=n;
|
||||
end;
|
||||
|
||||
@ -2084,16 +2071,9 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function tcallnode.getforcedprocname: TSymStr;
|
||||
function tcallnode.getoverrideprocnamedef: tprocdef; inline;
|
||||
begin
|
||||
{$ifdef symansistr}
|
||||
result:=fforcedprocname;
|
||||
{$else}
|
||||
if assigned(fforcedprocname) then
|
||||
result:=fforcedprocname^
|
||||
else
|
||||
result:='';
|
||||
{$endif}
|
||||
result:=foverrideprocnamedef;
|
||||
end;
|
||||
|
||||
|
||||
@ -2670,7 +2650,7 @@ implementation
|
||||
vmt_def: trecorddef;
|
||||
begin
|
||||
if not assigned(right) and
|
||||
(forcedprocname='') and
|
||||
not assigned(overrideprocnamedef) and
|
||||
(po_virtualmethod in procdefinition.procoptions) and
|
||||
not is_objectpascal_helper(tprocdef(procdefinition).struct) and
|
||||
assigned(methodpointer) and
|
||||
@ -2780,11 +2760,7 @@ implementation
|
||||
(srsym.typ<>procsym) or
|
||||
(tprocsym(srsym).ProcdefList.count<>1) then
|
||||
Message1(cg_f_unknown_compilerproc,'objc.'+msgsendname);
|
||||
{$ifdef symansistr}
|
||||
fforcedprocname:=tprocdef(tprocsym(srsym).ProcdefList[0]).mangledname;
|
||||
{$else symansistr}
|
||||
fforcedprocname:=stringdup(tprocdef(tprocsym(srsym).ProcdefList[0]).mangledname);
|
||||
{$endif symansistr}
|
||||
foverrideprocnamedef:=tprocdef(tprocsym(srsym).ProcdefList[0]);
|
||||
|
||||
{ B) Handle self }
|
||||
{ 1) in case of sending a message to a superclass, self is a pointer to
|
||||
|
@ -1067,10 +1067,10 @@ implementation
|
||||
end;
|
||||
{$endif vtentry}
|
||||
|
||||
name_to_call:=forcedprocname;
|
||||
{ When methodpointer is typen we don't need (and can't) load
|
||||
a pointer. We can directly call the correct procdef (PFV) }
|
||||
if (name_to_call='') and
|
||||
name_to_call:='';
|
||||
if not assigned(overrideprocnamedef) and
|
||||
(po_virtualmethod in procdefinition.procoptions) and
|
||||
not is_objectpascal_helper(tprocdef(procdefinition).struct) and
|
||||
assigned(methodpointer) and
|
||||
@ -1164,8 +1164,13 @@ implementation
|
||||
extra_interrupt_code;
|
||||
extra_call_code;
|
||||
retloc.resetiftemp;
|
||||
if (name_to_call='') then
|
||||
name_to_call:=tprocdef(procdefinition).mangledname;
|
||||
if name_to_call='' then
|
||||
begin
|
||||
if not assigned(overrideprocnamedef) then
|
||||
name_to_call:=tprocdef(procdefinition).mangledname
|
||||
else
|
||||
name_to_call:=overrideprocnamedef.mangledname;
|
||||
end;
|
||||
if cnf_inherited in callnodeflags then
|
||||
retloc:=hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,paralocs)
|
||||
{ under certain conditions, a static call (i.e. without PIC) can be generated }
|
||||
|
Loading…
Reference in New Issue
Block a user