diff --git a/compiler/aasmcnst.pas b/compiler/aasmcnst.pas index 112cdbbea8..5bf38a90d0 100644 --- a/compiler/aasmcnst.pas +++ b/compiler/aasmcnst.pas @@ -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; diff --git a/compiler/llvm/agllvm.pas b/compiler/llvm/agllvm.pas index f4a9746ab1..e508ffd573 100644 --- a/compiler/llvm/agllvm.pas +++ b/compiler/llvm/agllvm.pas @@ -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 diff --git a/compiler/llvm/nllvmtcon.pas b/compiler/llvm/nllvmtcon.pas index 419444ed26..55b97b1d3a 100644 --- a/compiler/llvm/nllvmtcon.pas +++ b/compiler/llvm/nllvmtcon.pas @@ -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