llvmtype.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. {
  2. Copyright (c) 2008,2015 by Peter Vreman, Florian Klaempfl and Jonas Maebe
  3. This units contains support for generating LLVM type info
  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. {
  18. This units contains support for LLVM type info generation.
  19. It's based on the debug info system, since it's quite similar
  20. }
  21. unit llvmtype;
  22. {$i fpcdefs.inc}
  23. {$h+}
  24. interface
  25. uses
  26. cclasses,globtype,
  27. aasmbase,aasmtai,aasmdata,
  28. symbase,symtype,symdef,symsym,
  29. aasmllvm,aasmcnst,
  30. finput,
  31. dbgbase;
  32. { TLLVMTypeInfo }
  33. type
  34. TLLVMTypeInfo = class(TDebugInfo)
  35. protected
  36. { using alias/external declarations it's possible to refer to the same
  37. assembler symbol using multiple types:
  38. function f(p: pointer): pointer; [public, alias: 'FPC_FUNC'];
  39. procedure test(p: pointer); external name 'FPC_FUNC';
  40. We have to insert the appropriate typecasts (per module) for LLVM in
  41. this case. That can only be done after all code for a module has been
  42. generated, as these alias declarations can appear anywhere }
  43. asmsymtypes: THashSet;
  44. procedure record_asmsym_def(sym: TAsmSymbol; def: tdef; redefine: boolean);
  45. function get_asmsym_def(sym: TAsmSymbol): tdef;
  46. function record_def(def:tdef): tdef;
  47. procedure appenddef_array(list:TAsmList;def:tarraydef);override;
  48. procedure appenddef_abstractrecord(list:TAsmList;def:tabstractrecorddef);
  49. procedure appenddef_record(list:TAsmList;def:trecorddef);override;
  50. procedure appenddef_pointer(list:TAsmList;def:tpointerdef);override;
  51. procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
  52. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  53. procedure appenddef_object(list:TAsmList;def: tobjectdef);override;
  54. procedure appenddef_classref(list: TAsmList; def: tclassrefdef);override;
  55. procedure appenddef_variant(list:TAsmList;def: tvariantdef);override;
  56. procedure appenddef_file(list:TasmList;def:tfiledef);override;
  57. procedure appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  58. procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
  59. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  60. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  61. procedure appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);override;
  62. procedure appendsym_const(list:TAsmList;sym:tconstsym);override;
  63. procedure appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);override;
  64. procedure enum_membersyms_callback(p:TObject;arg:pointer);
  65. procedure collect_llvmins_info(deftypelist: tasmlist; p: taillvm);
  66. procedure collect_tai_info(deftypelist: tasmlist; p: tai);
  67. procedure collect_asmlist_info(deftypelist, asmlist: tasmlist);
  68. procedure insert_llvmins_typeconversions(toplevellist: tasmlist; p: taillvm);
  69. procedure insert_typedconst_typeconversion(toplevellist: tasmlist; p: tai_abstracttypedconst);
  70. procedure insert_tai_typeconversions(toplevellist: tasmlist; p: tai);
  71. procedure insert_asmlist_typeconversions(toplevellist, list: tasmlist);
  72. procedure maybe_insert_extern_sym_decl(toplevellist: tasmlist; sym: tasmsymbol; def: tdef);
  73. procedure update_asmlist_alias_types(list: tasmlist);
  74. public
  75. constructor Create;override;
  76. destructor Destroy;override;
  77. procedure inserttypeinfo;override;
  78. end;
  79. implementation
  80. uses
  81. sysutils,cutils,cfileutl,constexp,
  82. version,globals,verbose,systems,
  83. cpubase,cgbase,paramgr,
  84. fmodule,nobj,
  85. defutil,defcmp,symconst,symtable,
  86. llvmbase,llvmdef
  87. ;
  88. {****************************************************************************
  89. TDebugInfoDwarf
  90. ****************************************************************************}
  91. procedure TLLVMTypeInfo.record_asmsym_def(sym: TAsmSymbol; def: tdef; redefine: boolean);
  92. var
  93. res: PHashSetItem;
  94. begin
  95. record_def(def);
  96. res:=asmsymtypes.FindOrAdd(@sym,sizeof(sym));
  97. { due to internal aliases with different signatures, we may end up with
  98. multiple defs for the same symbol -> use the one from the declaration,
  99. and insert typecasts as necessary elsewhere }
  100. if redefine or
  101. not assigned(res^.Data) then
  102. res^.Data:=def;
  103. end;
  104. function TLLVMTypeInfo.get_asmsym_def(sym: TAsmSymbol): tdef;
  105. var
  106. res: PHashSetItem;
  107. begin
  108. res:=asmsymtypes.Find(@sym,sizeof(sym));
  109. { we must have a def for every used asmsym }
  110. if not assigned(res) or
  111. not assigned(res^.data) then
  112. internalerror(2015042701);
  113. result:=tdef(res^.Data);
  114. end;
  115. function TLLVMTypeInfo.record_def(def:tdef): tdef;
  116. begin
  117. result:=def;
  118. if def.dbg_state<>dbg_state_unused then
  119. exit;
  120. def.dbg_state:=dbg_state_used;
  121. deftowritelist.Add(def);
  122. defnumberlist.Add(def);
  123. end;
  124. constructor TLLVMTypeInfo.Create;
  125. begin
  126. inherited Create;
  127. asmsymtypes:=THashSet.Create(current_asmdata.AsmSymbolDict.Count,true,false);
  128. end;
  129. destructor TLLVMTypeInfo.Destroy;
  130. begin
  131. asmsymtypes.free;
  132. inherited destroy;
  133. end;
  134. procedure TLLVMTypeInfo.enum_membersyms_callback(p:TObject; arg: pointer);
  135. begin
  136. case tsym(p).typ of
  137. fieldvarsym:
  138. appendsym_fieldvar(TAsmList(arg),tfieldvarsym(p));
  139. end;
  140. end;
  141. procedure TLLVMTypeInfo.collect_llvmins_info(deftypelist: tasmlist; p: taillvm);
  142. var
  143. opidx, paraidx: longint;
  144. callpara: pllvmcallpara;
  145. begin
  146. for opidx:=0 to p.ops-1 do
  147. case p.oper[opidx]^.typ of
  148. top_def:
  149. record_def(p.oper[opidx]^.def);
  150. top_tai:
  151. collect_tai_info(deftypelist,p.oper[opidx]^.ai);
  152. top_ref:
  153. begin
  154. if (p.llvmopcode<>la_br) and
  155. assigned(p.oper[opidx]^.ref^.symbol) and
  156. (p.oper[opidx]^.ref^.symbol.bind<>AB_TEMP) then
  157. begin
  158. if (opidx=3) and
  159. (p.llvmopcode=la_call) then
  160. record_asmsym_def(p.oper[opidx]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef,false)
  161. { not a named register }
  162. else if (p.oper[opidx]^.ref^.refaddr<>addr_full) then
  163. record_asmsym_def(p.oper[opidx]^.ref^.symbol,p.spilling_get_reg_type(opidx),false);
  164. end;
  165. end;
  166. top_para:
  167. for paraidx:=0 to p.oper[opidx]^.paras.count-1 do
  168. begin
  169. callpara:=pllvmcallpara(p.oper[opidx]^.paras[paraidx]);
  170. record_def(callpara^.def);
  171. end;
  172. end;
  173. end;
  174. procedure TLLVMTypeInfo.collect_tai_info(deftypelist: tasmlist; p: tai);
  175. var
  176. value: tai_abstracttypedconst;
  177. begin
  178. case p.typ of
  179. ait_llvmalias:
  180. begin
  181. record_asmsym_def(taillvmalias(p).newsym,taillvmalias(p).def,true);
  182. end;
  183. ait_llvmdecl:
  184. begin
  185. record_asmsym_def(taillvmdecl(p).namesym,taillvmdecl(p).def,true);
  186. collect_asmlist_info(deftypelist,taillvmdecl(p).initdata);
  187. end;
  188. ait_llvmins:
  189. collect_llvmins_info(deftypelist,taillvm(p));
  190. ait_typedconst:
  191. begin
  192. record_def(tai_abstracttypedconst(p).def);
  193. case tai_abstracttypedconst(p).adetyp of
  194. tck_simple:
  195. collect_tai_info(deftypelist,tai_simpletypedconst(p).val);
  196. tck_array,tck_record:
  197. for value in tai_aggregatetypedconst(p) do
  198. collect_tai_info(deftypelist,value);
  199. end;
  200. end;
  201. end;
  202. end;
  203. procedure TLLVMTypeInfo.collect_asmlist_info(deftypelist, asmlist: tasmlist);
  204. var
  205. hp: tai;
  206. begin
  207. if not assigned(asmlist) then
  208. exit;
  209. hp:=tai(asmlist.first);
  210. while assigned(hp) do
  211. begin
  212. collect_tai_info(deftypelist,hp);
  213. hp:=tai(hp.next);
  214. end;
  215. end;
  216. function equal_llvm_defs(def1, def2: tdef): boolean;
  217. var
  218. def1str, def2str: TSymStr;
  219. begin
  220. if def1=def2 then
  221. exit(true);
  222. def1str:=llvmencodetypename(def1);
  223. def2str:=llvmencodetypename(def2);
  224. { normalise both type representations in case one is a procdef
  225. and the other is a procvardef}
  226. if def1.typ=procdef then
  227. def1str:=def1str+'*';
  228. if def2.typ=procdef then
  229. def2str:=def2str+'*';
  230. result:=def1str=def2str;
  231. end;
  232. procedure TLLVMTypeInfo.insert_llvmins_typeconversions(toplevellist: tasmlist; p: taillvm);
  233. var
  234. symdef,
  235. opdef,
  236. opcmpdef: tdef;
  237. cnv: taillvm;
  238. i: longint;
  239. begin
  240. case p.llvmopcode of
  241. la_call:
  242. if p.oper[3]^.typ=top_ref then
  243. begin
  244. maybe_insert_extern_sym_decl(toplevellist,p.oper[3]^.ref^.symbol,tpointerdef(p.oper[2]^.def).pointeddef);
  245. symdef:=get_asmsym_def(p.oper[3]^.ref^.symbol);
  246. { the type used in the call is different from the type used to
  247. declare the symbol -> insert a typecast }
  248. if not equal_llvm_defs(symdef,p.oper[2]^.def) then
  249. begin
  250. if symdef.typ=procdef then
  251. { ugly, but can't use getcopyas(procvardef) due to the
  252. symtablestack not being available here (cpointerdef.getreusable
  253. is hardcoded to put things in the current module's
  254. symtable) and "pointer to procedure" results in the
  255. correct llvm type }
  256. symdef:=cpointerdef.getreusable(tprocdef(symdef));
  257. cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,symdef,p.oper[3]^.ref^.symbol,p.oper[2]^.def);
  258. p.loadtai(3,cnv);
  259. end;
  260. end;
  261. else if p.llvmopcode<>la_br then
  262. begin
  263. { check the types of all symbolic operands }
  264. for i:=0 to p.ops-1 do
  265. case p.oper[i]^.typ of
  266. top_ref:
  267. if (p.oper[i]^.ref^.refaddr<>addr_full) and
  268. assigned(p.oper[i]^.ref^.symbol) and
  269. (p.oper[i]^.ref^.symbol.bind<>AB_TEMP) then
  270. begin
  271. opdef:=p.spilling_get_reg_type(i);
  272. case opdef.typ of
  273. pointerdef:
  274. opcmpdef:=tpointerdef(opdef).pointeddef;
  275. procvardef,
  276. procdef:
  277. opcmpdef:=opdef;
  278. else
  279. internalerror(2015073101);
  280. end;
  281. maybe_insert_extern_sym_decl(toplevellist,p.oper[i]^.ref^.symbol,opcmpdef);
  282. symdef:=get_asmsym_def(p.oper[i]^.ref^.symbol);
  283. if not equal_llvm_defs(symdef,opcmpdef) then
  284. begin
  285. if symdef.typ=procdef then
  286. symdef:=cpointerdef.getreusable(symdef);
  287. cnv:=taillvm.op_reg_size_sym_size(la_bitcast,NR_NO,cpointerdef.getreusable(symdef),p.oper[i]^.ref^.symbol,opdef);
  288. p.loadtai(i,cnv);
  289. end;
  290. end;
  291. top_tai:
  292. insert_tai_typeconversions(toplevellist,p.oper[i]^.ai);
  293. end;
  294. end;
  295. end;
  296. end;
  297. procedure TLLVMTypeInfo.insert_typedconst_typeconversion(toplevellist: tasmlist; p: tai_abstracttypedconst);
  298. var
  299. symdef: tdef;
  300. cnv: taillvm;
  301. elementp: tai_abstracttypedconst;
  302. begin
  303. case p.adetyp of
  304. tck_simple:
  305. begin
  306. case tai_simpletypedconst(p).val.typ of
  307. ait_const:
  308. if assigned(tai_const(tai_simpletypedconst(p).val).sym) and
  309. not assigned(tai_const(tai_simpletypedconst(p).val).endsym) then
  310. begin
  311. maybe_insert_extern_sym_decl(toplevellist,tai_const(tai_simpletypedconst(p).val).sym,p.def);
  312. symdef:=get_asmsym_def(tai_const(tai_simpletypedconst(p).val).sym);
  313. { all references to symbols in typed constants are
  314. references to the address of a global symbol (you can't
  315. refer to the data itself, just like you can't initialise
  316. a Pascal (typed) constant with the contents of another
  317. typed constant) }
  318. symdef:=cpointerdef.getreusable(symdef);
  319. if not equal_llvm_defs(symdef,p.def) then
  320. begin
  321. cnv:=taillvm.op_reg_tai_size(la_bitcast,NR_NO,tai_simpletypedconst.create(tck_simple,symdef,tai_simpletypedconst(p).val),p.def);
  322. tai_simpletypedconst(p).val:=cnv;
  323. end;
  324. end;
  325. else
  326. insert_tai_typeconversions(toplevellist,tai_simpletypedconst(p).val);
  327. end;
  328. end;
  329. tck_array,
  330. tck_record:
  331. begin
  332. for elementp in tai_aggregatetypedconst(p) do
  333. insert_typedconst_typeconversion(toplevellist,elementp);
  334. end;
  335. end;
  336. end;
  337. procedure TLLVMTypeInfo.insert_tai_typeconversions(toplevellist: tasmlist; p: tai);
  338. begin
  339. case p.typ of
  340. ait_llvmins:
  341. insert_llvmins_typeconversions(toplevellist,taillvm(p));
  342. { can also be necessary in case someone initialises a typed const with
  343. the address of an external symbol aliasing one declared with a
  344. different type in the same mmodule. }
  345. ait_typedconst:
  346. insert_typedconst_typeconversion(toplevellist,tai_abstracttypedconst(p));
  347. ait_llvmdecl:
  348. insert_asmlist_typeconversions(toplevellist,taillvmdecl(p).initdata);
  349. end;
  350. end;
  351. procedure TLLVMTypeInfo.insert_asmlist_typeconversions(toplevellist, list: tasmlist);
  352. var
  353. hp: tai;
  354. begin
  355. if not assigned(list) then
  356. exit;
  357. hp:=tai(list.first);
  358. while assigned(hp) do
  359. begin
  360. insert_tai_typeconversions(toplevellist,hp);
  361. hp:=tai(hp.next);
  362. end;
  363. end;
  364. procedure TLLVMTypeInfo.maybe_insert_extern_sym_decl(toplevellist: tasmlist; sym: tasmsymbol; def: tdef);
  365. var
  366. sec: tasmsectiontype;
  367. begin
  368. { Necessery for "external" declarations for symbols not declared in the
  369. current unit. We can't create these declarations when the alias is
  370. initially generated, because the symbol may still be defined later at
  371. that point.
  372. We also do it for all other external symbol references (e.g.
  373. references to symbols declared in other units), because then this
  374. handling is centralised in one place. }
  375. if not(sym.declared) then
  376. begin
  377. if def.typ=procdef then
  378. sec:=sec_code
  379. else
  380. sec:=sec_data;
  381. toplevellist.Concat(taillvmdecl.createdecl(sym,def,nil,sec,def.alignment));
  382. record_asmsym_def(sym,def,true);
  383. end;
  384. end;
  385. procedure TLLVMTypeInfo.update_asmlist_alias_types(list: tasmlist);
  386. var
  387. hp: tai;
  388. def: tdef;
  389. begin
  390. if not assigned(list) then
  391. exit;
  392. hp:=tai(list.first);
  393. while assigned(hp) do
  394. begin
  395. case hp.typ of
  396. ait_llvmalias:
  397. begin
  398. { replace the def of the alias declaration with the def of
  399. the aliased symbol -> we'll insert the appropriate type
  400. conversions for all uses of this symbol in the code (since
  401. every use also specifies the used type) }
  402. record_asmsym_def(taillvmalias(hp).oldsym,taillvmalias(hp).def,false);
  403. def:=get_asmsym_def(taillvmalias(hp).oldsym);
  404. if taillvmalias(hp).def<>def then
  405. begin
  406. taillvmalias(hp).def:=def;
  407. record_asmsym_def(taillvmalias(hp).newsym,def,true);
  408. end;
  409. end;
  410. ait_llvmdecl:
  411. update_asmlist_alias_types(taillvmdecl(hp).initdata);
  412. end;
  413. hp:=tai(hp.next);
  414. end;
  415. end;
  416. procedure TLLVMTypeInfo.appenddef_array(list:TAsmList;def:tarraydef);
  417. begin
  418. appenddef(list,def.elementdef);
  419. end;
  420. procedure TLLVMTypeInfo.appenddef_abstractrecord(list:TAsmList;def:tabstractrecorddef);
  421. var
  422. symdeflist: tfpobjectlist;
  423. i: longint;
  424. begin
  425. symdeflist:=tabstractrecordsymtable(def.symtable).llvmst.symdeflist;
  426. for i:=0 to symdeflist.Count-1 do
  427. record_def(tllvmshadowsymtableentry(symdeflist[i]).def);
  428. if assigned(def.typesym) then
  429. list.concat(taillvm.op_size(LA_TYPE,record_def(def)));
  430. end;
  431. procedure TLLVMTypeInfo.appenddef_record(list:TAsmList;def:trecorddef);
  432. begin
  433. appenddef_abstractrecord(list,def);
  434. end;
  435. procedure TLLVMTypeInfo.appenddef_pointer(list:TAsmList;def:tpointerdef);
  436. begin
  437. appenddef(list,def.pointeddef);
  438. end;
  439. procedure TLLVMTypeInfo.appenddef_procvar(list:TAsmList;def:tprocvardef);
  440. var
  441. i: longint;
  442. begin
  443. { todo: handle mantis #25551; there is no way to create a symbolic
  444. la_type for a procvardef (unless it's a procedure of object/record),
  445. which means that recursive references should become plain "procedure"
  446. types that are then casted to the real type when they are used }
  447. for i:=0 to def.paras.count-1 do
  448. appenddef(list,tparavarsym(def.paras[i]).vardef);
  449. appenddef(list,def.returndef);
  450. if assigned(def.typesym) and
  451. not def.is_addressonly then
  452. list.concat(taillvm.op_size(LA_TYPE,record_def(def)));
  453. end;
  454. procedure TLLVMTypeInfo.appendprocdef(list:TAsmList;def:tprocdef);
  455. begin
  456. { the procdef itself is already written by appendprocdef_implicit }
  457. { last write the types from this procdef }
  458. if assigned(def.parast) then
  459. write_symtable_defs(current_asmdata.asmlists[al_start],def.parast);
  460. if assigned(def.localst) and
  461. (def.localst.symtabletype=localsymtable) then
  462. write_symtable_defs(current_asmdata.asmlists[al_start],def.localst);
  463. end;
  464. procedure TLLVMTypeInfo.appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  465. begin
  466. appenddef(list,sym.vardef);
  467. end;
  468. procedure TLLVMTypeInfo.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
  469. begin
  470. appendsym_var(list,sym);
  471. end;
  472. procedure TLLVMTypeInfo.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
  473. begin
  474. appendsym_var(list,sym);
  475. end;
  476. procedure TLLVMTypeInfo.appendsym_paravar(list:TAsmList;sym:tparavarsym);
  477. begin
  478. appendsym_var(list,sym);
  479. end;
  480. procedure TLLVMTypeInfo.appendsym_fieldvar(list:TAsmList;sym: tfieldvarsym);
  481. begin
  482. appenddef(list,sym.vardef);
  483. end;
  484. procedure TLLVMTypeInfo.appendsym_const(list:TAsmList;sym:tconstsym);
  485. begin
  486. appenddef(list,sym.constdef);
  487. end;
  488. procedure TLLVMTypeInfo.appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);
  489. begin
  490. appenddef(list,sym.vardef);
  491. end;
  492. procedure TLLVMTypeInfo.inserttypeinfo;
  493. procedure write_defs_to_write;
  494. var
  495. n : integer;
  496. looplist,
  497. templist: TFPObjectList;
  498. def : tdef;
  499. begin
  500. templist := TFPObjectList.Create(False);
  501. looplist := deftowritelist;
  502. while looplist.count > 0 do
  503. begin
  504. deftowritelist := templist;
  505. for n := 0 to looplist.count - 1 do
  506. begin
  507. def := tdef(looplist[n]);
  508. case def.dbg_state of
  509. dbg_state_written:
  510. continue;
  511. dbg_state_writing:
  512. internalerror(200610052);
  513. dbg_state_unused:
  514. internalerror(200610053);
  515. dbg_state_used:
  516. appenddef(current_asmdata.asmlists[al_start],def)
  517. else
  518. internalerror(200610054);
  519. end;
  520. end;
  521. looplist.clear;
  522. templist := looplist;
  523. looplist := deftowritelist;
  524. end;
  525. templist.free;
  526. end;
  527. var
  528. storefilepos: tfileposinfo;
  529. def: tdef;
  530. i: longint;
  531. hal: tasmlisttype;
  532. begin
  533. storefilepos:=current_filepos;
  534. current_filepos:=current_module.mainfilepos;
  535. defnumberlist:=TFPObjectList.create(false);
  536. deftowritelist:=TFPObjectList.create(false);
  537. { write all global/static variables, part of flaggin all required tdefs }
  538. if assigned(current_module.globalsymtable) then
  539. write_symtable_syms(current_asmdata.asmlists[al_start],current_module.globalsymtable);
  540. if assigned(current_module.localsymtable) then
  541. write_symtable_syms(current_asmdata.asmlists[al_start],current_module.localsymtable);
  542. { write all procedures and methods, part of flagging all required tdefs }
  543. if assigned(current_module.globalsymtable) then
  544. write_symtable_procdefs(current_asmdata.asmlists[al_start],current_module.globalsymtable);
  545. if assigned(current_module.localsymtable) then
  546. write_symtable_procdefs(current_asmdata.asmlists[al_start],current_module.localsymtable);
  547. { process all llvm instructions, part of flagging all required tdefs }
  548. for hal:=low(TasmlistType) to high(TasmlistType) do
  549. if hal<>al_start then
  550. collect_asmlist_info(current_asmdata.asmlists[al_start],current_asmdata.asmlists[hal]);
  551. { update the defs of all alias declarations so they match those of the
  552. declarations of the symbols they alias }
  553. for hal:=low(TasmlistType) to high(TasmlistType) do
  554. if hal<>al_start then
  555. update_asmlist_alias_types(current_asmdata.asmlists[hal]);
  556. { and insert the necessary type conversions }
  557. for hal:=low(TasmlistType) to high(TasmlistType) do
  558. if hal<>al_start then
  559. insert_asmlist_typeconversions(
  560. current_asmdata.asmlists[hal],
  561. current_asmdata.asmlists[hal]);
  562. { write all used defs }
  563. write_defs_to_write;
  564. { reset all def labels }
  565. for i:=0 to defnumberlist.count-1 do
  566. begin
  567. def := tdef(defnumberlist[i]);
  568. if assigned(def) then
  569. begin
  570. def.dbg_state:=dbg_state_unused;
  571. end;
  572. end;
  573. defnumberlist.free;
  574. defnumberlist:=nil;
  575. deftowritelist.free;
  576. deftowritelist:=nil;
  577. current_filepos:=storefilepos;
  578. end;
  579. procedure TLLVMTypeInfo.appenddef_object(list:TAsmList;def: tobjectdef);
  580. begin
  581. if is_any_interface_kind(def) then
  582. record_def(def.vmt_def)
  583. else
  584. appenddef_abstractrecord(list,def);
  585. end;
  586. procedure TLLVMTypeInfo.appenddef_classref(list: TAsmList; def: tclassrefdef);
  587. begin
  588. record_def(tobjectdef(tclassrefdef(def).pointeddef).vmt_def);
  589. end;
  590. procedure TLLVMTypeInfo.appenddef_variant(list:TAsmList;def: tvariantdef);
  591. begin
  592. appenddef(list,tabstractrecorddef(search_system_type('TVARDATA').typedef));
  593. end;
  594. procedure TLLVMTypeInfo.appenddef_file(list:TAsmList;def:tfiledef);
  595. begin
  596. case tfiledef(def).filetyp of
  597. ft_text :
  598. appenddef(list,tabstractrecorddef(search_system_type('TEXTREC').typedef));
  599. ft_typed,
  600. ft_untyped :
  601. appenddef(list,tabstractrecorddef(search_system_type('FILEREC').typedef));
  602. end;
  603. end;
  604. end.