mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 20:26:00 +02:00
* several fixes for emitting aggregate typed constants with C/ABI packing:
o don't emit explicit padding bytes (LLVM adds them) o don't mark them in LLVM as packed either git-svn-id: trunk@31187 -
This commit is contained in:
parent
4edb6e68fd
commit
7a8b5fd6c5
@ -153,7 +153,7 @@ type
|
|||||||
constructor create(_def: tdef; _typ: ttypedconstkind); virtual;
|
constructor create(_def: tdef; _typ: ttypedconstkind); virtual;
|
||||||
{ calculated padding bytes for alignment if needed, and add the def of the
|
{ calculated padding bytes for alignment if needed, and add the def of the
|
||||||
next field in case we are constructing an anonymous record }
|
next field in case we are constructing an anonymous record }
|
||||||
function prepare_next_field(nextfielddef: tdef): asizeint;
|
function prepare_next_field(nextfielddef: tdef): asizeint; virtual;
|
||||||
|
|
||||||
property def: tdef read fdef;
|
property def: tdef read fdef;
|
||||||
property typ: ttypedconstkind read ftyp;
|
property typ: ttypedconstkind read ftyp;
|
||||||
@ -269,6 +269,7 @@ type
|
|||||||
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
|
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
procedure maybe_emit_tail_padding(def: tdef); virtual;
|
||||||
function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel):tasmlabofs;
|
function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel):tasmlabofs;
|
||||||
procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
|
procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
|
||||||
procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
|
procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
|
||||||
@ -1009,6 +1010,30 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure ttai_typedconstbuilder.maybe_emit_tail_padding(def: tdef);
|
||||||
|
var
|
||||||
|
info: taggregateinformation;
|
||||||
|
fillbytes: asizeint;
|
||||||
|
begin
|
||||||
|
info:=curagginfo;
|
||||||
|
if not assigned(info) then
|
||||||
|
internalerror(2014091002);
|
||||||
|
if def<>info.def then
|
||||||
|
internalerror(2014091205);
|
||||||
|
if (is_record(def) or
|
||||||
|
is_object(def)) and
|
||||||
|
not is_packed_record_or_object(def) then
|
||||||
|
begin
|
||||||
|
fillbytes:=def.size-info.curoffset;
|
||||||
|
while fillbytes>0 do
|
||||||
|
begin
|
||||||
|
do_emit_tai(Tai_const.Create_8bit(0),u8inttype);
|
||||||
|
dec(fillbytes)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel): tasmlabofs;
|
function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel): tasmlabofs;
|
||||||
var
|
var
|
||||||
string_symofs: asizeint;
|
string_symofs: asizeint;
|
||||||
@ -1102,30 +1127,15 @@ implementation
|
|||||||
procedure ttai_typedconstbuilder.end_aggregate_internal(def: tdef; anonymous: boolean);
|
procedure ttai_typedconstbuilder.end_aggregate_internal(def: tdef; anonymous: boolean);
|
||||||
var
|
var
|
||||||
info: taggregateinformation;
|
info: taggregateinformation;
|
||||||
fillbytes: asizeint;
|
|
||||||
tck: ttypedconstkind;
|
tck: ttypedconstkind;
|
||||||
begin
|
begin
|
||||||
tck:=aggregate_kind(def);
|
tck:=aggregate_kind(def);
|
||||||
if tck=tck_simple then
|
if tck=tck_simple then
|
||||||
exit;
|
exit;
|
||||||
info:=curagginfo;
|
|
||||||
if not assigned(info) then
|
|
||||||
internalerror(2014091002);
|
|
||||||
if def<>info.def then
|
|
||||||
internalerror(2014091205);
|
|
||||||
{ add tail padding if necessary }
|
{ add tail padding if necessary }
|
||||||
if (is_record(def) or
|
maybe_emit_tail_padding(def);
|
||||||
is_object(def)) and
|
|
||||||
not is_packed_record_or_object(def) then
|
|
||||||
begin
|
|
||||||
fillbytes:=def.size-info.curoffset;
|
|
||||||
while fillbytes>0 do
|
|
||||||
begin
|
|
||||||
do_emit_tai(Tai_const.Create_8bit(0),u8inttype);
|
|
||||||
dec(fillbytes)
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{ pop and free the information }
|
{ pop and free the information }
|
||||||
|
info:=curagginfo;
|
||||||
faggregateinformation.count:=faggregateinformation.count-1;
|
faggregateinformation.count:=faggregateinformation.count-1;
|
||||||
info.free;
|
info.free;
|
||||||
end;
|
end;
|
||||||
|
@ -81,7 +81,7 @@ implementation
|
|||||||
SysUtils,
|
SysUtils,
|
||||||
cutils,cfileutl,systems,
|
cutils,cfileutl,systems,
|
||||||
fmodule,verbose,
|
fmodule,verbose,
|
||||||
aasmcnst,symconst,symdef,
|
aasmcnst,symconst,symdef,symtable,
|
||||||
llvmbase,aasmllvm,itllvm,llvmdef,
|
llvmbase,aasmllvm,itllvm,llvmdef,
|
||||||
cgbase,cgutils,cpubase;
|
cgbase,cgutils,cpubase;
|
||||||
|
|
||||||
@ -685,7 +685,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
AsmWrite(defstr);
|
AsmWrite(defstr);
|
||||||
AsmWrite(' ');
|
AsmWrite(' ');
|
||||||
AsmWrite('<{');
|
if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
|
||||||
|
AsmWrite('<{')
|
||||||
|
else
|
||||||
|
AsmWrite('{');
|
||||||
first:=true;
|
first:=true;
|
||||||
for p in tai_aggregatetypedconst(hp) do
|
for p in tai_aggregatetypedconst(hp) do
|
||||||
begin
|
begin
|
||||||
@ -695,7 +698,10 @@ implementation
|
|||||||
first:=false;
|
first:=false;
|
||||||
WriteTypedConstData(p);
|
WriteTypedConstData(p);
|
||||||
end;
|
end;
|
||||||
AsmWrite('}>');
|
if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
|
||||||
|
AsmWrite('}>')
|
||||||
|
else
|
||||||
|
AsmWrite('}');
|
||||||
end;
|
end;
|
||||||
tck_array:
|
tck_array:
|
||||||
begin
|
begin
|
||||||
|
@ -39,6 +39,8 @@ interface
|
|||||||
public
|
public
|
||||||
constructor create(_def: tdef; _typ: ttypedconstkind); override;
|
constructor create(_def: tdef; _typ: ttypedconstkind); override;
|
||||||
|
|
||||||
|
function prepare_next_field(nextfielddef: tdef): asizeint; override;
|
||||||
|
|
||||||
property aggai: tai_aggregatetypedconst read faggai write faggai;
|
property aggai: tai_aggregatetypedconst read faggai write faggai;
|
||||||
property anonrecalignpos: longint read fanonrecalignpos write fanonrecalignpos;
|
property anonrecalignpos: longint read fanonrecalignpos write fanonrecalignpos;
|
||||||
end;
|
end;
|
||||||
@ -66,11 +68,14 @@ interface
|
|||||||
procedure do_emit_tai(p: tai; def: tdef); override;
|
procedure do_emit_tai(p: tai; def: tdef); override;
|
||||||
procedure mark_anon_aggregate_alignment; override;
|
procedure mark_anon_aggregate_alignment; override;
|
||||||
procedure insert_marked_aggregate_alignment(def: tdef); override;
|
procedure insert_marked_aggregate_alignment(def: tdef); override;
|
||||||
|
procedure maybe_emit_tail_padding(def: tdef); override;
|
||||||
procedure begin_aggregate_internal(def: tdef; anonymous: boolean); override;
|
procedure begin_aggregate_internal(def: tdef; anonymous: boolean); override;
|
||||||
procedure end_aggregate_internal(def: tdef; anonymous: boolean); override;
|
procedure end_aggregate_internal(def: tdef; anonymous: boolean); override;
|
||||||
|
|
||||||
function get_internal_data_section_start_label: tasmlabel; override;
|
function get_internal_data_section_start_label: tasmlabel; override;
|
||||||
function get_internal_data_section_internal_label: tasmlabel; override;
|
function get_internal_data_section_internal_label: tasmlabel; override;
|
||||||
|
|
||||||
|
procedure do_emit_extended_in_aggregate(p: tai);
|
||||||
public
|
public
|
||||||
destructor destroy; override;
|
destructor destroy; override;
|
||||||
procedure emit_tai(p: tai; def: tdef); override;
|
procedure emit_tai(p: tai; def: tdef); override;
|
||||||
@ -104,6 +109,14 @@ implementation
|
|||||||
fanonrecalignpos:=-1;
|
fanonrecalignpos:=-1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function tllvmaggregateinformation.prepare_next_field(nextfielddef: tdef): asizeint;
|
||||||
|
begin
|
||||||
|
result:=inherited;
|
||||||
|
{ in case of C/ABI alignment, the padding gets added by LLVM }
|
||||||
|
if tabstractrecordsymtable(tabstractrecorddef(def).symtable).usefieldalignment=C_alignment then
|
||||||
|
result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
class constructor tllvmtai_typedconstbuilder.classcreate;
|
class constructor tllvmtai_typedconstbuilder.classcreate;
|
||||||
begin
|
begin
|
||||||
@ -249,6 +262,16 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure tllvmtai_typedconstbuilder.maybe_emit_tail_padding(def: tdef);
|
||||||
|
begin
|
||||||
|
{ in case of C/ABI alignment, the padding gets added by LLVM }
|
||||||
|
if (is_record(def) or
|
||||||
|
is_object(def)) and
|
||||||
|
(tabstractrecordsymtable(tabstractrecorddef(def).symtable).usefieldalignment=C_alignment) then
|
||||||
|
exit;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tllvmtai_typedconstbuilder.emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef);
|
procedure tllvmtai_typedconstbuilder.emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef);
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user