mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 12:19:18 +02:00
* basic llvm metadata support
git-svn-id: branches/debug_eh@41978 -
This commit is contained in:
parent
3a1fb45315
commit
3fa6838815
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -338,6 +338,7 @@ compiler/jvm/tgcpu.pas svneol=native#text/plain
|
|||||||
compiler/ldscript.pas svneol=native#text/plain
|
compiler/ldscript.pas svneol=native#text/plain
|
||||||
compiler/link.pas svneol=native#text/plain
|
compiler/link.pas svneol=native#text/plain
|
||||||
compiler/llvm/aasmllvm.pas svneol=native#text/plain
|
compiler/llvm/aasmllvm.pas svneol=native#text/plain
|
||||||
|
compiler/llvm/aasmllvmmetadata.pas svneol=native#text/plain
|
||||||
compiler/llvm/agllvm.pas svneol=native#text/plain
|
compiler/llvm/agllvm.pas svneol=native#text/plain
|
||||||
compiler/llvm/cgllvm.pas svneol=native#text/plain
|
compiler/llvm/cgllvm.pas svneol=native#text/plain
|
||||||
compiler/llvm/hlcgllvm.pas svneol=native#text/plain
|
compiler/llvm/hlcgllvm.pas svneol=native#text/plain
|
||||||
|
@ -52,7 +52,7 @@ type
|
|||||||
|
|
||||||
{ a simple data element; the value is stored as a tai }
|
{ a simple data element; the value is stored as a tai }
|
||||||
tai_simpletypedconst = class(tai_abstracttypedconst)
|
tai_simpletypedconst = class(tai_abstracttypedconst)
|
||||||
private
|
private
|
||||||
procedure setval(AValue: tai);
|
procedure setval(AValue: tai);
|
||||||
protected
|
protected
|
||||||
fval: tai;
|
fval: tai;
|
||||||
@ -90,7 +90,7 @@ type
|
|||||||
public
|
public
|
||||||
constructor create(_adetyp: ttypedconstkind; _fdef: tdef);
|
constructor create(_adetyp: ttypedconstkind; _fdef: tdef);
|
||||||
function getenumerator: tadeenumerator;
|
function getenumerator: tadeenumerator;
|
||||||
procedure addvalue(val: tai_abstracttypedconst);
|
procedure addvalue(val: tai_abstracttypedconst); virtual;
|
||||||
function valuecount: longint;
|
function valuecount: longint;
|
||||||
procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
|
procedure insertvaluebeforepos(val: tai_abstracttypedconst; pos: longint);
|
||||||
procedure replacevalueatpos(val: tai_abstracttypedconst; pos: longint);
|
procedure replacevalueatpos(val: tai_abstracttypedconst; pos: longint);
|
||||||
|
@ -87,6 +87,9 @@ interface
|
|||||||
ait_llvmins, { llvm instruction }
|
ait_llvmins, { llvm instruction }
|
||||||
ait_llvmalias, { alias for a symbol }
|
ait_llvmalias, { alias for a symbol }
|
||||||
ait_llvmdecl, { llvm symbol declaration (global/external variable, external procdef) }
|
ait_llvmdecl, { llvm symbol declaration (global/external variable, external procdef) }
|
||||||
|
ait_llvmmetadatanode, (* llvm metadata node: !id = !{type value, ...} *)
|
||||||
|
ait_llvmmetadatareftypedconst, { reference to metadata inside a metadata constant }
|
||||||
|
ait_llvmmetadatarefoperand, { llvm metadata referece: !metadataname !id }
|
||||||
{$endif}
|
{$endif}
|
||||||
{ SEH directives used in ARM,MIPS and x86_64 COFF targets }
|
{ SEH directives used in ARM,MIPS and x86_64 COFF targets }
|
||||||
ait_seh_directive,
|
ait_seh_directive,
|
||||||
@ -222,6 +225,9 @@ interface
|
|||||||
'llvmins',
|
'llvmins',
|
||||||
'llvmalias',
|
'llvmalias',
|
||||||
'llvmdecl',
|
'llvmdecl',
|
||||||
|
'llvmmetadata',
|
||||||
|
'llvmmetadatareftc',
|
||||||
|
'llvmmetadatarefop',
|
||||||
{$endif}
|
{$endif}
|
||||||
'cfi',
|
'cfi',
|
||||||
'seh_directive'
|
'seh_directive'
|
||||||
@ -323,6 +329,9 @@ interface
|
|||||||
{$endif JVM}
|
{$endif JVM}
|
||||||
{$ifdef llvm}
|
{$ifdef llvm}
|
||||||
ait_llvmdecl,
|
ait_llvmdecl,
|
||||||
|
ait_llvmmetadatanode,
|
||||||
|
ait_llvmmetadatareftypedconst,
|
||||||
|
ait_llvmmetadatarefoperand,
|
||||||
{$endif llvm}
|
{$endif llvm}
|
||||||
ait_seh_directive,
|
ait_seh_directive,
|
||||||
ait_cfi
|
ait_cfi
|
||||||
|
187
compiler/llvm/aasmllvmmetadata.pas
Normal file
187
compiler/llvm/aasmllvmmetadata.pas
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
{
|
||||||
|
Copyright (c) 2019 by Jonas Maebe,
|
||||||
|
member of the Free Pascal Compiler development team
|
||||||
|
|
||||||
|
Support for LLVM metadata
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
}
|
||||||
|
unit aasmllvmmetadata;
|
||||||
|
|
||||||
|
{$i fpcdefs.inc}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
aasmtai, aasmcnst,
|
||||||
|
symtype;
|
||||||
|
|
||||||
|
type
|
||||||
|
tspecialisedmetadatanodekind = (
|
||||||
|
smeta_DIFile,
|
||||||
|
smeta_DIBasicType,
|
||||||
|
smeta_DISubroutineType,
|
||||||
|
smeta_DIDerivedType,
|
||||||
|
smeta_DICompositeType,
|
||||||
|
smeta_DISubrange,
|
||||||
|
smeta_DIEnumerator,
|
||||||
|
smeta_DITemplateTypeParameter,
|
||||||
|
smeta_DITemplateValueParameter,
|
||||||
|
smeta_DINamespace,
|
||||||
|
smeta_DIGlobalVariable,
|
||||||
|
smeta_DISubprogram,
|
||||||
|
smeta_DILexicalBlock,
|
||||||
|
smeta_DILexicalBlockFile,
|
||||||
|
smeta_DILocation,
|
||||||
|
smeta_DILocalVariable,
|
||||||
|
smeta_DIExpression,
|
||||||
|
smeta_DIObjCProperty,
|
||||||
|
smeta_DIImportedEntity,
|
||||||
|
smeta_DIMacro,
|
||||||
|
smeta_DIMacroFile
|
||||||
|
);
|
||||||
|
|
||||||
|
tai_llvmbasemetadatanode = class abstract(tai_aggregatetypedconst)
|
||||||
|
strict protected
|
||||||
|
function getname: ansistring; virtual; abstract;
|
||||||
|
public
|
||||||
|
procedure addvalue(val: tai_abstracttypedconst); override;
|
||||||
|
property name: ansistring read getname;
|
||||||
|
constructor create; reintroduce;
|
||||||
|
end;
|
||||||
|
|
||||||
|
(* !0 = !{ type1 value1, ... } *)
|
||||||
|
tai_llvmunnamedmetadatanode = class(tai_llvmbasemetadatanode)
|
||||||
|
strict private class var
|
||||||
|
snextid: cardinal;
|
||||||
|
class function getnextid: cardinal;
|
||||||
|
strict protected
|
||||||
|
fnameval: cardinal;
|
||||||
|
public
|
||||||
|
constructor create; reintroduce;
|
||||||
|
function getname: ansistring; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
(* !name = !{ type1 value1, ... } *)
|
||||||
|
tai_llvmnamedmetadatanode = class(tai_llvmbasemetadatanode)
|
||||||
|
strict protected
|
||||||
|
fname: ansistring;
|
||||||
|
function getname: ansistring; override;
|
||||||
|
public
|
||||||
|
constructor create(const aName: ansistring);
|
||||||
|
end;
|
||||||
|
|
||||||
|
tai_llvmmetadatareftypedconst = class(tai_simple)
|
||||||
|
strict private
|
||||||
|
fval: tai_llvmbasemetadatanode;
|
||||||
|
public
|
||||||
|
constructor create(_val: tai_llvmbasemetadatanode);
|
||||||
|
property val: tai_llvmbasemetadatanode read fval;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ @g1 = global i32 0, *!id !value.name* }
|
||||||
|
tai_llvmmetadatareferenceoperand = class(tai_simple)
|
||||||
|
strict private
|
||||||
|
fid: ansistring;
|
||||||
|
fvalue: tai_llvmbasemetadatanode;
|
||||||
|
public
|
||||||
|
constructor create(const anID: ansistring; aValue: tai_llvmbasemetadatanode);
|
||||||
|
property id: ansistring read fid;
|
||||||
|
property value: tai_llvmbasemetadatanode read fvalue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ !name = !kindname(field1: value1, ...) }
|
||||||
|
tai_llvmspecialisedmetadatanode = class(tai_llvmunnamedmetadatanode)
|
||||||
|
{ identifies name and fieldnames }
|
||||||
|
kind: tspecialisedmetadatanodekind;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
symdef;
|
||||||
|
|
||||||
|
function llvm_getmetadatareftypedconst(metadata: tai_llvmbasemetadatanode): tai_simpletypedconst;
|
||||||
|
begin
|
||||||
|
result:=tai_simpletypedconst.create(llvm_metadatatype, tai_llvmmetadatareftypedconst.create(metadata));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure tai_llvmbasemetadatanode.addvalue(val: tai_abstracttypedconst);
|
||||||
|
begin
|
||||||
|
{ bypass string merging attempts, as we add tai_strings directly here }
|
||||||
|
fvalues.add(val);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor tai_llvmbasemetadatanode.create;
|
||||||
|
begin
|
||||||
|
inherited create(tck_array, llvm_metadatatype);
|
||||||
|
typ:=ait_llvmmetadatanode;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class function tai_llvmunnamedmetadatanode.getnextid: cardinal;
|
||||||
|
begin
|
||||||
|
result:=snextid;
|
||||||
|
inc(snextid);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tai_llvmunnamedmetadatanode.getname: ansistring;
|
||||||
|
begin
|
||||||
|
str(fnameval,result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor tai_llvmunnamedmetadatanode.create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
fnameval:=getnextid;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tai_llvmnamedmetadatanode.getname: ansistring;
|
||||||
|
begin
|
||||||
|
result:=fname;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor tai_llvmnamedmetadatanode.create(const aName: ansistring);
|
||||||
|
begin
|
||||||
|
inherited create;
|
||||||
|
fname:=aName;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor tai_llvmmetadatareftypedconst.create(_val: tai_llvmbasemetadatanode);
|
||||||
|
begin
|
||||||
|
inherited create(ait_llvmmetadatareftypedconst);
|
||||||
|
fval:=_val;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
constructor tai_llvmmetadatareferenceoperand.create(const anID: ansistring; aValue: tai_llvmbasemetadatanode);
|
||||||
|
begin
|
||||||
|
inherited create(ait_llvmmetadatarefoperand);
|
||||||
|
fid:=anID;
|
||||||
|
fvalue:=aValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -30,7 +30,7 @@ interface
|
|||||||
globtype,globals,systems,
|
globtype,globals,systems,
|
||||||
aasmbase,aasmtai,aasmdata,
|
aasmbase,aasmtai,aasmdata,
|
||||||
assemble,
|
assemble,
|
||||||
aasmllvm;
|
aasmllvm, aasmllvmmetadata;
|
||||||
|
|
||||||
type
|
type
|
||||||
TLLVMInstrWriter = class;
|
TLLVMInstrWriter = class;
|
||||||
@ -61,7 +61,7 @@ interface
|
|||||||
procedure WriteDirectiveName(dir: TAsmDirective); virtual;
|
procedure WriteDirectiveName(dir: TAsmDirective); virtual;
|
||||||
procedure WriteRealConst(hp: tai_realconst; do_line: boolean);
|
procedure WriteRealConst(hp: tai_realconst; do_line: boolean);
|
||||||
procedure WriteOrdConst(hp: tai_const);
|
procedure WriteOrdConst(hp: tai_const);
|
||||||
procedure WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
|
procedure WriteTai(const replaceforbidden: boolean; const do_line, inmetadata: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
|
||||||
public
|
public
|
||||||
constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
|
constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
|
||||||
procedure WriteTree(p:TAsmList);override;
|
procedure WriteTree(p:TAsmList);override;
|
||||||
@ -376,7 +376,7 @@ implementation
|
|||||||
hp:=para^.ai;
|
hp:=para^.ai;
|
||||||
owner.writer.AsmWrite(fstr);
|
owner.writer.AsmWrite(fstr);
|
||||||
fstr:='';
|
fstr:='';
|
||||||
owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
|
owner.WriteTai(false,false,para^.def=llvm_metadatatype,tmpinline,tmpasmblock,hp);
|
||||||
end;
|
end;
|
||||||
{ empty records }
|
{ empty records }
|
||||||
top_undef:
|
top_undef:
|
||||||
@ -436,7 +436,6 @@ implementation
|
|||||||
|
|
||||||
function TLLVMInstrWriter.getopstr(const o:toper; refwithalign: boolean) : TSymStr;
|
function TLLVMInstrWriter.getopstr(const o:toper; refwithalign: boolean) : TSymStr;
|
||||||
var
|
var
|
||||||
hs : ansistring;
|
|
||||||
hp: tai;
|
hp: tai;
|
||||||
tmpinline: cardinal;
|
tmpinline: cardinal;
|
||||||
tmpasmblock: boolean;
|
tmpasmblock: boolean;
|
||||||
@ -499,7 +498,7 @@ implementation
|
|||||||
hp:=o.ai;
|
hp:=o.ai;
|
||||||
owner.writer.AsmWrite(fstr);
|
owner.writer.AsmWrite(fstr);
|
||||||
fstr:='';
|
fstr:='';
|
||||||
owner.WriteTai(false,false,tmpinline,tmpasmblock,hp);
|
owner.WriteTai(false,false,false,tmpinline,tmpasmblock,hp);
|
||||||
end;
|
end;
|
||||||
result:='';
|
result:='';
|
||||||
end;
|
end;
|
||||||
@ -838,7 +837,7 @@ implementation
|
|||||||
WriteSourceLine(hp as tailineinfo);
|
WriteSourceLine(hp as tailineinfo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
WriteTai(replaceforbidden, do_line, InlineLevel, asmblock, hp);
|
WriteTai(replaceforbidden, do_line, false, InlineLevel, asmblock, hp);
|
||||||
hp:=tai(hp.next);
|
hp:=tai(hp.next);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -971,7 +970,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TLLVMAssember.WriteTai(const replaceforbidden: boolean; const do_line: boolean; var InlineLevel: cardinal; var asmblock: boolean; var hp: tai);
|
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);
|
||||||
begin
|
begin
|
||||||
@ -1021,20 +1020,34 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure WriteTypedConstData(hp: tai_abstracttypedconst);
|
procedure WriteTypedConstData(hp: tai_abstracttypedconst; metadata: boolean);
|
||||||
var
|
var
|
||||||
p: tai_abstracttypedconst;
|
p: tai_abstracttypedconst;
|
||||||
pval: tai;
|
pval: tai;
|
||||||
defstr: TSymStr;
|
defstr: TSymStr;
|
||||||
first, gotstring: boolean;
|
first, gotstring: boolean;
|
||||||
begin
|
begin
|
||||||
defstr:=llvmencodetypename(hp.def);
|
if hp.def<>llvm_metadatatype then
|
||||||
|
begin
|
||||||
|
defstr:=llvmencodetypename(hp.def)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
defstr:=''
|
||||||
|
end;
|
||||||
{ write the struct, array or simple type }
|
{ write the struct, array or simple type }
|
||||||
case hp.adetyp of
|
case hp.adetyp of
|
||||||
tck_record:
|
tck_record:
|
||||||
begin
|
begin
|
||||||
writer.AsmWrite(defstr);
|
if not(metadata) then
|
||||||
writer.AsmWrite(' <{');
|
begin
|
||||||
|
writer.AsmWrite(defstr);
|
||||||
|
writer.AsmWrite(' <{');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
writer.AsmWrite(' !{');
|
||||||
|
end;
|
||||||
first:=true;
|
first:=true;
|
||||||
for p in tai_aggregatetypedconst(hp) do
|
for p in tai_aggregatetypedconst(hp) do
|
||||||
begin
|
begin
|
||||||
@ -1042,19 +1055,29 @@ implementation
|
|||||||
writer.AsmWrite(', ')
|
writer.AsmWrite(', ')
|
||||||
else
|
else
|
||||||
first:=false;
|
first:=false;
|
||||||
WriteTypedConstData(p);
|
WriteTypedConstData(p,metadata);
|
||||||
|
end;
|
||||||
|
if not(metadata) then
|
||||||
|
begin
|
||||||
|
writer.AsmWrite('}>');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
writer.AsmWrite('}');
|
||||||
end;
|
end;
|
||||||
writer.AsmWrite('}>');
|
|
||||||
end;
|
end;
|
||||||
tck_array:
|
tck_array:
|
||||||
begin
|
begin
|
||||||
writer.AsmWrite(defstr);
|
if not(metadata) then
|
||||||
|
begin
|
||||||
|
writer.AsmWrite(defstr);
|
||||||
|
end;
|
||||||
first:=true;
|
first:=true;
|
||||||
gotstring:=false;
|
gotstring:=false;
|
||||||
for p in tai_aggregatetypedconst(hp) do
|
for p in tai_aggregatetypedconst(hp) do
|
||||||
begin
|
begin
|
||||||
if not first then
|
if not first then
|
||||||
writer.AsmWrite(',')
|
writer.AsmWrite(', ')
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
writer.AsmWrite(' ');
|
writer.AsmWrite(' ');
|
||||||
@ -1065,33 +1088,65 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
writer.AsmWrite('[');
|
if not metadata then
|
||||||
|
begin
|
||||||
|
writer.AsmWrite('[');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
writer.AsmWrite('!{');
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
first:=false;
|
first:=false;
|
||||||
end;
|
end;
|
||||||
{ cannot concat strings and other things }
|
{ cannot concat strings and other things }
|
||||||
if gotstring and
|
if gotstring and
|
||||||
|
not metadata and
|
||||||
((tai_abstracttypedconst(p).adetyp<>tck_simple) or
|
((tai_abstracttypedconst(p).adetyp<>tck_simple) or
|
||||||
(tai_simpletypedconst(p).val.typ<>ait_string)) then
|
(tai_simpletypedconst(p).val.typ<>ait_string)) then
|
||||||
internalerror(2014062701);
|
internalerror(2014062701);
|
||||||
WriteTypedConstData(p);
|
WriteTypedConstData(p,metadata);
|
||||||
end;
|
end;
|
||||||
if not gotstring then
|
if not gotstring then
|
||||||
writer.AsmWrite(']');
|
begin
|
||||||
|
if not metadata then
|
||||||
|
begin
|
||||||
|
writer.AsmWrite(']');
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
writer.AsmWrite('}');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
tck_simple:
|
tck_simple:
|
||||||
begin
|
begin
|
||||||
pval:=tai_simpletypedconst(hp).val;
|
pval:=tai_simpletypedconst(hp).val;
|
||||||
if pval.typ<>ait_string then
|
if (pval.typ<>ait_string) and
|
||||||
|
(defstr<>'') then
|
||||||
begin
|
begin
|
||||||
writer.AsmWrite(defstr);
|
writer.AsmWrite(defstr);
|
||||||
writer.AsmWrite(' ');
|
writer.AsmWrite(' ');
|
||||||
end;
|
end;
|
||||||
WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,pval);
|
WriteTai(replaceforbidden,do_line,metadata,InlineLevel,asmblock,pval);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure WriteLlvmMetadataNode(hp: tai_llvmbasemetadatanode);
|
||||||
|
begin
|
||||||
|
{ must only appear at the top level }
|
||||||
|
if fdecllevel<>0 then
|
||||||
|
internalerror(2019050111);
|
||||||
|
writer.AsmWrite('!');
|
||||||
|
writer.AsmWrite(tai_llvmbasemetadatanode(hp).name);
|
||||||
|
writer.AsmWrite(' =');
|
||||||
|
inc(fdecllevel);
|
||||||
|
WriteTypedConstData(hp,true);
|
||||||
|
writer.AsmLn;
|
||||||
|
dec(fdecllevel);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
hp2: tai;
|
hp2: tai;
|
||||||
s: string;
|
s: string;
|
||||||
@ -1162,7 +1217,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if fdecllevel=0 then
|
if fdecllevel=0 then
|
||||||
internalerror(2016120201);
|
internalerror(2016120201);
|
||||||
writer.AsmWrite('c"');
|
if not inmetadata then
|
||||||
|
writer.AsmWrite('c"')
|
||||||
|
else
|
||||||
|
writer.AsmWrite('!"');
|
||||||
for i:=1 to tai_string(hp).len do
|
for i:=1 to tai_string(hp).len do
|
||||||
begin
|
begin
|
||||||
ch:=tai_string(hp).str[i-1];
|
ch:=tai_string(hp).str[i-1];
|
||||||
@ -1278,7 +1336,7 @@ implementation
|
|||||||
hp2:=tai(taillvmdecl(hp).initdata.first);
|
hp2:=tai(taillvmdecl(hp).initdata.first);
|
||||||
while assigned(hp2) do
|
while assigned(hp2) do
|
||||||
begin
|
begin
|
||||||
WriteTai(replaceforbidden,do_line,InlineLevel,asmblock,hp2);
|
WriteTai(replaceforbidden,do_line,inmetadata,InlineLevel,asmblock,hp2);
|
||||||
hp2:=tai(hp2.next);
|
hp2:=tai(hp2.next);
|
||||||
end;
|
end;
|
||||||
dec(fdecllevel);
|
dec(fdecllevel);
|
||||||
@ -1328,6 +1386,28 @@ implementation
|
|||||||
writer.AsmWrite('* ');
|
writer.AsmWrite('* ');
|
||||||
writer.AsmWriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
|
writer.AsmWriteln(LlvmAsmSymName(taillvmalias(hp).oldsym));
|
||||||
end;
|
end;
|
||||||
|
ait_llvmmetadatanode:
|
||||||
|
begin
|
||||||
|
WriteLlvmMetadataNode(tai_llvmbasemetadatanode(hp));
|
||||||
|
end;
|
||||||
|
ait_llvmmetadatareftypedconst:
|
||||||
|
begin
|
||||||
|
{ must only appear as an element in a typed const }
|
||||||
|
if fdecllevel=0 then
|
||||||
|
internalerror(2019050110);
|
||||||
|
writer.AsmWrite('!');
|
||||||
|
writer.AsmWrite(tai_llvmbasemetadatanode(tai_llvmmetadatareftypedconst(hp).val).name);
|
||||||
|
end;
|
||||||
|
ait_llvmmetadatarefoperand:
|
||||||
|
begin
|
||||||
|
{ must only appear as an operand }
|
||||||
|
if fdecllevel=0 then
|
||||||
|
internalerror(2019050110);
|
||||||
|
writer.AsmWrite('!');
|
||||||
|
writer.AsmWrite(tai_llvmmetadatareferenceoperand(hp).id);
|
||||||
|
writer.AsmWrite(' !');
|
||||||
|
writer.AsmWrite(tai_llvmmetadatareferenceoperand(hp).value.name);
|
||||||
|
end;
|
||||||
ait_symbolpair:
|
ait_symbolpair:
|
||||||
begin
|
begin
|
||||||
{ should be emitted as part of the symbol def }
|
{ should be emitted as part of the symbol def }
|
||||||
@ -1411,7 +1491,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
ait_typedconst:
|
ait_typedconst:
|
||||||
begin
|
begin
|
||||||
WriteTypedConstData(tai_abstracttypedconst(hp));
|
WriteTypedConstData(tai_abstracttypedconst(hp),false);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
internalerror(2019012010);
|
internalerror(2019012010);
|
||||||
@ -1435,7 +1515,6 @@ implementation
|
|||||||
procedure TLLVMAssember.WriteAsmList;
|
procedure TLLVMAssember.WriteAsmList;
|
||||||
var
|
var
|
||||||
hal : tasmlisttype;
|
hal : tasmlisttype;
|
||||||
i: longint;
|
|
||||||
a: TExternalAssembler;
|
a: TExternalAssembler;
|
||||||
decorator: TLLVMModuleInlineAssemblyDecorator;
|
decorator: TLLVMModuleInlineAssemblyDecorator;
|
||||||
begin
|
begin
|
||||||
|
@ -191,6 +191,9 @@ implementation
|
|||||||
if def.stab_number<>0 then
|
if def.stab_number<>0 then
|
||||||
exit;
|
exit;
|
||||||
def.stab_number:=1;
|
def.stab_number:=1;
|
||||||
|
{ this is an internal llvm type }
|
||||||
|
if def=llvm_metadatatype then
|
||||||
|
exit;
|
||||||
if def.dbg_state=dbg_state_unused then
|
if def.dbg_state=dbg_state_unused then
|
||||||
begin
|
begin
|
||||||
def.dbg_state:=dbg_state_used;
|
def.dbg_state:=dbg_state_used;
|
||||||
|
@ -619,6 +619,11 @@ implementation
|
|||||||
addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[],true));
|
addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[],true));
|
||||||
nestedprocpointertype:=crecorddef.create('',hrecst);
|
nestedprocpointertype:=crecorddef.create('',hrecst);
|
||||||
addtype('$nestedprocpointer',nestedprocpointertype);
|
addtype('$nestedprocpointer',nestedprocpointertype);
|
||||||
|
{$ifdef llvm}
|
||||||
|
llvm_metadatatype:=cpointerdef.create(voidtype);
|
||||||
|
{ if this gets renamed, also adjust agllvm so it still writes the identifier of this type as "metadata" }
|
||||||
|
addtype('$metadata',llvm_metadatatype);
|
||||||
|
{$endif}
|
||||||
symtablestack.pop(systemunit);
|
symtablestack.pop(systemunit);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -734,6 +739,9 @@ implementation
|
|||||||
end;
|
end;
|
||||||
loadtype('methodpointer',methodpointertype);
|
loadtype('methodpointer',methodpointertype);
|
||||||
loadtype('nestedprocpointer',nestedprocpointertype);
|
loadtype('nestedprocpointer',nestedprocpointertype);
|
||||||
|
{$ifdef llvm}
|
||||||
|
loadtype('metadata',llvm_metadatatype);
|
||||||
|
{$endif}
|
||||||
loadtype('HRESULT',hresultdef);
|
loadtype('HRESULT',hresultdef);
|
||||||
loadtype('TTYPEKIND',typekindtype);
|
loadtype('TTYPEKIND',typekindtype);
|
||||||
set_default_int_types;
|
set_default_int_types;
|
||||||
|
@ -1150,6 +1150,12 @@ interface
|
|||||||
objc_fastenumeration : tobjectdef;
|
objc_fastenumeration : tobjectdef;
|
||||||
objc_fastenumerationstate : trecorddef;
|
objc_fastenumerationstate : trecorddef;
|
||||||
|
|
||||||
|
{$ifdef llvm}
|
||||||
|
{ llvm types }
|
||||||
|
{ a unique def to identify any kind of metadata }
|
||||||
|
llvm_metadatatype : tdef;
|
||||||
|
{$endif llvm}
|
||||||
|
|
||||||
{ Java base types }
|
{ Java base types }
|
||||||
{ java.lang.Object }
|
{ java.lang.Object }
|
||||||
java_jlobject : tobjectdef;
|
java_jlobject : tobjectdef;
|
||||||
|
Loading…
Reference in New Issue
Block a user