diff --git a/compiler/ncgrtti.pas b/compiler/ncgrtti.pas index 9d8e618898..aac001ffa6 100644 --- a/compiler/ncgrtti.pas +++ b/compiler/ncgrtti.pas @@ -27,7 +27,7 @@ interface uses cclasses,constexp, - aasmbase, + aasmbase,aasmcnst, symbase,symconst,symtype,symdef; type @@ -36,23 +36,28 @@ interface TRTTIWriter=class private + { required internal alignment of the rtti data } + reqalign: shortint; + { required packing of all structures except for ttypeinfo and tpropinfo, + which always use packrecords 1 } + defaultpacking: shortint; + procedure fields_write_rtti(st:tsymtable;rt:trttitype); procedure params_write_rtti(def:tabstractprocdef;rt:trttitype); - procedure fields_write_rtti_data(def:tabstractrecorddef;rt:trttitype); + procedure fields_write_rtti_data(tcb: ttai_typedconstbuilder; def: tabstractrecorddef; rt: trttitype); procedure write_rtti_extrasyms(def:Tdef;rt:Trttitype;mainrtti:Tasmsymbol); procedure published_write_rtti(st:tsymtable;rt:trttitype); function published_properties_count(st:tsymtable):longint; - procedure published_properties_write_rtti_data(propnamelist:TFPHashObjectList;st:tsymtable); + procedure published_properties_write_rtti_data(tcb: ttai_typedconstbuilder; propnamelist: TFPHashObjectList; st: tsymtable); procedure collect_propnamelist(propnamelist:TFPHashObjectList;objdef:tobjectdef); function ref_rtti(def:tdef;rt:trttitype):tasmsymbol; - procedure write_rtti_name(def:tdef); - procedure write_rtti_data(def:tdef;rt:trttitype); + procedure write_rtti_name(tcb: ttai_typedconstbuilder; def: tdef); + procedure write_rtti_data(tcb: ttai_typedconstbuilder; def:tdef; rt: trttitype); procedure write_child_rtti_data(def:tdef;rt:trttitype); - procedure write_rtti_reference(def:tdef;rt:trttitype); - procedure write_header(def: tdef; typekind: byte); - procedure write_string(const s: string); - procedure maybe_write_align; + procedure write_rtti_reference(tcb: ttai_typedconstbuilder; def: tdef; rt: trttitype); + procedure write_header(tcb: ttai_typedconstbuilder; def: tdef; typekind: byte); public + constructor create; procedure write_rtti(def:tdef;rt:trttitype); function get_rtti_label(def:tdef;rt:trttitype):tasmsymbol; function get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol; @@ -69,7 +74,7 @@ implementation cutils, globals,globtype,verbose,systems, fmodule, procinfo, - symsym, + symtable,symsym, aasmtai,aasmdata, defutil, wpobase @@ -94,32 +99,27 @@ implementation TRTTIWriter ***************************************************************************} - procedure TRTTIWriter.maybe_write_align; - begin - if (tf_requires_proper_alignment in target_info.flags) then - current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt))); - end; - - procedure TRTTIWriter.write_string(const s: string); - begin - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(s))); - current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(s)); - end; - - procedure TRTTIWriter.write_header(def: tdef; typekind: byte); + procedure TRTTIWriter.write_header(tcb: ttai_typedconstbuilder; def: tdef; typekind: byte); + var + name: shortstring; begin + if assigned(def.typesym) then + name:=ttypesym(def.typesym).realname + else + name:=''; + { TTypeInfo, always packed and doesn't need alignment } + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_header]+tostr(length(name)),1,1, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); if def.typ=arraydef then InternalError(201012211); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(typekind)); - if assigned(def.typesym) then - write_string(ttypesym(def.typesym).realname) - else - current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(#0)); + tcb.emit_tai(Tai_const.Create_8bit(typekind),u8inttype); + tcb.emit_shortstring_const(name); + tcb.end_anonymous_record; end; - procedure TRTTIWriter.write_rtti_name(def:tdef); - var - hs : string; + procedure TRTTIWriter.write_rtti_name(tcb: ttai_typedconstbuilder; def: tdef); begin if is_open_array(def) then { open arrays never have a typesym with a name, since you cannot @@ -130,41 +130,36 @@ implementation def:=tarraydef(def).elementdef; { name } if assigned(def.typesym) then - begin - hs:=ttypesym(def.typesym).realname; - current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(chr(length(hs))+hs)); - end + tcb.emit_shortstring_const(ttypesym(def.typesym).realname) else - current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(#0)); + tcb.emit_shortstring_const(''); end; { writes a 32-bit count followed by array of field infos for given symtable } - procedure TRTTIWriter.fields_write_rtti_data(def:tabstractrecorddef;rt:trttitype); + procedure TRTTIWriter.fields_write_rtti_data(tcb: ttai_typedconstbuilder; def: tabstractrecorddef; rt: trttitype); var i : longint; sym : tsym; fieldcnt: longint; - lastai: TLinkedListItem; st: tsymtable; + fields: tfplist; + parentrtti: boolean; begin fieldcnt:=0; - { Count will be inserted at this location. It cannot be nil as we've just - written header for this symtable owner. But stay safe. } - lastai:=current_asmdata.asmlists[al_rtti].last; - if lastai=nil then - InternalError(201012212); - + parentrtti:=false; + st:=def.symtable; + fields:=tfplist.create; + fields.capacity:=st.symlist.count+1; { For objects, treat parent (if any) as a field with offset 0. This provides correct handling of entire instance with RTL rtti routines. } if (def.typ=objectdef) and (tobjectdef(def).objecttype=odt_object) and Assigned(tobjectdef(def).childof) and ((rt=fullrtti) or (tobjectdef(def).childof.needs_inittable)) then - begin - write_rtti_reference(tobjectdef(def).childof,rt); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_pint(0)); - inc(fieldcnt); - end; - st:=def.symtable; + begin + parentrtti:=true; + inc(fieldcnt); + end; + for i:=0 to st.SymList.Count-1 do begin sym:=tsym(st.SymList[i]); @@ -176,13 +171,26 @@ implementation ) and not is_objc_class_or_protocol(tfieldvarsym(sym).vardef) then begin - write_rtti_reference(tfieldvarsym(sym).vardef,rt); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_pint(tfieldvarsym(sym).fieldoffset)); + fields.add(tfieldvarsym(sym)); inc(fieldcnt); end; end; { insert field count before data } - current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_32bit(fieldcnt),lastai) + tcb.emit_ord_const(fieldcnt,u32inttype); + { parent object? } + if parentrtti then + begin + write_rtti_reference(tcb,tobjectdef(def).childof,rt); + tcb.emit_ord_const(0,ptruinttype); + end; + { fields } + for i:=0 to fields.count-1 do + begin + sym:=tsym(fields[i]); + write_rtti_reference(tcb,tfieldvarsym(sym).vardef,rt); + tcb.emit_ord_const(tfieldvarsym(sym).fieldoffset,ptruinttype); + end; + fields.free; end; @@ -282,7 +290,7 @@ implementation end; - procedure TRTTIWriter.published_properties_write_rtti_data(propnamelist:TFPHashObjectList;st:tsymtable); + procedure TRTTIWriter.published_properties_write_rtti_data(tcb: ttai_typedconstbuilder; propnamelist:TFPHashObjectList;st:tsymtable); var i : longint; sym : tsym; @@ -293,6 +301,7 @@ implementation var typvalue : byte; hp : ppropaccesslistitem; + extnumber: longint; address,space : longint; def : tdef; hpropsym : tpropertysym; @@ -307,8 +316,8 @@ implementation until not assigned(hpropsym); if not(assigned(propaccesslist) and assigned(propaccesslist.firstsym)) then begin - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_int_codeptr(unsetvalue)); - typvalue:=3; + tcb.emit_tai(Tai_const.Create_int_codeptr(unsetvalue),voidcodepointertype); + typvalue:=3; end else if propaccesslist.firstsym^.sym.typ=fieldvarsym then begin @@ -347,7 +356,7 @@ implementation end; hp:=hp^.next; end; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_int_codeptr(address)); + tcb.emit_tai(Tai_const.Create_int_codeptr(address),voidcodepointertype); typvalue:=0; end else @@ -358,74 +367,88 @@ implementation if not(po_virtualmethod in tprocdef(propaccesslist.procdef).procoptions) or is_objectpascal_helper(tprocdef(propaccesslist.procdef).struct) then begin - current_asmdata.asmlists[al_rtti].concat(Tai_const.createname(tprocdef(propaccesslist.procdef).mangledname,AT_FUNCTION,0)); - typvalue:=1; + tcb.emit_procdef_const(tprocdef(propaccesslist.procdef)); + typvalue:=1; end else begin - { virtual method, write vmt offset } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_int_codeptr( - tobjectdef(tprocdef(propaccesslist.procdef).struct).vmtmethodoffset(tprocdef(propaccesslist.procdef).extnumber))); - { register for wpo } - tobjectdef(tprocdef(propaccesslist.procdef).struct).register_vmt_call(tprocdef(propaccesslist.procdef).extnumber); - {$ifdef vtentry} - { not sure if we can insert those vtentry symbols safely here } - {$error register methods used for published properties} - {$endif vtentry} - typvalue:=2; + { virtual method, write vmt offset } + extnumber:=tprocdef(propaccesslist.procdef).extnumber; + tcb.emit_tai(Tai_const.Create_int_codeptr( + tobjectdef(tprocdef(propaccesslist.procdef).struct).vmtmethodoffset(extnumber)), + voidcodepointertype); + { register for wpo } + tobjectdef(tprocdef(propaccesslist.procdef).struct).register_vmt_call(extnumber); + {$ifdef vtentry} + { not sure if we can insert those vtentry symbols safely here } + {$error register methods used for published properties} + {$endif vtentry} + typvalue:=2; end; end; proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue); end; begin + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(published_properties_count(st),u16inttype); for i:=0 to st.SymList.Count-1 do begin sym:=tsym(st.SymList[i]); if (sym.typ=propertysym) and (sym.visibility=vis_published) then begin + { TPropInfo is a packed record (even on targets that require + alignment), but it starts aligned } + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_prop]+tostr(length(tpropertysym(sym).realname)), + 1,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); if ppo_indexed in tpropertysym(sym).propoptions then proctypesinfo:=$40 else proctypesinfo:=0; - write_rtti_reference(tpropertysym(sym).propdef,fullrtti); + write_rtti_reference(tcb,tpropertysym(sym).propdef,fullrtti); writeaccessproc(palt_read,0,0); writeaccessproc(palt_write,2,0); { is it stored ? } if not(ppo_stored in tpropertysym(sym).propoptions) then begin { no, so put a constant zero } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_nil_codeptr); + tcb.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype); proctypesinfo:=proctypesinfo or (3 shl 4); end else writeaccessproc(palt_stored,4,1); { maybe; if no procedure put a constant 1 (=true) } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tpropertysym(sym).index)); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tpropertysym(sym).default)); + tcb.emit_ord_const(tpropertysym(sym).index,u32inttype); + tcb.emit_ord_const(tpropertysym(sym).default,u32inttype); propnameitem:=TPropNameListItem(propnamelist.Find(tpropertysym(sym).name)); if not assigned(propnameitem) then internalerror(200512201); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnameitem.propindex)); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(proctypesinfo)); - write_string(tpropertysym(sym).realname); - maybe_write_align; + tcb.emit_ord_const(propnameitem.propindex,u16inttype); + tcb.emit_ord_const(proctypesinfo,u8inttype); + tcb.emit_shortstring_const(tpropertysym(sym).realname); + tcb.end_anonymous_record; end; end; + tcb.end_anonymous_record; end; - procedure TRTTIWriter.write_rtti_data(def:tdef;rt:trttitype); + procedure TRTTIWriter.write_rtti_data(tcb: ttai_typedconstbuilder; def: tdef; rt: trttitype); procedure unknown_rtti(def:tstoreddef); begin - current_asmdata.asmlists[al_rtti].concat(tai_const.create_8bit(tkUnknown)); - write_rtti_name(def); + tcb.emit_ord_const(tkUnknown,u8inttype); + write_rtti_name(tcb,def); end; procedure variantdef_rtti(def:tvariantdef); begin - write_header(def,tkVariant); + write_header(tcb,def,tkVariant); end; procedure stringdef_rtti(def:tstringdef); @@ -433,58 +456,76 @@ implementation case def.stringtype of st_ansistring: begin - write_header(def,tkAString); - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.encoding)); + write_header(tcb,def,tkAString); + { align } + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_ansistr], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(def.encoding,u16inttype); + tcb.end_anonymous_record; end; st_widestring: - write_header(def,tkWString); + write_header(tcb,def,tkWString); st_unicodestring: - write_header(def,tkUString); + write_header(tcb,def,tkUString); st_longstring: - write_header(def,tkLString); + write_header(tcb,def,tkLString); st_shortstring: begin - write_header(def,tkSString); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.len)); - maybe_write_align; // is align necessary here? + write_header(tcb,def,tkSString); + tcb.emit_ord_const(def.len,u8inttype); end; end; end; - procedure enumdef_rtti(def:tenumdef); + procedure enumdef_rtti(def: tenumdef); var i : integer; hp : tenumsym; begin - write_header(def,tkEnumeration); - maybe_write_align; + write_header(tcb,def,tkEnumeration); + { align; the named fields are so that we can let the compiler + calculate the string offsets later on } + tcb.next_field_name:='size_start_rec'; + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); case longint(def.size) of 1 : - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte)); + tcb.emit_ord_const(otUByte,u8inttype); 2 : - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord)); + tcb.emit_ord_const(otUWord,u8inttype); 4 : - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong)); + tcb.emit_ord_const(otULong,u8inttype); end; - { we need to align by Tconstptruint here to satisfy the alignment rules set by - records: in the typinfo unit we overlay a TTypeData record on this data, which at - the innermost variant record needs an alignment of TConstPtrUint due to e.g. - the "CompType" member for tkSet (also the "BaseType" member for tkEnumeration). - We need to adhere to this, otherwise things will break. - Note that other code (e.g. enumdef_rtti_calcstringtablestart()) relies on the - exact sequence too. } - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.min)); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.max)); - maybe_write_align; // is align necessary here? + { we need to align by Tconstptruint here to satisfy the alignment + rules set by records: in the typinfo unit we overlay a TTypeData + record on this data, which at the innermost variant record needs an + alignment of TConstPtrUint due to e.g. the "CompType" member for + tkSet (also the "BaseType" member for tkEnumeration). + + We need to adhere to this, otherwise things will break. } + tcb.next_field_name:='min_max_rec'; + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(def.min,s32inttype); + tcb.emit_ord_const(def.max,s32inttype); + tcb.next_field_name:='basetype_array_rec'; + { all strings must appear right after each other -> from now on + packrecords 1 (but the start must still be aligned) } + tcb.begin_anonymous_record('',1,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { write base type } - write_rtti_reference(def.basedef,rt); - for i := 0 to def.symtable.SymList.Count - 1 do + write_rtti_reference(tcb,def.basedef,rt); + for i:=0 to def.symtable.SymList.Count-1 do begin hp:=tenumsym(def.symtable.SymList[i]); if hp.valuedef.maxval then break; - write_string(hp.realname); + tcb.next_field_name:='enumname'+tostr(hp.SymId); + tcb.emit_shortstring_const(hp.realname); end; { write unit name } - write_string(current_module.realmodulename^); + tcb.emit_shortstring_const(current_module.realmodulename^); { write zero which is required by RTL } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0)); + tcb.emit_ord_const(0,u8inttype); + { terminate all records } + tcb.end_anonymous_record; + tcb.end_anonymous_record; + tcb.end_anonymous_record; end; procedure orddef_rtti(def:torddef); @@ -512,35 +558,56 @@ implementation otSByte,otSWord,otSLong,otSByte, otUByte,otUWord,otUByte); begin - write_header(def,typekind); - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(byte(trans[def.ordtype]))); - maybe_write_align; + write_header(tcb,def,typekind); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_ord_outer], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(byte(trans[def.ordtype]),u8inttype); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_ord_inner], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); {Convert to longint to smuggle values in high(longint)+1..high(cardinal) into asmlist.} - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.low.svalue))); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.high.svalue))); + tcb.emit_ord_const(longint(def.low.svalue),s32inttype); + tcb.emit_ord_const(longint(def.high.svalue),s32inttype); + tcb.end_anonymous_record; + tcb.end_anonymous_record; end; begin case def.ordtype of s64bit : begin - write_header(def,tkInt64); - maybe_write_align; + write_header(tcb,def,tkInt64); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_ord_64bit], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { low } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.low.svalue)); + tcb.emit_ord_const(def.low.svalue,s64inttype); { high } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.high.svalue)); + tcb.emit_ord_const(def.high.svalue,s64inttype); + tcb.end_anonymous_record; end; u64bit : begin - write_header(def,tkQWord); - maybe_write_align; - {use svalue because Create_64bit accepts int64, prevents range checks} + write_header(tcb,def,tkQWord); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_ord_64bit], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + { use svalue because emit_ord_const accepts int64, prevents + range check errors } { low } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.low.svalue)); + tcb.emit_ord_const(def.low.svalue,s64inttype); { high } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.high.svalue)); + tcb.emit_ord_const(def.high.svalue,s64inttype); + tcb.end_anonymous_record; end; pasbool8: dointeger(tkBool); @@ -550,9 +617,14 @@ implementation dointeger(tkWChar); scurrency: begin - write_header(def,tkFloat); - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ftCurr)); + write_header(tcb,def,tkFloat); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_1byte], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(ftCurr,u8inttype); + tcb.end_anonymous_record; end; else dointeger(tkInteger); @@ -566,77 +638,93 @@ implementation translate : array[tfloattype] of byte = (ftSingle,ftDouble,ftExtended,ftExtended,ftComp,ftCurr,ftFloat128); begin - write_header(def,tkFloat); - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(translate[def.floattype])); + write_header(tcb,def,tkFloat); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_1byte], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(translate[def.floattype],u8inttype); + tcb.end_anonymous_record; end; procedure setdef_rtti(def:tsetdef); begin - write_header(def,tkSet); - maybe_write_align; + write_header(tcb,def,tkSet); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_1byte], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); case def.size of 1: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte)); + tcb.emit_ord_const(otUByte,u8inttype); 2: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord)); + tcb.emit_ord_const(otUWord,u8inttype); 4: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong)); + tcb.emit_ord_const(otULong,u8inttype); else - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte)); + tcb.emit_ord_const(otUByte,u8inttype); end; - maybe_write_align; - write_rtti_reference(def.elementdef,rt); + { since this record has an alignment of reqalign, its size will also + be rounded up to a multiple of reqalign -> the following value will + also be properly aligned without having to start an extra record } + tcb.end_anonymous_record; + write_rtti_reference(tcb,def.elementdef,rt); end; procedure arraydef_rtti(def:tarraydef); var - lastai: TLinkedListItem; - dimcount: byte; + i,dimcount: byte; totalcount: asizeuint; + finaldef: tdef; curdef:tarraydef; begin if ado_IsDynamicArray in def.arrayoptions then - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkdynarray)) + tcb.emit_ord_const(tkDynArray,u8inttype) else - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkarray)); - write_rtti_name(def); - maybe_write_align; + tcb.emit_ord_const(tkArray,u8inttype); + write_rtti_name(tcb,def); if not(ado_IsDynamicArray in def.arrayoptions) then begin { remember tha last instruction. we will need to insert some calculated values after it } - lastai:=current_asmdata.asmlists[al_rtti].last; - curdef:=def; + finaldef:=def; totalcount:=1; dimcount:=0; - while assigned(curdef) do - begin - { Dims[i] PTypeInfo } - write_rtti_reference(curdef.rangedef,rt); - inc(dimcount); - totalcount:=totalcount*curdef.elecount; - { get the next static array } - if assigned(curdef.elementdef) and - (curdef.elementdef.typ=arraydef) and - not(ado_IsDynamicArray in tarraydef(curdef.elementdef).arrayoptions) then - curdef:=tarraydef(curdef.elementdef) - else - break; - end; - if (tf_requires_proper_alignment in target_info.flags) then - current_asmdata.asmlists[al_rtti].InsertAfter(cai_align.Create(sizeof(TConstPtrUInt)),lastai); - { dimension count } - current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_8bit(dimcount),lastai); - { last dimension element type } - current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_sym(ref_rtti(curdef.elementdef,rt)),lastai); - { total element count } - current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_pint(pint(totalcount)),lastai); + repeat + curdef:=tarraydef(finaldef); + finaldef:=curdef.elementdef; + { Dims[i] PTypeInfo } + inc(dimcount); + totalcount:=totalcount*curdef.elecount; + until (finaldef.typ<>arraydef) or + (ado_IsDynamicArray in tarraydef(finaldef).arrayoptions); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_normal_array]+tostr(dimcount), + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { total size = elecount * elesize of the first arraydef } - current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_pint(def.elecount*def.elesize),lastai); + tcb.emit_tai(Tai_const.Create_pint(def.elecount*def.elesize),ptruinttype); + { total element count } + tcb.emit_tai(Tai_const.Create_pint(pint(totalcount)),ptruinttype); + { last dimension element type } + tcb.emit_tai(Tai_const.Create_sym(ref_rtti(curdef.elementdef,rt)),voidpointertype); + { dimension count } + tcb.emit_ord_const(dimcount,u8inttype); + finaldef:=def; + { ranges of the dimensions } + for i:=1 to dimcount do + begin + curdef:=tarraydef(finaldef); + finaldef:=curdef.elementdef; + { Dims[i] PTypeInfo } + write_rtti_reference(tcb,curdef.rangedef,rt); + end; end else { write a delphi almost compatible dyn. array entry: @@ -646,42 +734,54 @@ implementation the names are swapped in typinfo.pp } begin + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_dyn_array], + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { size of elements } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_pint(def.elesize)); + tcb.emit_tai(Tai_const.Create_pint(def.elesize),ptruinttype); { element type } - write_rtti_reference(def.elementdef,rt); + write_rtti_reference(tcb,def.elementdef,rt); { variant type } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tstoreddef(def.elementdef).getvardef)); + tcb.emit_ord_const(tstoreddef(def.elementdef).getvardef,s32inttype); { element type } if def.elementdef.needs_inittable then - write_rtti_reference(def.elementdef,rt) + write_rtti_reference(tcb,def.elementdef,rt) else - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_nil_dataptr); + tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype); { write unit name } - write_string(current_module.realmodulename^); + tcb.emit_shortstring_const(current_module.realmodulename^); end; + tcb.end_anonymous_record; end; procedure classrefdef_rtti(def:tclassrefdef); begin - write_header(def,tkClassRef); - maybe_write_align; - write_rtti_reference(def.pointeddef,rt); + write_header(tcb,def,tkClassRef); + { will be aligned thanks to encompassing record } + write_rtti_reference(tcb,def.pointeddef,rt); end; procedure pointerdef_rtti(def:tpointerdef); begin - write_header(def,tkPointer); - maybe_write_align; - write_rtti_reference(def.pointeddef,rt); + write_header(tcb,def,tkPointer); + { will be aligned thanks to encompassing record } + write_rtti_reference(tcb,def.pointeddef,rt); end; procedure recorddef_rtti(def:trecorddef); begin - write_header(def,tkRecord); - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size)); - fields_write_rtti_data(def,rt); + write_header(tcb,def,tkRecord); + { need extra reqalign record, because otherwise the u32 int will + only be aligned to 4 even on 64 bit target (while the rtti code + in typinfo expects alignments to sizeof(pointer)) } + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + tcb.emit_ord_const(def.size,u32inttype); + fields_write_rtti_data(tcb,def,rt); + tcb.end_anonymous_record; end; @@ -733,7 +833,7 @@ implementation if (target_info.endian = endian_big) then paraspec:=reverse_byte(paraspec); { write flags for current parameter } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(paraspec)); + tcb.emit_ord_const(paraspec,u8inttype); end; procedure write_para(parasym:tparavarsym); @@ -744,9 +844,9 @@ implementation { write flags for current parameter } write_param_flag(parasym); { write name of current parameter } - write_string(parasym.realname); + tcb.emit_shortstring_const(parasym.realname); { write name of type of current parameter } - write_rtti_name(parasym.vardef); + write_rtti_name(tcb,parasym.vardef); end; end; @@ -755,13 +855,19 @@ implementation { only store user visible parameters } if not(vo_is_hidden_para in parasym.varoptions) then begin + { every parameter is expected to start aligned } + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rtti_proc_param]+tostr(length(parasym.realname)), + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { write flags for current parameter } write_param_flag(parasym); - maybe_write_align; { write param type } - write_rtti_reference(parasym.vardef,fullrtti); + write_rtti_reference(tcb,parasym.vardef,fullrtti); { write name of current parameter } - write_string(parasym.realname); + tcb.emit_shortstring_const(parasym.realname); + tcb.end_anonymous_record; end; end; @@ -772,8 +878,10 @@ implementation if po_methodpointer in def.procoptions then begin { write method id and name } - write_header(def,tkMethod); - maybe_write_align; + write_header(tcb,def,tkMethod); + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { write kind of method } case def.proctypeoption of @@ -800,11 +908,11 @@ implementation methodkind:=mkFunction; end; end; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(methodkind)); + tcb.emit_ord_const(methodkind,u8inttype); { write parameter info. The parameters must be written in reverse order if this method uses right to left parameter pushing! } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount)); + tcb.emit_ord_const(def.maxparacount,u8inttype); for i:=0 to def.paras.count-1 do write_para(tparavarsym(def.paras[i])); @@ -812,56 +920,57 @@ implementation if (methodkind=mkFunction) or (methodkind=mkClassFunction) then begin { write name of result type } - write_rtti_name(def.returndef); - maybe_write_align; + write_rtti_name(tcb,def.returndef); + { enclosing record takes care of alignment } { write result typeinfo } - write_rtti_reference(def.returndef,fullrtti); + write_rtti_reference(tcb,def.returndef,fullrtti); end; { write calling convention } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption])); - maybe_write_align; + tcb.emit_ord_const(ProcCallOptionToCallConv[def.proccalloption],u8inttype); + { enclosing record takes care of alignment } { write params typeinfo } for i:=0 to def.paras.count-1 do if not(vo_is_hidden_para in tparavarsym(def.paras[i]).varoptions) then - write_rtti_reference(tparavarsym(def.paras[i]).vardef,fullrtti); + write_rtti_reference(tcb,tparavarsym(def.paras[i]).vardef,fullrtti); + tcb.end_anonymous_record; end else begin - write_header(def,tkProcvar); - maybe_write_align; + write_header(tcb,def,tkProcvar); + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { flags } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0)); - //maybe_write_align; // aligning between bytes is not necessary + tcb.emit_ord_const(0,u8inttype); { write calling convention } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption])); - maybe_write_align; + tcb.emit_ord_const(ProcCallOptionToCallConv[def.proccalloption],u8inttype); + { enclosing record takes care of alignment } { write result typeinfo } - write_rtti_reference(def.returndef,fullrtti); + write_rtti_reference(tcb,def.returndef,fullrtti); { write parameter count } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount)); + tcb.emit_ord_const(def.maxparacount,u8inttype); for i:=0 to def.paras.count-1 do - begin - maybe_write_align; - write_procedure_param(tparavarsym(def.paras[i])); - end; + write_procedure_param(tparavarsym(def.paras[i])); + tcb.end_anonymous_record; end; end; - procedure objectdef_rtti(def:tobjectdef); + procedure objectdef_rtti(def: tobjectdef); procedure objectdef_rtti_fields(def:tobjectdef); begin - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size)); - fields_write_rtti_data(def,rt); + tcb.emit_ord_const(def.size, u32inttype); + { enclosing record takes care of alignment } + fields_write_rtti_data(tcb,def,rt); end; procedure objectdef_rtti_interface_init(def:tobjectdef); begin - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size)); + tcb.emit_ord_const(def.size, u32inttype); end; procedure objectdef_rtti_class_full(def:tobjectdef); @@ -874,38 +983,36 @@ implementation if not is_objectpascal_helper(def) then if (oo_has_vmt in def.objectoptions) then - current_asmdata.asmlists[al_rtti].concat(Tai_const.Createname(def.vmt_mangledname,AT_DATA,0)) + tcb.emit_tai( + Tai_const.Createname(def.vmt_mangledname,AT_DATA,0), + cpointerdef.getreusable(def.vmt_def)) else - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_nil_dataptr); + tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype); { write parent typeinfo } - write_rtti_reference(def.childof,fullrtti); + write_rtti_reference(tcb,def.childof,fullrtti); { write typeinfo of extended type } if is_objectpascal_helper(def) then if assigned(def.extendeddef) then - write_rtti_reference(def.extendeddef,fullrtti) + write_rtti_reference(tcb,def.extendeddef,fullrtti) else InternalError(2011033001); { total number of unique properties } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnamelist.count)); + tcb.emit_ord_const(propnamelist.count,u16inttype); { write unit name } - write_string(current_module.realmodulename^); - maybe_write_align; + tcb.emit_shortstring_const(current_module.realmodulename^); { write published properties for this object } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(published_properties_count(def.symtable))); - maybe_write_align; - published_properties_write_rtti_data(propnamelist,def.symtable); + published_properties_write_rtti_data(tcb,propnamelist,def.symtable); propnamelist.free; end; procedure objectdef_rtti_interface_full(def:tobjectdef); var - i : longint; propnamelist : TFPHashObjectList; { if changed to a set, make sure it's still a byte large, and swap appropriately when cross-compiling @@ -917,7 +1024,7 @@ implementation collect_propnamelist(propnamelist,def); { write parent typeinfo } - write_rtti_reference(def.childof,fullrtti); + write_rtti_reference(tcb,def.childof,fullrtti); { interface: write flags, iid and iidstr } IntfFlags:=0; @@ -931,27 +1038,31 @@ implementation IntfFlags:=reverse_byte(IntfFlags); { ifDispatch, } - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(IntfFlags)); - maybe_write_align; - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.iidguid^.D1))); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.iidguid^.D2)); - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.iidguid^.D3)); - for i:=Low(def.iidguid^.D4) to High(def.iidguid^.D4) do - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.iidguid^.D4[i])); + tcb.emit_ord_const(IntfFlags,u8inttype); + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + + tcb.emit_guid_const(def.iidguid^); { write unit name } - write_string(current_module.realmodulename^); - maybe_write_align; + tcb.emit_shortstring_const(current_module.realmodulename^); + + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); { write iidstr } if assigned(def.iidstr) then - write_string(def.iidstr^) + tcb.emit_shortstring_const(def.iidstr^) else - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0)); - maybe_write_align; + tcb.emit_shortstring_const(''); { write published properties for this object } - published_properties_write_rtti_data(propnamelist,def.symtable); + published_properties_write_rtti_data(tcb,propnamelist,def.symtable); + + tcb.end_anonymous_record; + tcb.end_anonymous_record; propnamelist.free; end; @@ -959,23 +1070,26 @@ implementation begin case def.objecttype of odt_class: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkclass)); + tcb.emit_ord_const(tkclass,u8inttype); odt_object: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkobject)); + tcb.emit_ord_const(tkobject,u8inttype); odt_dispinterface, odt_interfacecom: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterface)); + tcb.emit_ord_const(tkInterface,u8inttype); odt_interfacecorba: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterfaceCorba)); + tcb.emit_ord_const(tkinterfaceCorba,u8inttype); odt_helper: - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkhelper)); + tcb.emit_ord_const(tkhelper,u8inttype); else internalerror(200611034); end; { generate the name } - write_string(def.objrealname^); - maybe_write_align; + tcb.emit_shortstring_const(def.objrealname^); + + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); case rt of initrtti : @@ -998,6 +1112,7 @@ implementation end; end; end; + tcb.end_anonymous_record; end; begin @@ -1045,36 +1160,16 @@ implementation type Penumsym = ^Tenumsym; - function enumdef_rtti_calcstringtablestart(const def : Tenumdef) : integer; - begin - { the alignment calls must correspond to the ones used during generating the - actual data structure created elsewhere in this file } - result:=1; - if assigned(def.typesym) then - inc(result,length(def.typesym.realname)+1) - else - inc(result); - if (tf_requires_proper_alignment in target_info.flags) then - result:=align(result,sizeof(Tconstptruint)); - inc(result); - if (tf_requires_proper_alignment in target_info.flags) then - result:=align(result,sizeof(Tconstptruint)); - inc(result, sizeof(longint) * 2); - if (tf_requires_proper_alignment in target_info.flags) then - result:=align(result,sizeof(Tconstptruint)); - inc(result, sizeof(pint)); - end; - { Writes a helper table for accelerated conversion of ordinal enum values to strings. If you change something in this method, make sure to adapt the corresponding code in sstrings.inc. } - procedure enumdef_rtti_ord2stringindex(const sym_count:longint; const offsets:plongint; const syms:Penumsym; const st:longint); + procedure enumdef_rtti_ord2stringindex(rttidef: trecorddef; const sym_count:longint; {const offsets:plongint;} const syms:Penumsym{; const st:longint}); var rttilab:Tasmsymbol; h,i,o,prev_value:longint; mode:(lookup,search); {Modify with care, ordinal value of enum is written.} r:single; {Must be real type because of integer overflow risk.} - + tcb: ttai_typedconstbuilder; begin {Decide wether a lookup array is size efficient.} @@ -1110,73 +1205,107 @@ implementation end; { write rtti data; make sure that the alignment matches the corresponding data structure in the code that uses it (if alignment is required). } - with current_asmdata do + rttilab:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_GLOBAL,AT_DATA); + tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]); + { use TConstPtrUInt packrecords to ensure good alignment } + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + { now emit the data: first the mode } + tcb.emit_tai(Tai_const.create_32bit(longint(mode)),u32inttype); + { align } + tcb.begin_anonymous_record('',defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign); + if mode=lookup then begin - rttilab:=defineasmsymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_GLOBAL,AT_DATA); - maybe_new_object_file(asmlists[al_rtti]); - new_section(asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(pint))); - asmlists[al_rtti].concat(Tai_symbol.create_global(rttilab,0)); - asmlists[al_rtti].concat(Tai_const.create_32bit(longint(mode))); - if mode=lookup then + o:=syms[0].value; {Start with min value.} + for i:=0 to sym_count-1 do begin - maybe_write_align; - o:=syms[0].value; {Start with min value.} - for i:=0 to sym_count-1 do + while o=sym_alloc then begin reallocmem(syms,2*sym_alloc*sizeof(Tenumsym)); - reallocmem(offsets,2*sym_alloc*sizeof(longint)); sym_alloc:=sym_alloc*2; end; syms[sym_count]:=t; - offsets[sym_count]:=st; inc(sym_count); - st:=st+length(t.realname)+1; end; {Sort the syms by enum name} if sym_count>=2 then @@ -1224,22 +1349,23 @@ implementation begin i:=h; t:=syms[i]; - o:=offsets[i]; repeat if syms[i-p].name<=t.name then break; syms[i]:=syms[i-p]; - offsets[i]:=offsets[i-p]; dec(i,p); until irecorddef) then + internalerror(2015071402); + rttidef:=trecorddef(ttypesym(rttitypesym).typedef); + enumdef_rtti_string2ordindex(rttidef,sym_count,syms); { Sort the syms by enum value } if sym_count>=2 then begin @@ -1252,23 +1378,19 @@ implementation begin i:=h; t:=syms[i]; - o:=offsets[i]; repeat if syms[i-p].value<=t.value then break; syms[i]:=syms[i-p]; - offsets[i]:=offsets[i-p]; dec(i,p); until iinitrtti) and is_objc_class_or_protocol(def)) then - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_nil_dataptr) + tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype) else - current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def,rt))); + tcb.emit_tai(Tai_const.Create_sym(ref_rtti(def,rt)),voidpointertype); end; @@ -1335,7 +1468,9 @@ implementation procedure TRTTIWriter.write_rtti(def:tdef;rt:trttitype); var - rttilab : tasmsymbol; + tcb: ttai_typedconstbuilder; + rttilab: tasmsymbol; + rttidef: tdef; begin { only write rtti of definitions from the current module } if not findunitsymtable(def.owner).iscurrentunit then @@ -1350,16 +1485,37 @@ implementation { write first all dependencies } write_child_rtti_data(def,rt); { write rtti data } + tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]); rttilab:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(rt),AB_GLOBAL,AT_DATA); - maybe_new_object_file(current_asmdata.asmlists[al_rtti]); - new_section(current_asmdata.asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(pint))); - current_asmdata.asmlists[al_rtti].concat(Tai_symbol.Create_global(rttilab,0)); - write_rtti_data(def,rt); - current_asmdata.asmlists[al_rtti].concat(Tai_symbol_end.Create(rttilab)); + tcb.begin_anonymous_record( + internaltypeprefixName[itp_rttidef]+rttilab.Name, + defaultpacking,reqalign, + targetinfos[target_info.system]^.alignment.recordalignmin, + targetinfos[target_info.system]^.alignment.maxCrecordalign + ); + write_rtti_data(tcb,def,rt); + rttidef:=tcb.end_anonymous_record; + current_asmdata.AsmLists[al_rtti].concatList( + tcb.get_final_asmlist(rttilab,rttidef,sec_rodata,rttilab.name,const_align(sizeof(pint)))); write_rtti_extrasyms(def,rt,rttilab); end; + constructor TRTTIWriter.create; + begin + if tf_requires_proper_alignment in target_info.flags then + begin + reqalign:=sizeof(TConstPtrUInt); + defaultpacking:=C_alignment; + end + else + begin + reqalign:=1; + defaultpacking:=1; + end; + end; + + function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype):tasmsymbol; begin result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt),AT_DATA); diff --git a/compiler/symconst.pas b/compiler/symconst.pas index 2c55a101f4..379d425ff0 100644 --- a/compiler/symconst.pas +++ b/compiler/symconst.pas @@ -632,6 +632,7 @@ type { prefixes for internally generated type names (centralised to avoid accidental collisions) } tinternaltypeprefix = ( + itp_1byte, itp_llvmstruct, itp_vmtdef, itp_vmt_tstringmesssagetable, @@ -639,7 +640,17 @@ type itp_vmt_tmethod_name_table, itp_vmt_intern_msgint_table, itp_vmt_intern_tmethodnamerec, - itp_vmt_intern_tmethodnametable + itp_vmt_intern_tmethodnametable, + itp_rttidef, + itp_rtti_header, + itp_rtti_prop, + itp_rtti_ansistr, + itp_rtti_ord_outer, + itp_rtti_ord_inner, + itp_rtti_ord_64bit, + itp_rtti_normal_array, + itp_rtti_dyn_array, + itp_rtti_proc_param ); { The order is from low priority to high priority, @@ -742,6 +753,7 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has ); internaltypeprefixName : array[tinternaltypeprefix] of TSymStr = ( + '$1byte$', '$llvmstruct$', '$vmtdef$', '$vmt_TStringMesssageTable$', @@ -749,7 +761,17 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has '$vmt_tmethod_name_table$', '$vmt_intern_msgint_table$', '$vmt_intern_tmethodnamerec$', - '$vmt_intern_tmethodnametable$' + '$vmt_intern_tmethodnametable$', + '$rttidef$', + '$rtti_header$', + '$rtti_prop$', + '$rtti_ansistr$', + '$rtti_ord_outer$', + '$rtti_ord_inner$', + '$rtti_ord_64bit$', + '$rtti_normal_array$', + '$rtti_dyn_array$', + '$rtti_proc_param$' );