ncgrtti.pas 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Routines for the code generation of RTTI data structures
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit ncgrtti;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,
  22. aasmbase,
  23. symbase,symconst,symtype,symdef;
  24. type
  25. { TRTTIWriter }
  26. TRTTIWriter=class
  27. private
  28. function fields_count(st:tsymtable;rt:trttitype):longint;
  29. procedure fields_write_rtti(st:tsymtable;rt:trttitype);
  30. procedure fields_write_rtti_data(st:tsymtable;rt:trttitype);
  31. procedure write_rtti_extrasyms(def:Tdef;rt:Trttitype;mainrtti:Tasmsymbol);
  32. procedure published_write_rtti(st:tsymtable;rt:trttitype);
  33. function published_properties_count(st:tsymtable):longint;
  34. procedure published_properties_write_rtti_data(propnamelist:TFPHashObjectList;st:tsymtable);
  35. procedure collect_propnamelist(propnamelist:TFPHashObjectList;objdef:tobjectdef);
  36. procedure write_rtti_name(def:tdef);
  37. procedure write_rtti_data(def:tdef;rt:trttitype);
  38. procedure write_child_rtti_data(def:tdef;rt:trttitype);
  39. function ref_rtti(def:tdef;rt:trttitype):tasmsymbol;
  40. public
  41. procedure write_rtti(def:tdef;rt:trttitype);
  42. function get_rtti_label(def:tdef;rt:trttitype):tasmsymbol;
  43. function get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol;
  44. function get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
  45. end;
  46. var
  47. RTTIWriter : TRTTIWriter;
  48. implementation
  49. uses
  50. cutils,
  51. globals,globtype,verbose,systems,
  52. fmodule,
  53. symsym,
  54. aasmtai,aasmdata
  55. ;
  56. const
  57. rttidefstate : array[trttitype] of tdefstate = (ds_rtti_table_written,ds_init_table_written);
  58. type
  59. TPropNameListItem = class(TFPHashObject)
  60. propindex : longint;
  61. propowner : TSymtable;
  62. end;
  63. {***************************************************************************
  64. TRTTIWriter
  65. ***************************************************************************}
  66. procedure TRTTIWriter.write_rtti_name(def:tdef);
  67. var
  68. hs : string;
  69. begin
  70. { name }
  71. if assigned(def.typesym) then
  72. begin
  73. hs:=ttypesym(def.typesym).realname;
  74. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(chr(length(hs))+hs));
  75. end
  76. else
  77. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(#0));
  78. end;
  79. function TRTTIWriter.fields_count(st:tsymtable;rt:trttitype):longint;
  80. var
  81. i : longint;
  82. sym : tsym;
  83. begin
  84. result:=0;
  85. for i:=0 to st.SymList.Count-1 do
  86. begin
  87. sym:=tsym(st.SymList[i]);
  88. if (rt=fullrtti) or
  89. (
  90. (tsym(sym).typ=fieldvarsym) and
  91. tfieldvarsym(sym).vardef.needs_inittable
  92. ) then
  93. inc(result);
  94. end;
  95. end;
  96. procedure TRTTIWriter.fields_write_rtti_data(st:tsymtable;rt:trttitype);
  97. var
  98. i : longint;
  99. sym : tsym;
  100. begin
  101. for i:=0 to st.SymList.Count-1 do
  102. begin
  103. sym:=tsym(st.SymList[i]);
  104. if (rt=fullrtti) or
  105. (
  106. (tsym(sym).typ=fieldvarsym) and
  107. tfieldvarsym(sym).vardef.needs_inittable
  108. ) then
  109. begin
  110. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(tfieldvarsym(sym).vardef,rt)));
  111. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tfieldvarsym(sym).fieldoffset));
  112. end;
  113. end;
  114. end;
  115. procedure TRTTIWriter.fields_write_rtti(st:tsymtable;rt:trttitype);
  116. var
  117. i : longint;
  118. sym : tsym;
  119. begin
  120. for i:=0 to st.SymList.Count-1 do
  121. begin
  122. sym:=tsym(st.SymList[i]);
  123. if (rt=fullrtti) or
  124. (
  125. (tsym(sym).typ=fieldvarsym) and
  126. tfieldvarsym(sym).vardef.needs_inittable
  127. ) then
  128. write_rtti(tfieldvarsym(sym).vardef,rt);
  129. end;
  130. end;
  131. procedure TRTTIWriter.published_write_rtti(st:tsymtable;rt:trttitype);
  132. var
  133. i : longint;
  134. sym : tsym;
  135. begin
  136. for i:=0 to st.SymList.Count-1 do
  137. begin
  138. sym:=tsym(st.SymList[i]);
  139. if (sp_published in tsym(sym).symoptions) then
  140. begin
  141. case tsym(sym).typ of
  142. propertysym:
  143. write_rtti(tpropertysym(sym).propdef,rt);
  144. fieldvarsym:
  145. write_rtti(tfieldvarsym(sym).vardef,rt);
  146. end;
  147. end;
  148. end;
  149. end;
  150. function TRTTIWriter.published_properties_count(st:tsymtable):longint;
  151. var
  152. i : longint;
  153. sym : tsym;
  154. begin
  155. result:=0;
  156. for i:=0 to st.SymList.Count-1 do
  157. begin
  158. sym:=tsym(st.SymList[i]);
  159. if (tsym(sym).typ=propertysym) and
  160. (sp_published in tsym(sym).symoptions) then
  161. inc(result);
  162. end;
  163. end;
  164. procedure TRTTIWriter.collect_propnamelist(propnamelist:TFPHashObjectList;objdef:tobjectdef);
  165. var
  166. i : longint;
  167. sym : tsym;
  168. pn : tpropnamelistitem;
  169. begin
  170. if assigned(objdef.childof) then
  171. collect_propnamelist(propnamelist,objdef.childof);
  172. for i:=0 to objdef.symtable.SymList.Count-1 do
  173. begin
  174. sym:=tsym(objdef.symtable.SymList[i]);
  175. if (tsym(sym).typ=propertysym) and
  176. (sp_published in tsym(sym).symoptions) then
  177. begin
  178. pn:=TPropNameListItem(propnamelist.Find(tsym(sym).name));
  179. if not assigned(pn) then
  180. begin
  181. pn:=tpropnamelistitem.create(propnamelist,tsym(sym).name);
  182. pn.propindex:=propnamelist.count-1;
  183. pn.propowner:=tsym(sym).owner;
  184. end;
  185. end;
  186. end;
  187. end;
  188. procedure TRTTIWriter.published_properties_write_rtti_data(propnamelist:TFPHashObjectList;st:tsymtable);
  189. var
  190. i : longint;
  191. sym : tsym;
  192. proctypesinfo : byte;
  193. propnameitem : tpropnamelistitem;
  194. procedure writeaccessproc(pap:tpropaccesslisttypes; shiftvalue : byte; unsetvalue: byte);
  195. var
  196. typvalue : byte;
  197. hp : ppropaccesslistitem;
  198. address,space : longint;
  199. def : tdef;
  200. hpropsym : tpropertysym;
  201. propaccesslist : tpropaccesslist;
  202. begin
  203. hpropsym:=tpropertysym(sym);
  204. repeat
  205. propaccesslist:=hpropsym.propaccesslist[pap];
  206. if not propaccesslist.empty then
  207. break;
  208. hpropsym:=hpropsym.overridenpropsym;
  209. until not assigned(hpropsym);
  210. if not(assigned(propaccesslist) and assigned(propaccesslist.firstsym)) then
  211. begin
  212. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,unsetvalue));
  213. typvalue:=3;
  214. end
  215. else if propaccesslist.firstsym^.sym.typ=fieldvarsym then
  216. begin
  217. address:=0;
  218. hp:=propaccesslist.firstsym;
  219. def:=nil;
  220. while assigned(hp) do
  221. begin
  222. case hp^.sltype of
  223. sl_load :
  224. begin
  225. def:=tfieldvarsym(hp^.sym).vardef;
  226. inc(address,tfieldvarsym(hp^.sym).fieldoffset);
  227. end;
  228. sl_subscript :
  229. begin
  230. if not(assigned(def) and (def.typ=recorddef)) then
  231. internalerror(200402171);
  232. inc(address,tfieldvarsym(hp^.sym).fieldoffset);
  233. def:=tfieldvarsym(hp^.sym).vardef;
  234. end;
  235. sl_vec :
  236. begin
  237. if not(assigned(def) and (def.typ=arraydef)) then
  238. internalerror(200402172);
  239. def:=tarraydef(def).elementdef;
  240. {Hp.value is a Tconstexprint, which can be rather large,
  241. sanity check for longint overflow.}
  242. space:=(high(address)-address) div def.size;
  243. if int64(space)<hp^.value then
  244. internalerror(200706101);
  245. inc(address,int64(def.size*hp^.value));
  246. end;
  247. end;
  248. hp:=hp^.next;
  249. end;
  250. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,address));
  251. typvalue:=0;
  252. end
  253. else
  254. begin
  255. { When there was an error then procdef is not assigned }
  256. if not assigned(propaccesslist.procdef) then
  257. exit;
  258. if not(po_virtualmethod in tprocdef(propaccesslist.procdef).procoptions) then
  259. begin
  260. current_asmdata.asmlists[al_rtti].concat(Tai_const.createname(tprocdef(propaccesslist.procdef).mangledname,0));
  261. typvalue:=1;
  262. end
  263. else
  264. begin
  265. { virtual method, write vmt offset }
  266. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,
  267. tprocdef(propaccesslist.procdef)._class.vmtmethodoffset(tprocdef(propaccesslist.procdef).extnumber)));
  268. typvalue:=2;
  269. end;
  270. end;
  271. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  272. end;
  273. begin
  274. for i:=0 to st.SymList.Count-1 do
  275. begin
  276. sym:=tsym(st.SymList[i]);
  277. if (sym.typ=propertysym) and
  278. (sp_published in sym.symoptions) then
  279. begin
  280. if ppo_indexed in tpropertysym(sym).propoptions then
  281. proctypesinfo:=$40
  282. else
  283. proctypesinfo:=0;
  284. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(tpropertysym(sym).propdef,fullrtti)));
  285. writeaccessproc(palt_read,0,0);
  286. writeaccessproc(palt_write,2,0);
  287. { is it stored ? }
  288. if not(ppo_stored in tpropertysym(sym).propoptions) then
  289. begin
  290. { no, so put a constant zero }
  291. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,0));
  292. proctypesinfo:=proctypesinfo or (3 shl 4);
  293. end
  294. else
  295. writeaccessproc(palt_stored,4,1); { maybe; if no procedure put a constant 1 (=true) }
  296. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tpropertysym(sym).index));
  297. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tpropertysym(sym).default));
  298. propnameitem:=TPropNameListItem(propnamelist.Find(tpropertysym(sym).name));
  299. if not assigned(propnameitem) then
  300. internalerror(200512201);
  301. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnameitem.propindex));
  302. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(proctypesinfo));
  303. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(tpropertysym(sym).realname)));
  304. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(tpropertysym(sym).realname));
  305. if (tf_requires_proper_alignment in target_info.flags) then
  306. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  307. end;
  308. end;
  309. end;
  310. procedure TRTTIWriter.write_rtti_data(def:tdef;rt:trttitype);
  311. procedure unknown_rtti(def:tstoreddef);
  312. begin
  313. current_asmdata.asmlists[al_rtti].concat(tai_const.create_8bit(tkUnknown));
  314. write_rtti_name(def);
  315. end;
  316. procedure variantdef_rtti(def:tvariantdef);
  317. begin
  318. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkVariant));
  319. end;
  320. procedure stringdef_rtti(def:tstringdef);
  321. begin
  322. case def.stringtype of
  323. st_ansistring:
  324. begin
  325. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkAString));
  326. write_rtti_name(def);
  327. end;
  328. st_widestring:
  329. begin
  330. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkWString));
  331. write_rtti_name(def);
  332. end;
  333. st_longstring:
  334. begin
  335. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkLString));
  336. write_rtti_name(def);
  337. end;
  338. st_shortstring:
  339. begin
  340. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkSString));
  341. write_rtti_name(def);
  342. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.len));
  343. if (tf_requires_proper_alignment in target_info.flags) then
  344. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  345. end;
  346. end;
  347. end;
  348. procedure enumdef_rtti(def:tenumdef);
  349. var
  350. hp : tenumsym;
  351. begin
  352. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkEnumeration));
  353. write_rtti_name(def);
  354. if (tf_requires_proper_alignment in target_info.flags) then
  355. current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(sizeof(TConstPtrUInt)));
  356. case longint(def.size) of
  357. 1 :
  358. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte));
  359. 2 :
  360. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord));
  361. 4 :
  362. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
  363. end;
  364. if (tf_requires_proper_alignment in target_info.flags) then
  365. current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(sizeof(TConstPtrUInt)));
  366. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.min));
  367. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.max));
  368. if assigned(def.basedef) then
  369. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.basedef,rt)))
  370. else
  371. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  372. hp:=tenumsym(def.firstenum);
  373. while assigned(hp) do
  374. begin
  375. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(hp.realname)));
  376. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(hp.realname));
  377. hp:=hp.nextenum;
  378. end;
  379. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  380. end;
  381. procedure orddef_rtti(def:torddef);
  382. procedure dointeger;
  383. const
  384. trans : array[tordtype] of byte =
  385. (otUByte{otNone},
  386. otUByte,otUWord,otULong,otUByte{otNone},
  387. otSByte,otSWord,otSLong,otUByte{otNone},
  388. otUByte,otUWord,otULong,otUByte,
  389. otUByte,otUWord,otUByte);
  390. begin
  391. write_rtti_name(def);
  392. if (tf_requires_proper_alignment in target_info.flags) then
  393. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  394. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(byte(trans[def.ordtype])));
  395. if (tf_requires_proper_alignment in target_info.flags) then
  396. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  397. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.low)));
  398. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.high)));
  399. end;
  400. begin
  401. case def.ordtype of
  402. s64bit :
  403. begin
  404. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkInt64));
  405. write_rtti_name(def);
  406. if (tf_requires_proper_alignment in target_info.flags) then
  407. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  408. { low }
  409. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(int64($80000000) shl 32));
  410. { high }
  411. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit((int64($7fffffff) shl 32) or int64($ffffffff)));
  412. end;
  413. u64bit :
  414. begin
  415. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkQWord));
  416. write_rtti_name(def);
  417. if (tf_requires_proper_alignment in target_info.flags) then
  418. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  419. { low }
  420. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(0));
  421. { high }
  422. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(int64((int64($ffffffff) shl 32) or int64($ffffffff))));
  423. end;
  424. bool8bit:
  425. begin
  426. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkBool));
  427. dointeger;
  428. end;
  429. uchar:
  430. begin
  431. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkChar));
  432. dointeger;
  433. end;
  434. uwidechar:
  435. begin
  436. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkWChar));
  437. dointeger;
  438. end;
  439. else
  440. begin
  441. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkInteger));
  442. dointeger;
  443. end;
  444. end;
  445. end;
  446. procedure floatdef_rtti(def:tfloatdef);
  447. const
  448. {tfloattype = (s32real,s64real,s80real,s64bit,s128bit);}
  449. translate : array[tfloattype] of byte =
  450. (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,ftFloat128);
  451. begin
  452. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkFloat));
  453. write_rtti_name(def);
  454. if (tf_requires_proper_alignment in target_info.flags) then
  455. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  456. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(translate[def.floattype]));
  457. end;
  458. procedure setdef_rtti(def:tsetdef);
  459. begin
  460. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkSet));
  461. write_rtti_name(def);
  462. if (tf_requires_proper_alignment in target_info.flags) then
  463. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  464. case def.size of
  465. 1:
  466. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte));
  467. 2:
  468. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord));
  469. 4:
  470. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
  471. end;
  472. if (tf_requires_proper_alignment in target_info.flags) then
  473. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  474. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.elementdef,rt)));
  475. end;
  476. procedure arraydef_rtti(def:tarraydef);
  477. begin
  478. if ado_IsDynamicArray in def.arrayoptions then
  479. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkdynarray))
  480. else
  481. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkarray));
  482. write_rtti_name(def);
  483. if (tf_requires_proper_alignment in target_info.flags) then
  484. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  485. { size of elements }
  486. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_aint(def.elesize));
  487. if not(ado_IsDynamicArray in def.arrayoptions) then
  488. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_aint(aint(def.elecount)));
  489. { element type }
  490. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.elementdef,rt)));
  491. { variant type }
  492. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tstoreddef(def.elementdef).getvardef));
  493. end;
  494. procedure recorddef_rtti(def:trecorddef);
  495. var
  496. fieldcnt : longint;
  497. begin
  498. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkrecord));
  499. write_rtti_name(def);
  500. if (tf_requires_proper_alignment in target_info.flags) then
  501. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  502. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size));
  503. fieldcnt:=fields_count(def.symtable,rt);
  504. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(fieldcnt));
  505. fields_write_rtti_data(def.symtable,rt);
  506. end;
  507. procedure procvardef_rtti(def:tprocvardef);
  508. procedure write_para(parasym:tparavarsym);
  509. var
  510. paraspec : byte;
  511. begin
  512. { only store user visible parameters }
  513. if not(vo_is_hidden_para in parasym.varoptions) then
  514. begin
  515. case parasym.varspez of
  516. vs_value: paraspec := 0;
  517. vs_const: paraspec := pfConst;
  518. vs_var : paraspec := pfVar;
  519. vs_out : paraspec := pfOut;
  520. end;
  521. { write flags for current parameter }
  522. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(paraspec));
  523. { write name of current parameter }
  524. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(parasym.realname)));
  525. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(parasym.realname));
  526. { write name of type of current parameter }
  527. write_rtti_name(parasym.vardef);
  528. end;
  529. end;
  530. var
  531. methodkind : byte;
  532. i : integer;
  533. begin
  534. if po_methodpointer in def.procoptions then
  535. begin
  536. { write method id and name }
  537. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkmethod));
  538. write_rtti_name(def);
  539. if (tf_requires_proper_alignment in target_info.flags) then
  540. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  541. { write kind of method (can only be function or procedure)}
  542. if def.returndef = voidtype then
  543. methodkind := mkProcedure
  544. else
  545. methodkind := mkFunction;
  546. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(methodkind));
  547. { write parameter info. The parameters must be written in reverse order
  548. if this method uses right to left parameter pushing! }
  549. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount));
  550. if def.proccalloption in pushleftright_pocalls then
  551. begin
  552. for i:=0 to def.paras.count-1 do
  553. write_para(tparavarsym(def.paras[i]));
  554. end
  555. else
  556. begin
  557. for i:=def.paras.count-1 downto 0 do
  558. write_para(tparavarsym(def.paras[i]));
  559. end;
  560. { write name of result type }
  561. write_rtti_name(def.returndef);
  562. end
  563. else
  564. begin
  565. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkprocvar));
  566. write_rtti_name(def);
  567. end;
  568. end;
  569. procedure objectdef_rtti(def:tobjectdef);
  570. procedure objectdef_rtti_class_init(def:tobjectdef);
  571. begin
  572. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size));
  573. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(fields_count(def.symtable,rt)));
  574. fields_write_rtti_data(def.symtable,rt);
  575. end;
  576. procedure objectdef_rtti_interface_init(def:tobjectdef);
  577. begin
  578. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size));
  579. end;
  580. procedure objectdef_rtti_class_full(def:tobjectdef);
  581. var
  582. propnamelist : TFPHashObjectList;
  583. begin
  584. { Collect unique property names with nameindex }
  585. propnamelist:=TFPHashObjectList.Create;
  586. collect_propnamelist(propnamelist,def);
  587. if (oo_has_vmt in def.objectoptions) then
  588. current_asmdata.asmlists[al_rtti].concat(Tai_const.Createname(def.vmt_mangledname,0))
  589. else
  590. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  591. { write parent typeinfo }
  592. if assigned(def.childof) and
  593. (oo_can_have_published in def.childof.objectoptions) then
  594. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.childof,fullrtti)))
  595. else
  596. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  597. { total number of unique properties }
  598. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnamelist.count));
  599. { write unit name }
  600. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  601. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(current_module.realmodulename^));
  602. if (tf_requires_proper_alignment in target_info.flags) then
  603. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  604. { write published properties for this object }
  605. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(published_properties_count(def.symtable)));
  606. if (tf_requires_proper_alignment in target_info.flags) then
  607. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  608. published_properties_write_rtti_data(propnamelist,def.symtable);
  609. propnamelist.free;
  610. end;
  611. procedure objectdef_rtti_interface_full(def:tobjectdef);
  612. var
  613. i : longint;
  614. propnamelist : TFPHashObjectList;
  615. begin
  616. { Collect unique property names with nameindex }
  617. propnamelist:=TFPHashObjectList.Create;
  618. collect_propnamelist(propnamelist,def);
  619. { write parent typeinfo }
  620. if assigned(def.childof) then
  621. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.childof,fullrtti)))
  622. else
  623. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  624. { interface: write flags, iid and iidstr }
  625. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(
  626. { ugly, but working }
  627. {$ifdef USE_PACKSET1}
  628. byte([
  629. {$else USE_PACKSET1}
  630. longint([
  631. {$endif USE_PACKSET1}
  632. TCompilerIntfFlag(ord(ifHasGuid)*ord(assigned(def.iidguid))),
  633. TCompilerIntfFlag(ord(ifHasStrGUID)*ord(assigned(def.iidstr))),
  634. TCompilerIntfFlag(ord(ifDispInterface)*ord(def.objecttype=odt_dispinterface))
  635. ])
  636. {
  637. ifDispatch, }
  638. ));
  639. if (tf_requires_proper_alignment in target_info.flags) then
  640. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  641. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.iidguid^.D1)));
  642. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.iidguid^.D2));
  643. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.iidguid^.D3));
  644. for i:=Low(def.iidguid^.D4) to High(def.iidguid^.D4) do
  645. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.iidguid^.D4[i]));
  646. { write unit name }
  647. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  648. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(current_module.realmodulename^));
  649. if (tf_requires_proper_alignment in target_info.flags) then
  650. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  651. { write iidstr }
  652. if assigned(def.iidstr) then
  653. begin
  654. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(def.iidstr^)));
  655. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(def.iidstr^));
  656. end
  657. else
  658. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  659. if (tf_requires_proper_alignment in target_info.flags) then
  660. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  661. { write published properties for this object }
  662. published_properties_write_rtti_data(propnamelist,def.symtable);
  663. propnamelist.free;
  664. end;
  665. begin
  666. case def.objecttype of
  667. odt_class:
  668. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkclass));
  669. odt_object:
  670. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkobject));
  671. odt_dispinterface,
  672. odt_interfacecom:
  673. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterface));
  674. odt_interfacecorba:
  675. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterfaceCorba));
  676. else
  677. internalerror(200611034);
  678. end;
  679. { generate the name }
  680. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(def.objrealname^)));
  681. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(def.objrealname^));
  682. if (tf_requires_proper_alignment in target_info.flags) then
  683. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  684. case rt of
  685. initrtti :
  686. begin
  687. if def.objecttype in [odt_class,odt_object] then
  688. objectdef_rtti_class_init(def)
  689. else
  690. objectdef_rtti_interface_init(def);
  691. end;
  692. fullrtti :
  693. begin
  694. if def.objecttype in [odt_class,odt_object] then
  695. objectdef_rtti_class_full(def)
  696. else
  697. objectdef_rtti_interface_full(def);
  698. end;
  699. end;
  700. end;
  701. begin
  702. case def.typ of
  703. variantdef :
  704. variantdef_rtti(tvariantdef(def));
  705. stringdef :
  706. stringdef_rtti(tstringdef(def));
  707. enumdef :
  708. enumdef_rtti(tenumdef(def));
  709. orddef :
  710. orddef_rtti(torddef(def));
  711. floatdef :
  712. floatdef_rtti(tfloatdef(def));
  713. setdef :
  714. setdef_rtti(tsetdef(def));
  715. procvardef :
  716. procvardef_rtti(tprocvardef(def));
  717. arraydef :
  718. begin
  719. if ado_IsBitPacked in tarraydef(def).arrayoptions then
  720. unknown_rtti(tstoreddef(def))
  721. else
  722. arraydef_rtti(tarraydef(def));
  723. end;
  724. recorddef :
  725. begin
  726. if trecorddef(def).is_packed then
  727. unknown_rtti(tstoreddef(def))
  728. else
  729. recorddef_rtti(trecorddef(def));
  730. end;
  731. objectdef :
  732. objectdef_rtti(tobjectdef(def));
  733. else
  734. unknown_rtti(tstoreddef(def));
  735. end;
  736. end;
  737. procedure TRTTIWriter.write_rtti_extrasyms(def:Tdef;rt:Trttitype;mainrtti:Tasmsymbol);
  738. procedure enumdef_rtti_ord2stringindex(def:Tenumdef);
  739. var rttilab:Tasmsymbol;
  740. t:Tenumsym;
  741. syms:^Tenumsym;
  742. offsets:^longint;
  743. sym_count,sym_alloc:longint;
  744. h,i,p,o,st:longint;
  745. mode:(lookup,search); {Modify with care, ordinal value of enum is written.}
  746. r:single; {Must be real type because of integer overflow risk.}
  747. begin
  748. {Random access needed, put in array.}
  749. getmem(syms,64*sizeof(Tenumsym));
  750. getmem(offsets,64*sizeof(longint));
  751. sym_count:=0;
  752. sym_alloc:=64;
  753. st:=0;
  754. t:=Tenumsym(def.firstenum);
  755. while assigned(t) do
  756. begin
  757. if sym_count>=sym_alloc then
  758. begin
  759. reallocmem(syms,2*sym_alloc*sizeof(Tenumsym));
  760. reallocmem(offsets,2*sym_alloc*sizeof(longint));
  761. sym_alloc:=sym_alloc*2;
  762. end;
  763. syms[sym_count]:=t;
  764. offsets[sym_count]:=st;
  765. inc(sym_count);
  766. st:=st+length(t.realname)+1;
  767. t:=t.nextenum;
  768. end;
  769. {Sort the syms by enum value}
  770. if sym_count>=2 then
  771. begin
  772. p:=1;
  773. while 2*p<sym_count do
  774. p:=2*p;
  775. while p<>0 do
  776. begin
  777. for h:=p to sym_count-1 do
  778. begin
  779. i:=h;
  780. t:=syms[i];
  781. o:=offsets[i];
  782. repeat
  783. if syms[i-p].value<=t.value then
  784. break;
  785. syms[i]:=syms[i-p];
  786. offsets[i]:=offsets[i-p];
  787. dec(i,p);
  788. until i<p;
  789. syms[i]:=t;
  790. offsets[i]:=o;
  791. end;
  792. p:=p shr 1;
  793. end;
  794. end;
  795. {Decide wether a lookup array is size efficient.}
  796. mode:=lookup;
  797. if sym_count>0 then
  798. begin
  799. i:=1;
  800. r:=0;
  801. h:=syms[0].value; {Next expected enum value is min.}
  802. while i<sym_count do
  803. begin
  804. {Calculate size of hole between values. Avoid integer overflows.}
  805. r:=r+(single(syms[i].value)-single(h))-1;
  806. h:=syms[i].value;
  807. inc(i);
  808. end;
  809. if r>sym_count then
  810. mode:=search; {Don't waste more than 50% space.}
  811. end;
  812. {Calculate start of string table.}
  813. st:=1;
  814. if assigned(def.typesym) then
  815. inc(st,length(def.typesym.realname)+1)
  816. else
  817. inc(st);
  818. if (tf_requires_proper_alignment in target_info.flags) then
  819. align(st,sizeof(Tconstptruint));
  820. inc(st);
  821. if (tf_requires_proper_alignment in target_info.flags) then
  822. align(st,sizeof(Tconstptruint));
  823. inc(st,8+sizeof(aint));
  824. { write rtti data }
  825. with current_asmdata do
  826. begin
  827. rttilab:=defineasmsymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_GLOBAL,AT_DATA);
  828. maybe_new_object_file(asmlists[al_rtti]);
  829. new_section(asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(aint)));
  830. asmlists[al_rtti].concat(Tai_symbol.create_global(rttilab,0));
  831. asmlists[al_rtti].concat(Tai_const.create_32bit(longint(mode)));
  832. if mode=lookup then
  833. begin
  834. o:=syms[0].value; {Start with min value.}
  835. for i:=0 to sym_count-1 do
  836. begin
  837. while o<syms[i].value do
  838. begin
  839. asmlists[al_rtti].concat(Tai_const.create_aint(0));
  840. inc(o);
  841. end;
  842. inc(o);
  843. asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
  844. end;
  845. end
  846. else
  847. begin
  848. asmlists[al_rtti].concat(Tai_const.create_32bit(sym_count));
  849. for i:=0 to sym_count-1 do
  850. begin
  851. asmlists[al_rtti].concat(Tai_const.create_32bit(syms[i].value));
  852. asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
  853. end;
  854. end;
  855. asmlists[al_rtti].concat(Tai_symbol_end.create(rttilab));
  856. end;
  857. dispose(syms);
  858. dispose(offsets);
  859. end;
  860. procedure enumdef_rtti_string2ordindex(def:Tenumdef);
  861. var rttilab:Tasmsymbol;
  862. t:Tenumsym;
  863. syms:^Tenumsym;
  864. offsets:^longint;
  865. sym_count,sym_alloc:longint;
  866. h,i,p,o,st:longint;
  867. begin
  868. {Random access needed, put in array.}
  869. getmem(syms,64*sizeof(Tenumsym));
  870. getmem(offsets,64*sizeof(longint));
  871. sym_count:=0;
  872. sym_alloc:=64;
  873. st:=0;
  874. t:=Tenumsym(def.firstenum);
  875. while assigned(t) do
  876. begin
  877. if sym_count>=sym_alloc then
  878. begin
  879. reallocmem(syms,2*sym_alloc*sizeof(Tenumsym));
  880. reallocmem(offsets,2*sym_alloc*sizeof(longint));
  881. sym_alloc:=sym_alloc*2;
  882. end;
  883. syms[sym_count]:=t;
  884. offsets[sym_count]:=st;
  885. inc(sym_count);
  886. st:=st+length(t.realname)+1;
  887. t:=t.nextenum;
  888. end;
  889. {Sort the syms by enum name}
  890. if sym_count>=2 then
  891. begin
  892. p:=1;
  893. while 2*p<sym_count do
  894. p:=2*p;
  895. while p<>0 do
  896. begin
  897. for h:=p to sym_count-1 do
  898. begin
  899. i:=h;
  900. t:=syms[i];
  901. o:=offsets[i];
  902. repeat
  903. if syms[i-p].name<=t.name then
  904. break;
  905. syms[i]:=syms[i-p];
  906. offsets[i]:=offsets[i-p];
  907. dec(i,p);
  908. until i<p;
  909. syms[i]:=t;
  910. offsets[i]:=o;
  911. end;
  912. p:=p shr 1;
  913. end;
  914. end;
  915. {Calculate start of string table.}
  916. st:=1;
  917. if assigned(def.typesym) then
  918. inc(st,length(def.typesym.realname)+1)
  919. else
  920. inc(st);
  921. if (tf_requires_proper_alignment in target_info.flags) then
  922. align(st,sizeof(Tconstptruint));
  923. inc(st);
  924. if (tf_requires_proper_alignment in target_info.flags) then
  925. align(st,sizeof(Tconstptruint));
  926. inc(st,8+sizeof(aint));
  927. { write rtti data }
  928. with current_asmdata do
  929. begin
  930. rttilab:=defineasmsymbol(Tstoreddef(def).rtti_mangledname(rt)+'_s2o',AB_GLOBAL,AT_DATA);
  931. maybe_new_object_file(asmlists[al_rtti]);
  932. new_section(asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(aint)));
  933. asmlists[al_rtti].concat(Tai_symbol.create_global(rttilab,0));
  934. asmlists[al_rtti].concat(Tai_const.create_32bit(sym_count));
  935. for i:=0 to sym_count-1 do
  936. begin
  937. asmlists[al_rtti].concat(Tai_const.create_32bit(syms[i].value));
  938. asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
  939. end;
  940. asmlists[al_rtti].concat(Tai_symbol_end.create(rttilab));
  941. end;
  942. dispose(syms);
  943. dispose(offsets);
  944. end;
  945. begin
  946. case def.typ of
  947. enumdef:
  948. if rt=fullrtti then
  949. begin
  950. enumdef_rtti_ord2stringindex(Tenumdef(def));
  951. enumdef_rtti_string2ordindex(Tenumdef(def));
  952. end;
  953. end;
  954. end;
  955. procedure TRTTIWriter.write_child_rtti_data(def:tdef;rt:trttitype);
  956. begin
  957. case def.typ of
  958. enumdef :
  959. if assigned(tenumdef(def).basedef) then
  960. write_rtti(tenumdef(def).basedef,rt);
  961. setdef :
  962. write_rtti(tsetdef(def).elementdef,rt);
  963. arraydef :
  964. write_rtti(tarraydef(def).elementdef,rt);
  965. recorddef :
  966. fields_write_rtti(trecorddef(def).symtable,rt);
  967. objectdef :
  968. begin
  969. if assigned(tobjectdef(def).childof) then
  970. write_rtti(tobjectdef(def).childof,rt);
  971. if rt=initrtti then
  972. fields_write_rtti(tobjectdef(def).symtable,rt)
  973. else
  974. published_write_rtti(tobjectdef(def).symtable,rt);
  975. end;
  976. end;
  977. end;
  978. function TRTTIWriter.ref_rtti(def:tdef;rt:trttitype):tasmsymbol;
  979. begin
  980. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt));
  981. end;
  982. procedure TRTTIWriter.write_rtti(def:tdef;rt:trttitype);
  983. var
  984. rttilab : tasmsymbol;
  985. begin
  986. { only write rtti of definitions from the current module }
  987. if not findunitsymtable(def.owner).iscurrentunit then
  988. exit;
  989. { prevent recursion }
  990. if rttidefstate[rt] in def.defstates then
  991. exit;
  992. include(def.defstates,rttidefstate[rt]);
  993. { write first all dependencies }
  994. write_child_rtti_data(def,rt);
  995. { write rtti data }
  996. rttilab:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(rt),AB_GLOBAL,AT_DATA);
  997. maybe_new_object_file(current_asmdata.asmlists[al_rtti]);
  998. new_section(current_asmdata.asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(aint)));
  999. current_asmdata.asmlists[al_rtti].concat(Tai_symbol.Create_global(rttilab,0));
  1000. write_rtti_data(def,rt);
  1001. current_asmdata.asmlists[al_rtti].concat(Tai_symbol_end.Create(rttilab));
  1002. write_rtti_extrasyms(def,rt,rttilab);
  1003. end;
  1004. function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype):tasmsymbol;
  1005. begin
  1006. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt));
  1007. end;
  1008. function TRTTIWriter.get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol;
  1009. begin
  1010. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_o2s');
  1011. end;
  1012. function TRTTIWriter.get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
  1013. begin
  1014. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_s2o');
  1015. end;
  1016. end.