llvmtype.pas 25 KB

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