* support taking the address of labels defined in assembler blocks in the

LLVM code genrator (for the rtti unit's thunk hacking)

git-svn-id: trunk@42969 -
This commit is contained in:
Jonas Maebe 2019-09-09 18:33:33 +00:00
parent cbe47848c2
commit dcf4e4cb2c
4 changed files with 33 additions and 12 deletions

View File

@ -224,6 +224,7 @@ interface
labeltype : TAsmLabelType;
is_set : boolean;
is_public : boolean;
defined_in_asmstatement : boolean;
constructor Createlocal(AList: TFPHashObjectList; nr: longint; ltyp: TAsmLabelType);
constructor Createstatic(AList: TFPHashObjectList; nr: longint; ltyp: TAsmLabelType);
constructor Createglobal(AList: TFPHashObjectList; const modulename: TSymStr; nr: longint; ltyp: TAsmLabelType);

View File

@ -973,8 +973,15 @@ implementation
procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line, inmetadata: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
procedure WriteLinkageVibilityFlags(bind: TAsmSymBind);
procedure WriteLinkageVibilityFlags(bind: TAsmSymBind; is_definition: boolean);
begin
{ re-declaration of a symbol defined in the current module (in an
assembler block) }
if not is_definition then
begin
writer.AsmWrite(' external');
exit;
end;
case bind of
AB_EXTERNAL,
AB_EXTERNAL_INDIRECT:
@ -1297,7 +1304,7 @@ implementation
writer.AsmWrite('define');
if ldf_weak in taillvmdecl(hp).flags then
writer.AsmWrite(' weak');
WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind);
WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind, true);
writer.AsmWrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def), '', lpd_def));
WriteFunctionFlags(tprocdef(taillvmdecl(hp).def));
if assigned(tprocdef(taillvmdecl(hp).def).personality) then
@ -1319,7 +1326,7 @@ implementation
writer.AsmWrite(' weak');
if ldf_appending in taillvmdecl(hp).flags then
writer.AsmWrite(' appending');
WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind);
WriteLinkageVibilityFlags(taillvmdecl(hp).namesym.bind, ldf_definition in taillvmdecl(hp).flags);
writer.AsmWrite(' ');
if (ldf_tls in taillvmdecl(hp).flags) then
writer.AsmWrite('thread_local ');
@ -1332,7 +1339,7 @@ implementation
if not assigned(taillvmdecl(hp).initdata) then
begin
writer.AsmWrite(llvmencodetypename(taillvmdecl(hp).def));
if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL, AB_WEAK_EXTERNAL,AB_EXTERNAL_INDIRECT]) then
if ldf_definition in taillvmdecl(hp).flags then
writer.AsmWrite(' zeroinitializer');
end
else
@ -1384,7 +1391,7 @@ implementation
begin
writer.AsmWrite(LlvmAsmSymName(taillvmalias(hp).newsym));
writer.AsmWrite(' = alias ');
WriteLinkageVibilityFlags(taillvmalias(hp).bind);
WriteLinkageVibilityFlags(taillvmalias(hp).bind, true);
if taillvmalias(hp).def.typ=procdef then
sstr:=llvmencodeproctype(tabstractprocdef(taillvmalias(hp).def), '', lpd_alias)
else

View File

@ -794,12 +794,24 @@ implementation
firstop,
secondop: tllvmop;
begin
ai:=taillvm.blockaddress(voidcodepointertype,
current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION),
current_asmdata.RefAsmSymbol(l.mangledname,AT_LABEL)
);
emit_tai(ai,voidcodepointertype);
fqueue_offset:=low(fqueue_offset);
if not assigned(l.asmblocklabel) or
not l.asmblocklabel.defined_in_asmstatement then
begin
ai:=taillvm.blockaddress(voidcodepointertype,
current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION),
current_asmdata.RefAsmSymbol(l.mangledname,AT_LABEL)
);
emit_tai(ai,voidcodepointertype);
fqueue_offset:=low(fqueue_offset);
end
else
begin
{ we've already incorporated the offset via the inserted operations above,
make sure it doesn't get emitted again as part of the tai_const for
the tasmsymbol }
fqueue_offset:=0;
inherited;
end;
end;

View File

@ -1754,7 +1754,8 @@ Begin
begin
if tlabelsym(sym).defined then
Message(sym_e_label_already_defined);
tlabelsym(sym).defined:=true
tlabelsym(sym).defined:=true;
hl.defined_in_asmstatement:=true
end
else
tlabelsym(sym).used:=true;