* store the to be used recordalignmin and maxcrecordalign settings inside

(abstract)recordsymtables, so that these settings don't depend on the
    current user settings when internally creating record definitions

git-svn-id: branches/hlcgllvm@30343 -
This commit is contained in:
Jonas Maebe 2015-03-27 21:25:56 +00:00
parent 419a97cce8
commit 25e6eaf07f
10 changed files with 70 additions and 40 deletions

View File

@ -301,7 +301,7 @@ type
b) the def of the record should be automatically constructed based on
the types of the emitted fields
}
function begin_anonymous_record(const optionalname: string; packrecords: shortint): trecorddef; virtual;
function begin_anonymous_record(const optionalname: string; packrecords, recordalignmin, maxcrecordalign: shortint): trecorddef; virtual;
function end_anonymous_record: trecorddef; virtual;
{ The next group of routines are for constructing complex expressions.
@ -982,7 +982,7 @@ implementation
result.ofs:=0;
{ pack the data, so that we don't add unnecessary null bytes after the
constant string }
begin_anonymous_record('$'+get_dynstring_rec_name(stringtype,false,len),1);
begin_anonymous_record('$'+get_dynstring_rec_name(stringtype,false,len),1,1,1);
string_symofs:=get_string_symofs(stringtype,false);
{ encoding }
emit_tai(tai_const.create_16bit(encoding),u16inttype);
@ -1151,7 +1151,10 @@ implementation
if winlike then
begin
result.lab:=startlab;
datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),sizeof(pint));
datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),
0,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
{ can we optimise by placing the string constant label at the
required offset? }
@ -1267,7 +1270,7 @@ implementation
end;
function ttai_typedconstbuilder.begin_anonymous_record(const optionalname: string; packrecords: shortint): trecorddef;
function ttai_typedconstbuilder.begin_anonymous_record(const optionalname: string; packrecords, recordalignmin, maxcrecordalign: shortint): trecorddef;
var
anonrecorddef: trecorddef;
srsym: tsym;
@ -1293,7 +1296,7 @@ implementation
end;
end;
{ create skeleton def }
anonrecorddef:=crecorddef.create_global_internal(optionalname,packrecords);
anonrecorddef:=crecorddef.create_global_internal(optionalname,packrecords,recordalignmin,maxcrecordalign);
{ generic aggregate housekeeping }
begin_aggregate_internal(anonrecorddef,true);
{ mark as anonymous record }

View File

