ncgrtti.pas 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  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,constexp,
  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. current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(cshortstringtype.alignment));
  354. write_rtti_name(def);
  355. if (tf_requires_proper_alignment in target_info.flags) then
  356. current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(sizeof(TConstPtrUInt)));
  357. case longint(def.size) of
  358. 1 :
  359. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte));
  360. 2 :
  361. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord));
  362. 4 :
  363. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
  364. end;
  365. if (tf_requires_proper_alignment in target_info.flags) then
  366. current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(longint(def.size)));
  367. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.min));
  368. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.max));
  369. if (tf_requires_proper_alignment in target_info.flags) then
  370. current_asmdata.asmlists[al_rtti].concat(Cai_align.Create(sizeof(TConstPtrUint)));
  371. if assigned(def.basedef) then
  372. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.basedef,rt)))
  373. else
  374. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  375. hp:=tenumsym(def.firstenum);
  376. while assigned(hp) do
  377. begin
  378. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(hp.realname)));
  379. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(hp.realname));
  380. hp:=hp.nextenum;
  381. end;
  382. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  383. end;
  384. procedure orddef_rtti(def:torddef);
  385. procedure dointeger;
  386. const
  387. trans : array[tordtype] of byte =
  388. (otUByte{otNone},
  389. otUByte,otUWord,otULong,otUByte{otNone},
  390. otSByte,otSWord,otSLong,otUByte{otNone},
  391. otUByte,otSByte,otSWord,otSLong,otSByte,
  392. otUByte,otUWord,otUByte);
  393. begin
  394. write_rtti_name(def);
  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_8bit(byte(trans[def.ordtype])));
  398. if (tf_requires_proper_alignment in target_info.flags) then
  399. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  400. {Convert to longint to smuggle values in high(longint)+1..high(cardinal) into asmlist.}
  401. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.low.svalue)));
  402. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.high.svalue)));
  403. end;
  404. begin
  405. case def.ordtype of
  406. s64bit :
  407. begin
  408. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkInt64));
  409. write_rtti_name(def);
  410. if (tf_requires_proper_alignment in target_info.flags) then
  411. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  412. { low }
  413. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.low.svalue));
  414. { high }
  415. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.high.svalue));
  416. end;
  417. u64bit :
  418. begin
  419. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkQWord));
  420. write_rtti_name(def);
  421. if (tf_requires_proper_alignment in target_info.flags) then
  422. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  423. {use svalue because Create_64bit accepts int64, prevents range checks}
  424. { low }
  425. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.low.svalue));
  426. { high }
  427. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(def.high.svalue));
  428. end;
  429. pasbool:
  430. begin
  431. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkBool));
  432. dointeger;
  433. end;
  434. uchar:
  435. begin
  436. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkChar));
  437. dointeger;
  438. end;
  439. uwidechar:
  440. begin
  441. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkWChar));
  442. dointeger;
  443. end;
  444. scurrency:
  445. begin
  446. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkFloat));
  447. write_rtti_name(def);
  448. if (tf_requires_proper_alignment in target_info.flags) then
  449. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  450. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ftCurr));
  451. end;
  452. else
  453. begin
  454. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkInteger));
  455. dointeger;
  456. end;
  457. end;
  458. end;
  459. procedure floatdef_rtti(def:tfloatdef);
  460. const
  461. {tfloattype = (s32real,s64real,s80real,s64bit,s128bit);}
  462. translate : array[tfloattype] of byte =
  463. (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,ftFloat128);
  464. begin
  465. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkFloat));
  466. write_rtti_name(def);
  467. if (tf_requires_proper_alignment in target_info.flags) then
  468. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  469. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(translate[def.floattype]));
  470. end;
  471. procedure setdef_rtti(def:tsetdef);
  472. begin
  473. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkSet));
  474. write_rtti_name(def);
  475. if (tf_requires_proper_alignment in target_info.flags) then
  476. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  477. case def.size of
  478. 1:
  479. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte));
  480. 2:
  481. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord));
  482. 4:
  483. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
  484. end;
  485. if (tf_requires_proper_alignment in target_info.flags) then
  486. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  487. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.elementdef,rt)));
  488. end;
  489. procedure arraydef_rtti(def:tarraydef);
  490. begin
  491. if ado_IsDynamicArray in def.arrayoptions then
  492. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkdynarray))
  493. else
  494. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkarray));
  495. write_rtti_name(def);
  496. if (tf_requires_proper_alignment in target_info.flags) then
  497. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  498. { size of elements }
  499. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_pint(def.elesize));
  500. if not(ado_IsDynamicArray in def.arrayoptions) then
  501. begin
  502. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_pint(pint(def.elecount)));
  503. { element type }
  504. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.elementdef,rt)));
  505. end
  506. else
  507. { write a delphi almost compatible dyn. array entry:
  508. there are two types, eltype and eltype2, the latter is nil if the element type needs
  509. no finalization, the former is always valid, delphi has this swapped, but for
  510. compatibility with older fpc versions we do it different, to be delphi compatible,
  511. the names are swapped in typinfo.pp
  512. }
  513. begin
  514. { element type }
  515. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.elementdef,rt)));
  516. end;
  517. { variant type }
  518. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tstoreddef(def.elementdef).getvardef));
  519. if ado_IsDynamicArray in def.arrayoptions then
  520. begin
  521. { element type }
  522. if def.elementdef.needs_inittable then
  523. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.elementdef,rt)))
  524. else
  525. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_pint(0));
  526. { dummy DynUnitName }
  527. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  528. end;
  529. end;
  530. procedure recorddef_rtti(def:trecorddef);
  531. var
  532. fieldcnt : longint;
  533. begin
  534. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkrecord));
  535. write_rtti_name(def);
  536. if (tf_requires_proper_alignment in target_info.flags) then
  537. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  538. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size));
  539. fieldcnt:=fields_count(def.symtable,rt);
  540. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(fieldcnt));
  541. fields_write_rtti_data(def.symtable,rt);
  542. end;
  543. procedure procvardef_rtti(def:tprocvardef);
  544. procedure write_para(parasym:tparavarsym);
  545. var
  546. paraspec : byte;
  547. begin
  548. { only store user visible parameters }
  549. if not(vo_is_hidden_para in parasym.varoptions) then
  550. begin
  551. case parasym.varspez of
  552. vs_value: paraspec := 0;
  553. vs_const: paraspec := pfConst;
  554. vs_var : paraspec := pfVar;
  555. vs_out : paraspec := pfOut;
  556. end;
  557. { write flags for current parameter }
  558. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(paraspec));
  559. { write name of current parameter }
  560. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(parasym.realname)));
  561. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(parasym.realname));
  562. { write name of type of current parameter }
  563. write_rtti_name(parasym.vardef);
  564. end;
  565. end;
  566. var
  567. methodkind : byte;
  568. i : integer;
  569. begin
  570. if po_methodpointer in def.procoptions then
  571. begin
  572. { write method id and name }
  573. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkmethod));
  574. write_rtti_name(def);
  575. if (tf_requires_proper_alignment in target_info.flags) then
  576. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  577. { write kind of method (can only be function or procedure)}
  578. if def.returndef = voidtype then
  579. methodkind := mkProcedure
  580. else
  581. methodkind := mkFunction;
  582. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(methodkind));
  583. { write parameter info. The parameters must be written in reverse order
  584. if this method uses right to left parameter pushing! }
  585. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount));
  586. if def.proccalloption in pushleftright_pocalls then
  587. begin
  588. for i:=0 to def.paras.count-1 do
  589. write_para(tparavarsym(def.paras[i]));
  590. end
  591. else
  592. begin
  593. for i:=def.paras.count-1 downto 0 do
  594. write_para(tparavarsym(def.paras[i]));
  595. end;
  596. { write name of result type }
  597. write_rtti_name(def.returndef);
  598. end
  599. else
  600. begin
  601. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkprocvar));
  602. write_rtti_name(def);
  603. end;
  604. end;
  605. procedure objectdef_rtti(def:tobjectdef);
  606. procedure objectdef_rtti_class_init(def:tobjectdef);
  607. begin
  608. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size));
  609. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(fields_count(def.symtable,rt)));
  610. fields_write_rtti_data(def.symtable,rt);
  611. end;
  612. procedure objectdef_rtti_interface_init(def:tobjectdef);
  613. begin
  614. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(def.size));
  615. end;
  616. procedure objectdef_rtti_class_full(def:tobjectdef);
  617. var
  618. propnamelist : TFPHashObjectList;
  619. begin
  620. { Collect unique property names with nameindex }
  621. propnamelist:=TFPHashObjectList.Create;
  622. collect_propnamelist(propnamelist,def);
  623. if (oo_has_vmt in def.objectoptions) then
  624. current_asmdata.asmlists[al_rtti].concat(Tai_const.Createname(def.vmt_mangledname,0))
  625. else
  626. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  627. { write parent typeinfo }
  628. if assigned(def.childof) and
  629. (oo_can_have_published in def.childof.objectoptions) then
  630. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.childof,fullrtti)))
  631. else
  632. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  633. { total number of unique properties }
  634. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnamelist.count));
  635. { write unit name }
  636. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  637. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(current_module.realmodulename^));
  638. if (tf_requires_proper_alignment in target_info.flags) then
  639. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  640. { write published properties for this object }
  641. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(published_properties_count(def.symtable)));
  642. if (tf_requires_proper_alignment in target_info.flags) then
  643. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  644. published_properties_write_rtti_data(propnamelist,def.symtable);
  645. propnamelist.free;
  646. end;
  647. procedure objectdef_rtti_interface_full(def:tobjectdef);
  648. var
  649. i : longint;
  650. propnamelist : TFPHashObjectList;
  651. begin
  652. { Collect unique property names with nameindex }
  653. propnamelist:=TFPHashObjectList.Create;
  654. collect_propnamelist(propnamelist,def);
  655. { write parent typeinfo }
  656. if assigned(def.childof) then
  657. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(ref_rtti(def.childof,fullrtti)))
  658. else
  659. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  660. { interface: write flags, iid and iidstr }
  661. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(
  662. { ugly, but working }
  663. {$ifdef USE_PACKSET1}
  664. byte([
  665. {$else USE_PACKSET1}
  666. longint([
  667. {$endif USE_PACKSET1}
  668. TCompilerIntfFlag(ord(ifHasGuid)*ord(assigned(def.iidguid))),
  669. TCompilerIntfFlag(ord(ifHasStrGUID)*ord(assigned(def.iidstr))),
  670. TCompilerIntfFlag(ord(ifDispInterface)*ord(def.objecttype=odt_dispinterface))
  671. ])
  672. {
  673. ifDispatch, }
  674. ));
  675. if (tf_requires_proper_alignment in target_info.flags) then
  676. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  677. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(def.iidguid^.D1)));
  678. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.iidguid^.D2));
  679. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(def.iidguid^.D3));
  680. for i:=Low(def.iidguid^.D4) to High(def.iidguid^.D4) do
  681. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.iidguid^.D4[i]));
  682. { write unit name }
  683. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  684. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(current_module.realmodulename^));
  685. if (tf_requires_proper_alignment in target_info.flags) then
  686. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  687. { write iidstr }
  688. if assigned(def.iidstr) then
  689. begin
  690. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(def.iidstr^)));
  691. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(def.iidstr^));
  692. end
  693. else
  694. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  695. if (tf_requires_proper_alignment in target_info.flags) then
  696. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  697. { write published properties for this object }
  698. published_properties_write_rtti_data(propnamelist,def.symtable);
  699. propnamelist.free;
  700. end;
  701. begin
  702. case def.objecttype of
  703. odt_class:
  704. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkclass));
  705. odt_object:
  706. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkobject));
  707. odt_dispinterface,
  708. odt_interfacecom:
  709. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterface));
  710. odt_interfacecorba:
  711. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterfaceCorba));
  712. else
  713. internalerror(200611034);
  714. end;
  715. { generate the name }
  716. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(def.objrealname^)));
  717. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(def.objrealname^));
  718. if (tf_requires_proper_alignment in target_info.flags) then
  719. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  720. case rt of
  721. initrtti :
  722. begin
  723. if def.objecttype in [odt_class,odt_object] then
  724. objectdef_rtti_class_init(def)
  725. else
  726. objectdef_rtti_interface_init(def);
  727. end;
  728. fullrtti :
  729. begin
  730. if def.objecttype in [odt_class,odt_object] then
  731. objectdef_rtti_class_full(def)
  732. else
  733. objectdef_rtti_interface_full(def);
  734. end;
  735. end;
  736. end;
  737. begin
  738. case def.typ of
  739. variantdef :
  740. variantdef_rtti(tvariantdef(def));
  741. stringdef :
  742. stringdef_rtti(tstringdef(def));
  743. enumdef :
  744. enumdef_rtti(tenumdef(def));
  745. orddef :
  746. orddef_rtti(torddef(def));
  747. floatdef :
  748. floatdef_rtti(tfloatdef(def));
  749. setdef :
  750. setdef_rtti(tsetdef(def));
  751. procvardef :
  752. procvardef_rtti(tprocvardef(def));
  753. arraydef :
  754. begin
  755. if ado_IsBitPacked in tarraydef(def).arrayoptions then
  756. unknown_rtti(tstoreddef(def))
  757. else
  758. arraydef_rtti(tarraydef(def));
  759. end;
  760. recorddef :
  761. begin
  762. if trecorddef(def).is_packed then
  763. unknown_rtti(tstoreddef(def))
  764. else
  765. recorddef_rtti(trecorddef(def));
  766. end;
  767. objectdef :
  768. objectdef_rtti(tobjectdef(def));
  769. else
  770. unknown_rtti(tstoreddef(def));
  771. end;
  772. end;
  773. procedure TRTTIWriter.write_rtti_extrasyms(def:Tdef;rt:Trttitype;mainrtti:Tasmsymbol);
  774. procedure enumdef_rtti_ord2stringindex(def:Tenumdef);
  775. var rttilab:Tasmsymbol;
  776. t:Tenumsym;
  777. syms:^Tenumsym;
  778. offsets:^longint;
  779. sym_count,sym_alloc:longint;
  780. h,i,p,o,st:longint;
  781. mode:(lookup,search); {Modify with care, ordinal value of enum is written.}
  782. r:single; {Must be real type because of integer overflow risk.}
  783. begin
  784. {Random access needed, put in array.}
  785. getmem(syms,64*sizeof(Tenumsym));
  786. getmem(offsets,64*sizeof(longint));
  787. sym_count:=0;
  788. sym_alloc:=64;
  789. st:=0;
  790. t:=Tenumsym(def.firstenum);
  791. while assigned(t) do
  792. begin
  793. if sym_count>=sym_alloc then
  794. begin
  795. reallocmem(syms,2*sym_alloc*sizeof(Tenumsym));
  796. reallocmem(offsets,2*sym_alloc*sizeof(longint));
  797. sym_alloc:=sym_alloc*2;
  798. end;
  799. syms[sym_count]:=t;
  800. offsets[sym_count]:=st;
  801. inc(sym_count);
  802. st:=st+length(t.realname)+1;
  803. t:=t.nextenum;
  804. end;
  805. {Sort the syms by enum value}
  806. if sym_count>=2 then
  807. begin
  808. p:=1;
  809. while 2*p<sym_count do
  810. p:=2*p;
  811. while p<>0 do
  812. begin
  813. for h:=p to sym_count-1 do
  814. begin
  815. i:=h;
  816. t:=syms[i];
  817. o:=offsets[i];
  818. repeat
  819. if syms[i-p].value<=t.value then
  820. break;
  821. syms[i]:=syms[i-p];
  822. offsets[i]:=offsets[i-p];
  823. dec(i,p);
  824. until i<p;
  825. syms[i]:=t;
  826. offsets[i]:=o;
  827. end;
  828. p:=p shr 1;
  829. end;
  830. end;
  831. {Decide wether a lookup array is size efficient.}
  832. mode:=lookup;
  833. if sym_count>0 then
  834. begin
  835. i:=1;
  836. r:=0;
  837. h:=syms[0].value; {Next expected enum value is min.}
  838. while i<sym_count do
  839. begin
  840. {Calculate size of hole between values. Avoid integer overflows.}
  841. r:=r+(single(syms[i].value)-single(h))-1;
  842. h:=syms[i].value;
  843. inc(i);
  844. end;
  845. if r>sym_count then
  846. mode:=search; {Don't waste more than 50% space.}
  847. end;
  848. {Calculate start of string table.}
  849. st:=1;
  850. if assigned(def.typesym) then
  851. inc(st,length(def.typesym.realname)+1)
  852. else
  853. inc(st);
  854. if (tf_requires_proper_alignment in target_info.flags) then
  855. st:=align(st,sizeof(Tconstptruint));
  856. inc(st);
  857. if (tf_requires_proper_alignment in target_info.flags) then
  858. st:=align(st,sizeof(Tconstptruint));
  859. inc(st,8+sizeof(pint));
  860. { write rtti data }
  861. with current_asmdata do
  862. begin
  863. rttilab:=defineasmsymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_GLOBAL,AT_DATA);
  864. maybe_new_object_file(asmlists[al_rtti]);
  865. new_section(asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(pint)));
  866. asmlists[al_rtti].concat(Tai_symbol.create_global(rttilab,0));
  867. asmlists[al_rtti].concat(Tai_const.create_32bit(longint(mode)));
  868. if mode=lookup then
  869. begin
  870. if (tf_requires_proper_alignment in target_info.flags) then
  871. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  872. o:=syms[0].value; {Start with min value.}
  873. for i:=0 to sym_count-1 do
  874. begin
  875. while o<syms[i].value do
  876. begin
  877. asmlists[al_rtti].concat(Tai_const.create_pint(0));
  878. inc(o);
  879. end;
  880. inc(o);
  881. asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
  882. end;
  883. end
  884. else
  885. begin
  886. asmlists[al_rtti].concat(Tai_const.create_32bit(sym_count));
  887. for i:=0 to sym_count-1 do
  888. begin
  889. if (tf_requires_proper_alignment in target_info.flags) then
  890. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(4));
  891. asmlists[al_rtti].concat(Tai_const.create_32bit(syms[i].value));
  892. if (tf_requires_proper_alignment in target_info.flags) then
  893. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  894. asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
  895. end;
  896. end;
  897. asmlists[al_rtti].concat(Tai_symbol_end.create(rttilab));
  898. end;
  899. dispose(syms);
  900. dispose(offsets);
  901. end;
  902. procedure enumdef_rtti_string2ordindex(def:Tenumdef);
  903. var rttilab:Tasmsymbol;
  904. t:Tenumsym;
  905. syms:^Tenumsym;
  906. offsets:^longint;
  907. sym_count,sym_alloc:longint;
  908. h,i,p,o,st:longint;
  909. begin
  910. {Random access needed, put in array.}
  911. getmem(syms,64*sizeof(Tenumsym));
  912. getmem(offsets,64*sizeof(longint));
  913. sym_count:=0;
  914. sym_alloc:=64;
  915. st:=0;
  916. t:=Tenumsym(def.firstenum);
  917. while assigned(t) do
  918. begin
  919. if sym_count>=sym_alloc then
  920. begin
  921. reallocmem(syms,2*sym_alloc*sizeof(Tenumsym));
  922. reallocmem(offsets,2*sym_alloc*sizeof(longint));
  923. sym_alloc:=sym_alloc*2;
  924. end;
  925. syms[sym_count]:=t;
  926. offsets[sym_count]:=st;
  927. inc(sym_count);
  928. st:=st+length(t.realname)+1;
  929. t:=t.nextenum;
  930. end;
  931. {Sort the syms by enum name}
  932. if sym_count>=2 then
  933. begin
  934. p:=1;
  935. while 2*p<sym_count do
  936. p:=2*p;
  937. while p<>0 do
  938. begin
  939. for h:=p to sym_count-1 do
  940. begin
  941. i:=h;
  942. t:=syms[i];
  943. o:=offsets[i];
  944. repeat
  945. if syms[i-p].name<=t.name then
  946. break;
  947. syms[i]:=syms[i-p];
  948. offsets[i]:=offsets[i-p];
  949. dec(i,p);
  950. until i<p;
  951. syms[i]:=t;
  952. offsets[i]:=o;
  953. end;
  954. p:=p shr 1;
  955. end;
  956. end;
  957. {Calculate start of string table.}
  958. st:=1;
  959. if assigned(def.typesym) then
  960. inc(st,length(def.typesym.realname)+1)
  961. else
  962. inc(st);
  963. if (tf_requires_proper_alignment in target_info.flags) then
  964. st:=align(st,sizeof(Tconstptruint));
  965. inc(st);
  966. if (tf_requires_proper_alignment in target_info.flags) then
  967. st:=align(st,sizeof(Tconstptruint));
  968. inc(st,8+sizeof(pint));
  969. { write rtti data }
  970. with current_asmdata do
  971. begin
  972. rttilab:=defineasmsymbol(Tstoreddef(def).rtti_mangledname(rt)+'_s2o',AB_GLOBAL,AT_DATA);
  973. maybe_new_object_file(asmlists[al_rtti]);
  974. new_section(asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(pint)));
  975. asmlists[al_rtti].concat(Tai_symbol.create_global(rttilab,0));
  976. asmlists[al_rtti].concat(Tai_const.create_32bit(sym_count));
  977. for i:=0 to sym_count-1 do
  978. begin
  979. if (tf_requires_proper_alignment in target_info.flags) then
  980. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(4));
  981. asmlists[al_rtti].concat(Tai_const.create_32bit(syms[i].value));
  982. if (tf_requires_proper_alignment in target_info.flags) then
  983. current_asmdata.asmlists[al_rtti].concat(cai_align.Create(sizeof(TConstPtrUInt)));
  984. asmlists[al_rtti].concat(Tai_const.create_sym_offset(mainrtti,st+offsets[i]));
  985. end;
  986. asmlists[al_rtti].concat(Tai_symbol_end.create(rttilab));
  987. end;
  988. dispose(syms);
  989. dispose(offsets);
  990. end;
  991. begin
  992. case def.typ of
  993. enumdef:
  994. if rt=fullrtti then
  995. begin
  996. enumdef_rtti_ord2stringindex(Tenumdef(def));
  997. enumdef_rtti_string2ordindex(Tenumdef(def));
  998. end;
  999. end;
  1000. end;
  1001. procedure TRTTIWriter.write_child_rtti_data(def:tdef;rt:trttitype);
  1002. begin
  1003. case def.typ of
  1004. enumdef :
  1005. if assigned(tenumdef(def).basedef) then
  1006. write_rtti(tenumdef(def).basedef,rt);
  1007. setdef :
  1008. write_rtti(tsetdef(def).elementdef,rt);
  1009. arraydef :
  1010. write_rtti(tarraydef(def).elementdef,rt);
  1011. recorddef :
  1012. fields_write_rtti(trecorddef(def).symtable,rt);
  1013. objectdef :
  1014. begin
  1015. if assigned(tobjectdef(def).childof) then
  1016. write_rtti(tobjectdef(def).childof,rt);
  1017. if rt=initrtti then
  1018. fields_write_rtti(tobjectdef(def).symtable,rt)
  1019. else
  1020. published_write_rtti(tobjectdef(def).symtable,rt);
  1021. end;
  1022. end;
  1023. end;
  1024. function TRTTIWriter.ref_rtti(def:tdef;rt:trttitype):tasmsymbol;
  1025. begin
  1026. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt));
  1027. end;
  1028. procedure TRTTIWriter.write_rtti(def:tdef;rt:trttitype);
  1029. var
  1030. rttilab : tasmsymbol;
  1031. begin
  1032. { only write rtti of definitions from the current module }
  1033. if not findunitsymtable(def.owner).iscurrentunit then
  1034. exit;
  1035. { prevent recursion }
  1036. if rttidefstate[rt] in def.defstates then
  1037. exit;
  1038. include(def.defstates,rttidefstate[rt]);
  1039. { write first all dependencies }
  1040. write_child_rtti_data(def,rt);
  1041. { write rtti data }
  1042. rttilab:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(rt),AB_GLOBAL,AT_DATA);
  1043. maybe_new_object_file(current_asmdata.asmlists[al_rtti]);
  1044. new_section(current_asmdata.asmlists[al_rtti],sec_rodata,rttilab.name,const_align(sizeof(pint)));
  1045. current_asmdata.asmlists[al_rtti].concat(Tai_symbol.Create_global(rttilab,0));
  1046. write_rtti_data(def,rt);
  1047. current_asmdata.asmlists[al_rtti].concat(Tai_symbol_end.Create(rttilab));
  1048. write_rtti_extrasyms(def,rt,rttilab);
  1049. end;
  1050. function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype):tasmsymbol;
  1051. begin
  1052. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt));
  1053. end;
  1054. function TRTTIWriter.get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol;
  1055. begin
  1056. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_o2s');
  1057. end;
  1058. function TRTTIWriter.get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
  1059. begin
  1060. result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_s2o');
  1061. end;
  1062. end.