LLVM debug info: LLVM 7.0 support

Also defined some llvm flags in a negative way so they can be removed from
later versions rather than added
This commit is contained in:
Jonas Maebe 2022-05-11 22:38:23 +02:00
parent edbddec98a
commit fd125b506e
2 changed files with 56 additions and 31 deletions

View File

@ -1188,45 +1188,73 @@ implementation
procedure TDebugInfoLLVM.appendprocdef(list:TAsmList; def:tprocdef); procedure TDebugInfoLLVM.appendprocdef(list:TAsmList; def:tprocdef);
function getdispflags(is_definition, is_virtual: boolean): TSymStr; procedure adddispflags(dinode: tai_llvmspecialisedmetadatanode; is_definition, is_virtual: boolean);
var
dispflags: TSymStr;
begin begin
result:=''; if llvmflag_NoDISPFlags in llvmversion_properties[current_settings.llvmversion] then
begin
dinode.addboolean('isDefinition',is_definition);
if is_definition then
begin
dinode.addboolean('isLocal: ',
not((po_global in def.procoptions) and
(def.parast.symtablelevel<=normal_function_level))
);
end;
if is_virtual then
begin
if not(po_abstractmethod in def.procoptions) then
dinode.addenum('virtuality','DW_VIRTUALITY_virtual')
else
dinode.addenum('virtuality','DW_VIRTUALITY_pure_virtual');
end;
exit;
end;
dispflags:='';
if is_definition then if is_definition then
begin begin
result:='DISPFlagDefinition'; dispflags:='DISPFlagDefinition';
if not((po_global in def.procoptions) and if not((po_global in def.procoptions) and
(def.parast.symtablelevel<=normal_function_level)) then (def.parast.symtablelevel<=normal_function_level)) then
result:=result+'|DISPFlagLocalToUnit'; dispflags:=dispflags+'|DISPFlagLocalToUnit';
end; end;
if is_virtual then if is_virtual then
begin begin
if result<>'' then if dispflags<>'' then
result:=result+'|'; dispflags:=dispflags+'|';
if not(po_abstractmethod in def.procoptions) then if not(po_abstractmethod in def.procoptions) then
result:=result+'DISPFlagVirtual' dispflags:=dispflags+'DISPFlagVirtual'
else else
result:=result+'DISPFlagPureVirtual'; dispflags:=dispflags+'DISPFlagPureVirtual';
end end
else else
begin begin
{ this one will always be a definition, so no need to check { this one will always be a definition, so no need to check
whether result is empty } whether result is empty }
if (llvmflag_DISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and if not(llvmflag_NoDISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and
(def.proctypeoption=potype_proginit) then (def.proctypeoption=potype_proginit) then
result:=result+'|DISPFlagMainSubprogram'; dispflags:=dispflags+'|DISPFlagMainSubprogram';
end; end;
if dispflags<>'' then
dinode.addenum('spFlags',dispflags);
end; end;
function getdiflags(is_definition: boolean): TSymStr; procedure adddiflags(dinode: tai_llvmspecialisedmetadatanode; is_definition: boolean);
var
diflags: TSymStr;
begin begin
if not(llvmflag_DISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and if (llvmflag_NoDISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and
(def.proctypeoption=potype_proginit) then (def.proctypeoption=potype_proginit) then
result:='DIFlagMainSubprogram' diflags:='DIFlagMainSubprogram'
else if def.owner.symtabletype in [objectsymtable,recordsymtable] then else if def.owner.symtabletype in [objectsymtable,recordsymtable] then
result:=visibilitydiflag(def.visibility) diflags:=visibilitydiflag(def.visibility)
else else
result:=''; diflags:='';
if diflags<>'' then
dinode.addenum('flags',diflags);
end; end;
var var
@ -1303,9 +1331,7 @@ implementation
(([po_abstractmethod, po_virtualmethod, po_overridingmethod]*def.procoptions)<>[]) and (([po_abstractmethod, po_virtualmethod, po_overridingmethod]*def.procoptions)<>[]) and
not is_objc_class_or_protocol(def.struct) and not is_objc_class_or_protocol(def.struct) and
not is_objectpascal_helper(def.struct); not is_objectpascal_helper(def.struct);
flags:=getdispflags(in_currentunit,is_virtual); adddispflags(dinode,in_currentunit,is_virtual);
if flags<>'' then
dinode.addenum('spFlags',flags);
if is_virtual then if is_virtual then
begin begin
{ the sizeof(pint) is a bit iffy, since vmtmethodoffset() calculates { the sizeof(pint) is a bit iffy, since vmtmethodoffset() calculates
@ -1317,9 +1343,7 @@ implementation
internalerror(2022043001); internalerror(2022043001);
{$endif} {$endif}
end; end;
flags:=getdiflags(in_currentunit); adddiflags(dinode,in_currentunit);
if flags<>'' then
dinode.addenum('flags',flags);
dinode.addmetadatarefto('unit',fcunode); dinode.addmetadatarefto('unit',fcunode);
ditypenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubroutineType); ditypenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubroutineType);

View File

@ -56,7 +56,8 @@ type
llvmflag_generic_constrained_si64tofp, { supports sitofp for 64 bit signed integers on all targets } llvmflag_generic_constrained_si64tofp, { supports sitofp for 64 bit signed integers on all targets }
llvmflag_null_pointer_valid_new, { new syntax for the null pointer valid attribute: null_pointer_is_valid } llvmflag_null_pointer_valid_new, { new syntax for the null pointer valid attribute: null_pointer_is_valid }
llvmflag_array_datalocation, { arrays debug info supports a dataLocation attribute to specify how to obtain the array data based on the array variable } llvmflag_array_datalocation, { arrays debug info supports a dataLocation attribute to specify how to obtain the array data based on the array variable }
llvmflag_DISPFlagMainSubprogram { MainSubprogram got moved from DIFlags to DISPFlags } llvmflag_NoDISPFlags, { no DI sub program flags, but separate fields }
llvmflag_NoDISPFlagMainSubprogram { MainSubprogram still in DIFlags instead of DISPFlags }
); );
tllvmversionflags = set of tllvmversionflag; tllvmversionflags = set of tllvmversionflag;
@ -90,15 +91,15 @@ Const
llvmversion_properties: array[tllvmversion] of tllvmversionflags = llvmversion_properties: array[tllvmversion] of tllvmversionflags =
( (
{ invalid } [], { invalid } [],
{ llvmver_xc_10_0 } [], { llvmver_xc_10_0 } [llvmflag_NoDISPFlags],
{ llvmver_xc_10_1 } [], { llvmver_xc_10_1 } [llvmflag_NoDISPFlags],
{ llvmver_7_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_7_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlags],
{ llvmver_7_1 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_7_1 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlags],
{ llvmver_8_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_8_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlagMainSubprogram],
{ llvmver_xc_11 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_xc_11 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_NoDISPFlagMainSubprogram],
{ llvmver_9_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_DISPFlagMainSubprogram], { llvmver_9_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext],
{ llvmver_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp,llvmflag_DISPFlagMainSubprogram], { llvmver_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp],
{ llvmver_11_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid_new,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp,llvmflag_array_datalocation,llvmflag_DISPFlagMainSubprogram] { llvmver_11_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid_new,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp,llvmflag_array_datalocation]
); );
{ Supported optimizations, only used for information } { Supported optimizations, only used for information }