diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-03-27 21:25:56 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-03-27 21:25:56 +0000 |
commit | 699ea0c29f4af69d9717f27436d1c3056d2ac06f (patch) | |
tree | 0e6d70663ecaed791b5bc1af4d872fd9bfbc4be8 | |
parent | 22a6ef99f4199e06c5f4cc772f4449a479e4a190 (diff) | |
download | fpc-699ea0c29f4af69d9717f27436d1c3056d2ac06f.tar.gz |
* 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: http://svn.freepascal.org/svn/fpc/branches/hlcgllvm@30343 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/aasmcnst.pas | 13 | ||||
-rw-r--r-- | compiler/ncgvmt.pas | 25 | ||||
-rw-r--r-- | compiler/pdecvar.pas | 2 | ||||
-rw-r--r-- | compiler/pgenutil.pas | 2 | ||||
-rw-r--r-- | compiler/ppu.pas | 2 | ||||
-rw-r--r-- | compiler/psystem.pas | 6 | ||||
-rw-r--r-- | compiler/ptype.pas | 5 | ||||
-rw-r--r-- | compiler/symcreat.pas | 3 | ||||
-rw-r--r-- | compiler/symdef.pas | 17 | ||||
-rw-r--r-- | compiler/symtable.pas | 35 |
10 files changed, 70 insertions, 40 deletions
diff --git a/compiler/aasmcnst.pas b/compiler/aasmcnst.pas index 1dd0ef4300..d65e3d41be 100644 --- a/compiler/aasmcnst.pas +++ b/compiler/aasmcnst.pas @@ -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 } diff --git a/compiler/ncgvmt.pas b/compiler/ncgvmt.pas index cc0eba90a7..966be672a4 100644 --- a/compiler/ncgvmt.pas +++ b/compiler/ncgvmt.pas @@ -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; diff --git a/compiler/pdecvar.pas b/compiler/pdecvar.pas index 89166a4b59..b231cd9c88 100644 --- a/compiler/pdecvar.pas +++ b/compiler/pdecvar.pas @@ -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; diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas index ce82464bbb..cc25907412 100644 --- a/compiler/pgenutil.pas +++ b/compiler/pgenutil.pas @@ -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; diff --git a/compiler/ppu.pas b/compiler/ppu.pas index 7ca08a031a..80f8635c89 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -43,7 +43,7 @@ type {$endif Test_Double_checksum} const - CurrentPPUVersion = 173; + CurrentPPUVersion = 174; { buffer sizes } maxentrysize = 1024; diff --git a/compiler/psystem.pas b/compiler/psystem.pas index ee8015d3d2..96449c3f16 100644 --- a/compiler/psystem.pas +++ b/compiler/psystem.pas @@ -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); diff --git a/compiler/ptype.pas b/compiler/ptype.pas index d6c4b58adf..eb7c20ec79 100644 --- a/compiler/ptype.pas +++ b/compiler/ptype.pas @@ -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; diff --git a/compiler/symcreat.pas b/compiler/symcreat.pas index c4cbf70031..7273ae7957 100644 --- a/compiler/symcreat.pas +++ b/compiler/symcreat.pas @@ -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); diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 9f5cdeb3b8..ddd0ac2673 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -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 diff --git a/compiler/symtable.pas b/compiler/symtable.pas index d703b8428b..3323625cd6 100644 --- a/compiler/symtable.pas +++ b/compiler/symtable.pas @@ -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 } |