llvmtype.pas 24 KB

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