llvmtype.pas 25 KB

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