@ -636,7 +636,10 @@ implementation
{ generate the class table }
tcb:=ctai_typedconstbuilder.create([tcalo_is_lab]);
tcb.begin_anonymous_record('$fpc_intern_classtable_'+tostr(classtablelist.Count-1),packrecords);
tcb.begin_anonymous_record('$fpc_intern_classtable_'+tostr(classtablelist.Count-1),
packrecords,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
tcb.emit_tai(Tai_const.Create_16bit(classtablelist.count),u16inttype);
for i:=0 to classtablelist.Count-1 do
begin
@ -670,7 +673,9 @@ implementation
lengths and their order would have to incorporated in the name,
plus there would be very little chance that it could actually be
reused }
tcb.begin_anonymous_record('',packrecords);
tcb.begin_anonymous_record('',packrecords,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
tcb.emit_tai(Tai_const.Create_16bit(fieldcount),u16inttype);
tcb.emit_tai(Tai_const.Create_sym(classtable),getpointerdef(classtabledef));
for i:=0 to _class.symtable.SymList.Count-1 do
@ -690,7 +695,9 @@ implementation
Name: ShortString;
end;
}
tcb.begin_anonymous_record('$fpc_intern_fieldinfo_'+tostr(length(tfieldvarsym(sym).realname)),packrecords);
tcb.begin_anonymous_record('$fpc_intern_fieldinfo_'+tostr(length(tfieldvarsym(sym).realname)),packrecords,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
tcb.emit_tai(Tai_const.Create_pint(tfieldvarsym(sym).fieldoffset),ptruinttype);
classindex:=classtablelist.IndexOf(tfieldvarsym(sym).vardef);
if classindex=-1 then
@ -804,7 +811,9 @@ implementation
begin
current_asmdata.getlabel(result,alt_data);
tcb:=ctai_typedconstbuilder.create([tcalo_is_lab]);
tcb.begin_anonymous_record('',0);
tcb.begin_anonymous_record('',0,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
tcb.emit_tai(Tai_const.Create_pint(_class.ImplementedInterfaces.count),search_system_type('SIZEUINT').typedef);
interfaceentrydef:=search_system_type('TINTERFACEENTRY').typedef;
interfaceentrytypedef:=search_system_type('TINTERFACEENTRYTYPE').typedef;
@ -847,7 +856,9 @@ implementation
arrdef:=tarraydef(trecordsymtable(recdef.symtable).findfieldbyoffset(countdef.size).vardef);
exit
end;
recdef:=crecorddef.create_global_internal('$'+basename+tostr(count),packrecords);
recdef:=crecorddef.create_global_internal('$'+basename+tostr(count),packrecords,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
fields:=tfplist.create;
fields.add(countdef);
if count>0 then
@ -878,7 +889,9 @@ implementation
fieldlist:=tfplist.create;
for i:=low(fields) to high(fields) do
fieldlist.add(fields[i]);
result:=crecorddef.create_global_internal('$'+name,packrecords);
result:=crecorddef.create_global_internal('$'+name,packrecords,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
result.add_fields_from_deflist(fieldlist);
fieldlist.free;
end;

View File

@ -1758,7 +1758,7 @@ implementation
Message(type_e_ordinal_expr_expected);
consume(_OF);
UnionSymtable:=trecordsymtable.create('',current_settings.packrecords);
UnionSymtable:=trecordsymtable.create('',current_settings.packrecords,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
UnionDef:=crecorddef.create('',unionsymtable);
uniondef.isunion:=true;

View File

@ -1038,7 +1038,7 @@ uses
Message(parser_e_illegal_expression)
else
begin
srsymtable:=trecordsymtable.create(defname,0);
srsymtable:=trecordsymtable.create(defname,0,1,1);
basedef:=crecorddef.create(defname,srsymtable);
include(constraintdata.flags,gcf_record);
allowconstructor:=false;

View File

@ -43,7 +43,7 @@ type
{$endif Test_Double_checksum}
const
CurrentPPUVersion = 173;
CurrentPPUVersion = 174;
{ buffer sizes }
maxentrysize = 1024;

View File

@ -474,7 +474,7 @@ implementation
if not(target_info.system in systems_managed_vm) then
begin
{ Add a type for virtual method tables }
hrecst:=trecordsymtable.create('',current_settings.packrecords);
hrecst:=trecordsymtable.create('',current_settings.packrecords,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
vmttype:=crecorddef.create('',hrecst);
pvmttype:=cpointerdef.create(vmttype);
{ can't use addtype for pvmt because the rtti of the pointed
@ -499,13 +499,13 @@ implementation
addtype('$vtblarray',vmtarraytype);
end;
{ Add a type for methodpointers }
hrecst:=trecordsymtable.create('',1);
hrecst:=trecordsymtable.create('',1,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
addfield(hrecst,cfieldvarsym.create('$proc',vs_value,voidcodepointertype,[]));
addfield(hrecst,cfieldvarsym.create('$self',vs_value,voidpointertype,[]));
methodpointertype:=crecorddef.create('',hrecst);
addtype('$methodpointer',methodpointertype);
{ Add a type for nested proc pointers }
hrecst:=trecordsymtable.create('',1);
hrecst:=trecordsymtable.create('',1,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
addfield(hrecst,cfieldvarsym.create('$proc',vs_value,voidcodepointertype,[]));
addfield(hrecst,cfieldvarsym.create('$parentfp',vs_value,parentfpvoidpointertype,[]));
nestedprocpointertype:=crecorddef.create('',hrecst);

View File

@ -898,7 +898,7 @@ implementation
if (n<>'') or
not(target_info.system in systems_jvm) then
begin
recst:=trecordsymtable.create(n,current_settings.packrecords);
recst:=trecordsymtable.create(n,current_settings.packrecords,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
{ can't use recst.realname^ instead of n, because recst.realname is
nil in case of an empty name }
current_structdef:=crecorddef.create(n,recst);
@ -907,7 +907,8 @@ implementation
begin
{ for the JVM target records always need a name, because they are
represented by a class }
recst:=trecordsymtable.create(current_module.realmodulename^+'__fpc_intern_recname_'+tostr(current_module.deflist.count),current_settings.packrecords);
recst:=trecordsymtable.create(current_module.realmodulename^+'__fpc_intern_recname_'+tostr(current_module.deflist.count),
current_settings.packrecords,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
current_structdef:=crecorddef.create(recst.name^,recst);
end;
result:=current_structdef;

View File

@ -1118,7 +1118,8 @@ implementation
{ create struct to hold local variables and parameters that are
accessed from within nested routines (start with extra dollar to prevent
the JVM from thinking this is a nested class in the unit) }
nestedvarsst:=trecordsymtable.create('$'+current_module.realmodulename^+'$$_fpc_nestedvars$'+tostr(pd.defid),current_settings.alignment.localalignmax);
nestedvarsst:=trecordsymtable.create('$'+current_module.realmodulename^+'$$_fpc_nestedvars$'+tostr(pd.defid),
current_settings.alignment.localalignmax,current_settings.alignment.localalignmin,current_settings.alignment.maxCrecordalign);
nestedvarsdef:=crecorddef.create(nestedvarsst.name^,nestedvarsst);
{$ifdef jvm}
maybe_guarantee_record_typesym(nestedvarsdef,nestedvarsdef.owner);

View File

@ -298,7 +298,7 @@ interface
variantrecdesc : pvariantrecdesc;
isunion : boolean;
constructor create(const n:string; p:TSymtable);virtual;
constructor create_global_internal(n: string; packrecords: shortint); virtual;
constructor create_global_internal(n: string; packrecords, recordalignmin, maxCrecordalign: shortint); virtual;
procedure add_field_by_def(def: tdef);
procedure add_fields_from_deflist(fieldtypes: tfplist);
constructor ppuload(ppufile:tcompilerppufile);
@ -4031,7 +4031,7 @@ implementation
end;
constructor trecorddef.create_global_internal(n: string; packrecords: shortint);
constructor trecorddef.create_global_internal(n: string; packrecords, recordalignmin, maxCrecordalign: shortint);
var
oldsymtablestack: tsymtablestack;
ts: ttypesym;
@ -4046,7 +4046,7 @@ implementation
that can have side-effects (e.g., it removes helpers) }
symtablestack:=nil;
symtable:=trecordsymtable.create(n,packrecords);
symtable:=trecordsymtable.create(n,packrecords,recordalignmin,maxCrecordalign);
symtable.defowner:=self;
isunion:=false;
inherited create(n,recorddef);
@ -4128,11 +4128,12 @@ implementation
else
begin
ppuload_platform(ppufile);
symtable:=trecordsymtable.create(objrealname^,0);
symtable:=trecordsymtable.create(objrealname^,0,0,0);
trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).usefieldalignment:=shortint(ppufile.getbyte);
trecordsymtable(symtable).recordalignmin:=shortint(ppufile.getbyte);
trecordsymtable(symtable).datasize:=ppufile.getasizeint;
trecordsymtable(symtable).paddingsize:=ppufile.getword;
trecordsymtable(symtable).ppuload(ppufile);
@ -4257,6 +4258,7 @@ implementation
ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
ppufile.putbyte(byte(trecordsymtable(symtable).usefieldalignment));
ppufile.putbyte(byte(trecordsymtable(symtable).recordalignmin));
ppufile.putasizeint(trecordsymtable(symtable).datasize);
ppufile.putword(trecordsymtable(symtable).paddingsize);
{ the variantrecdesc is needed only for iso-like new statements new(prec,1,2,3 ...);
@ -5986,7 +5988,8 @@ implementation
childof:=nil;
if objecttype=odt_helper then
owner.includeoption(sto_has_helper);
symtable:=tObjectSymtable.create(self,n,current_settings.packrecords);
symtable:=tObjectSymtable.create(self,n,current_settings.packrecords,
current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
{ create space for vmt !! }
vmtentries:=TFPList.Create;
set_parent(c);
@ -6015,11 +6018,12 @@ implementation
{ only used for external Objective-C classes/protocols }
if (objextname^='') then
stringdispose(objextname);
symtable:=tObjectSymtable.create(self,objrealname^,0);
symtable:=tObjectSymtable.create(self,objrealname^,0,0,0);
tObjectSymtable(symtable).datasize:=ppufile.getasizeint;
tObjectSymtable(symtable).paddingsize:=ppufile.getword;
tObjectSymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
tObjectSymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
tObjectSymtable(symtable).recordalignmin:=shortint(ppufile.getbyte);
ppufile.getderef(vmt_fieldderef);
ppufile.getderef(childofderef);
@ -6222,6 +6226,7 @@ implementation
ppufile.putword(tObjectSymtable(symtable).paddingsize);
ppufile.putbyte(byte(tObjectSymtable(symtable).fieldalignment));
ppufile.putbyte(byte(tObjectSymtable(symtable).recordalignment));
ppufile.putbyte(byte(tObjectSymtable(symtable).recordalignmin));
ppufile.putderef(vmt_fieldderef);
ppufile.putderef(childofderef);
if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then

View File

@ -96,7 +96,9 @@ interface
recordalignment, { alignment desired when inserting this record }
fieldalignment, { alignment current alignment used when fields are inserted }
padalignment : shortint; { size to a multiple of which the symtable has to be rounded up }
constructor create(const n:string;usealign:shortint);
recordalignmin, { local equivalents of global settings, so that records can }
maxCrecordalign: shortint; { be created with custom settings internally }
constructor create(const n:string;usealign,recordminalign,recordmaxCalign:shortint);
destructor destroy;override;
procedure ppuload(ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
@ -133,13 +135,13 @@ interface
trecordsymtable = class(tabstractrecordsymtable)
public
constructor create(const n:string;usealign:shortint);
constructor create(const n:string;usealign,recordminalign,recordmaxCalign:shortint);
procedure insertunionst(unionst : trecordsymtable;offset : longint);
end;
tObjectSymtable = class(tabstractrecordsymtable)
public
constructor create(adefowner:tdef;const n:string;usealign:shortint);
constructor create(adefowner:tdef;const n:string;usealign,recordminalign,recordmaxCalign:shortint);
function checkduplicate(var hashedid:THashedIDString;sym:TSymEntry):boolean;override;
end;
@ -151,6 +153,7 @@ interface
private
equivst: tabstractrecordsymtable;
curroffset: aint;
recordalignmin: shortint;
function get(index: longint): tllvmshadowsymtableentry;
public
symdeflist: TFPObjectList;
@ -943,7 +946,7 @@ implementation
end;
{$endif llvm}
constructor tabstractrecordsymtable.create(const n:string;usealign:shortint);
constructor tabstractrecordsymtable.create(const n:string;usealign,recordminalign,recordmaxCalign:shortint);
begin
inherited create(n);
moduleid:=current_module.moduleid;
@ -951,6 +954,8 @@ implementation
databitsize:=0;
recordalignment:=1;
usefieldalignment:=usealign;
recordalignmin:=recordminalign;
maxCrecordalign:=recordmaxCalign;
padalignment:=1;
{ recordalign C_alignment means C record packing, that starts
with an alignment of 1 }
@ -981,6 +986,7 @@ implementation
Message(unit_f_ppu_read_error);
recordalignment:=shortint(ppufile.getbyte);
usefieldalignment:=shortint(ppufile.getbyte);
recordalignmin:=shortint(ppufile.getbyte);
if (usefieldalignment=C_alignment) then
fieldalignment:=shortint(ppufile.getbyte);
inherited ppuload(ppufile);
@ -997,6 +1003,7 @@ implementation
affects the alignment of fields of the childs }
ppufile.putbyte(byte(recordalignment));
ppufile.putbyte(byte(usefieldalignment));
ppufile.putbyte(byte(recordalignmin));
if (usefieldalignment=C_alignment) then
ppufile.putbyte(byte(fieldalignment));
ppufile.writeentry(ibrecsymtableoptions);
@ -1039,7 +1046,7 @@ implementation
begin
case usefieldalignment of
C_alignment:
varalignrecord:=used_align(varalign,current_settings.alignment.recordalignmin,current_settings.alignment.maxCrecordalign);
varalignrecord:=used_align(varalign,recordalignmin,maxCrecordalign);
mac68k_alignment:
varalignrecord:=2;
else
@ -1434,7 +1441,7 @@ implementation
Message1(sym_w_wrong_C_pack,vardef.typename);
if varalign=0 then
varalign:=l;
if (globalfieldalignment<current_settings.alignment.maxCrecordalign) then
if (globalfieldalignment<maxCrecordalign) then
begin
if (varalign>16) and (globalfieldalignment<32) then
globalfieldalignment:=32
@ -1450,7 +1457,7 @@ implementation
else if (varalign>1) and (globalfieldalignment<2) then
globalfieldalignment:=2;
end;
globalfieldalignment:=min(globalfieldalignment,current_settings.alignment.maxCrecordalign);
globalfieldalignment:=min(globalfieldalignment,maxCrecordalign);
end;
mac68k_alignment:
begin
@ -1468,7 +1475,7 @@ implementation
end;
if varalign=0 then
varalign:=size_2_align(l);
varalignfield:=used_align(varalign,current_settings.alignment.recordalignmin,globalfieldalignment);
varalignfield:=used_align(varalign,recordalignmin,globalfieldalignment);
result:=align(base,varalignfield);
end;
@ -1482,9 +1489,9 @@ implementation
TRecordSymtable
****************************************************************************}
constructor trecordsymtable.create(const n:string;usealign:shortint);
constructor trecordsymtable.create(const n:string;usealign,recordminalign,recordmaxCalign:shortint);
begin
inherited create(n,usealign);
inherited create(n,usealign,recordminalign,recordmaxCalign);
symtabletype:=recordsymtable;
end;
@ -1601,9 +1608,9 @@ implementation
TObjectSymtable
****************************************************************************}
constructor tObjectSymtable.create(adefowner:tdef;const n:string;usealign:shortint);
constructor tObjectSymtable.create(adefowner:tdef;const n:string;usealign,recordminalign,recordmaxCalign:shortint);
begin
inherited create(n,usealign);
inherited create(n,usealign,recordminalign,recordmaxCalign);
symtabletype:=ObjectSymtable;
defowner:=adefowner;
end;
@ -1810,7 +1817,7 @@ implementation
if (lastoffset=sym.fieldoffset) then
begin
if (equivst.fieldalignment<>bit_alignment) then
newalignment:=used_align(sym.vardef.alignment,current_settings.alignment.recordalignmin,equivst.fieldalignment)
newalignment:=used_align(sym.vardef.alignment,equivst.recordalignmin,equivst.fieldalignment)
else
newalignment:=1;
if (newalignment>tfieldvarsym(variantstarts[variantstarts.count-1]).vardef.alignment) then
@ -1833,7 +1840,7 @@ implementation
internalerror(2008051003);
{ new variant has higher alignment? }
if (equivst.fieldalignment<>bit_alignment) then
newalignment:=used_align(sym.vardef.alignment,current_settings.alignment.recordalignmin,equivst.fieldalignment)
newalignment:=used_align(sym.vardef.alignment,equivst.recordalignmin,equivst.fieldalignment)
else
newalignment:=1;
{ yes, replace and remove previous nested variants }