mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 17:49:27 +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;
|
||||
{ calculated padding bytes for alignment if needed, and add the def of the
|
||||
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 typ: ttypedconstkind read ftyp;
|
||||
@ -269,6 +269,7 @@ type
|
||||
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
|
||||
|
||||
protected
|
||||
procedure maybe_emit_tail_padding(def: tdef); virtual;
|
||||
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 end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
|
||||
@ -1009,6 +1010,30 @@ implementation
|
||||
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;
|
||||
var
|
||||
string_symofs: asizeint;
|
||||
@ -1102,30 +1127,15 @@ implementation
|
||||
procedure ttai_typedconstbuilder.end_aggregate_internal(def: tdef; anonymous: boolean);
|
||||
var
|
||||
info: taggregateinformation;
|
||||
fillbytes: asizeint;
|
||||
tck: ttypedconstkind;
|
||||
begin
|
||||
tck:=aggregate_kind(def);
|
||||
if tck=tck_simple then
|
||||
exit;
|
||||
info:=curagginfo;
|
||||
if not assigned(info) then
|
||||
internalerror(2014091002);
|
||||
if def<>info.def then
|
||||
internalerror(2014091205);
|
||||
{ add tail padding if necessary }
|
||||
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;
|
||||
maybe_emit_tail_padding(def);
|
||||
{ pop and free the information }
|
||||
info:=curagginfo;
|
||||
faggregateinformation.count:=faggregateinformation.count-1;
|
||||
info.free;
|
||||
end;
|
||||
|
@ -81,7 +81,7 @@ implementation
|
||||
SysUtils,
|
||||
cutils,cfileutl,systems,
|
||||
fmodule,verbose,
|
||||
aasmcnst,symconst,symdef,
|
||||
aasmcnst,symconst,symdef,symtable,
|
||||
llvmbase,aasmllvm,itllvm,llvmdef,
|
||||
cgbase,cgutils,cpubase;
|
||||
|
||||
@ -685,7 +685,10 @@ implementation
|
||||
begin
|
||||
AsmWrite(defstr);
|
||||
AsmWrite(' ');
|
||||
AsmWrite('<{');
|
||||
if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
|
||||
AsmWrite('<{')
|
||||
else
|
||||
AsmWrite('{');
|
||||
first:=true;
|
||||
for p in tai_aggregatetypedconst(hp) do
|
||||
begin
|
||||
@ -695,7 +698,10 @@ implementation
|
||||
first:=false;
|
||||
WriteTypedConstData(p);
|
||||
end;
|
||||
AsmWrite('}>');
|
||||
if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
|
||||
AsmWrite('}>')
|
||||
else
|
||||
AsmWrite('}');
|
||||
end;
|
||||
tck_array:
|
||||
begin
|
||||
|
@ -39,6 +39,8 @@ interface
|
||||
public
|
||||
constructor create(_def: tdef; _typ: ttypedconstkind); override;
|
||||
|
||||
function prepare_next_field(nextfielddef: tdef): asizeint; override;
|
||||
|
||||
property aggai: tai_aggregatetypedconst read faggai write faggai;
|
||||
property anonrecalignpos: longint read fanonrecalignpos write fanonrecalignpos;
|
||||
end;
|
||||
@ -66,11 +68,14 @@ interface
|
||||
procedure do_emit_tai(p: tai; def: tdef); override;
|
||||
procedure mark_anon_aggregate_alignment; 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 end_aggregate_internal(def: tdef; anonymous: boolean); override;
|
||||
|
||||
function get_internal_data_section_start_label: tasmlabel; override;
|
||||
function get_internal_data_section_internal_label: tasmlabel; override;
|
||||
|
||||
procedure do_emit_extended_in_aggregate(p: tai);
|
||||
public
|
||||
destructor destroy; override;
|
||||
procedure emit_tai(p: tai; def: tdef); override;
|
||||
@ -104,6 +109,14 @@ implementation
|
||||
fanonrecalignpos:=-1;
|
||||
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;
|
||||
begin
|
||||
@ -249,6 +262,16 @@ implementation
|
||||
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);
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user