llvmdef.pas 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. {
  2. Copyright (c) 2008 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 llvmdef;
  22. {$i fpcdefs.inc}
  23. {$h+}
  24. interface
  25. uses
  26. cclasses,globtype,
  27. aasmbase,aasmtai,aasmdata,
  28. symbase,symtype,symdef,symsym,
  29. finput,
  30. dbgbase;
  31. { TLLVMDefInfo }
  32. type
  33. TLLVMDefInfo = class(TDebugInfo)
  34. { collect all defs in one list so we can reset them easily }
  35. defnumberlist,
  36. deftowritelist : TFPObjectList;
  37. function def_llvm_name(def:tdef) : tasmsymbol;
  38. function def_llvm_pointer_name(def: tdef): tasmsymbol;
  39. function def_llvm_class_struct_name(def:tobjectdef) : tasmsymbol;
  40. function def_llvm_vmt_name(def:tobjectdef) : tasmsymbol;
  41. protected
  42. vardatadef: trecorddef;
  43. procedure record_def(def:tdef);
  44. procedure beforeappenddef(list:TAsmList;def:tdef);override;
  45. procedure afterappenddef(list:TAsmList;def:tdef);override;
  46. procedure appenddef_ord(list:TAsmList;def:torddef);override;
  47. procedure appenddef_float(list:TAsmList;def:tfloatdef);override;
  48. procedure appenddef_enum(list:TAsmList;def:tenumdef);override;
  49. procedure appenddef_array(list:TAsmList;def:tarraydef);override;
  50. procedure appenddef_abstractrecord(list:TAsmList;def:tabstractrecorddef);
  51. procedure appenddef_record(list:TAsmList;def:trecorddef);override;
  52. procedure appenddef_pointer(list:TAsmList;def:tpointerdef);override;
  53. procedure appenddef_string(list:TAsmList;def:tstringdef);override;
  54. procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
  55. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  56. procedure appendprocdef_implicit(list:TAsmList;def:tprocdef);override;
  57. procedure appenddef_formal(list:TAsmList;def: tformaldef);override;
  58. procedure appenddef_object(list:TAsmList;def: tobjectdef);override;
  59. procedure appenddef_set(list:TAsmList;def: tsetdef);override;
  60. procedure appenddef_undefined(list:TAsmList;def: tundefineddef);override;
  61. procedure appenddef_variant(list:TAsmList;def: tvariantdef);override;
  62. procedure appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  63. procedure beforeappendsym(list:TAsmList;sym:tsym);override;
  64. procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
  65. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  66. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  67. procedure appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);override;
  68. procedure appendsym_const(list:TAsmList;sym:tconstsym);override;
  69. procedure appendsym_type(list:TAsmList;sym:ttypesym);override;
  70. procedure appendsym_label(list:TAsmList;sym:tlabelsym);override;
  71. procedure appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);override;
  72. procedure appendsym_property(list:TAsmList;sym:tpropertysym);override;
  73. function getabstractprocdefstr(def:tabstractprocdef): ansistring;
  74. function symname(sym:tsym): String;
  75. procedure enum_membersyms_callback(p:TObject;arg:pointer);
  76. public
  77. constructor Create;override;
  78. destructor Destroy;override;
  79. procedure insertmoduleinfo;override;
  80. procedure inserttypeinfo;override;
  81. end;
  82. implementation
  83. uses
  84. sysutils,cutils,cfileutl,constexp,
  85. version,globals,verbose,systems,
  86. cpubase,cgbase,paramgr,
  87. fmodule,nobj,
  88. defutil,symconst,symtable,
  89. llvmbase, aasmllvm;
  90. {****************************************************************************
  91. TDebugInfoDwarf
  92. ****************************************************************************}
  93. procedure TLLVMDefInfo.record_def(def:tdef);
  94. begin
  95. if (def.dbg_state <> dbg_state_unused) then
  96. exit;
  97. { the name syms are set automatically when requested }
  98. def.dbg_state:=dbg_state_used;
  99. deftowritelist.Add(def);
  100. defnumberlist.Add(def);
  101. end;
  102. function TLLVMDefInfo.def_llvm_name(def: tdef): tasmsymbol;
  103. begin
  104. record_def(def);
  105. result:=def.llvm_name_sym;
  106. end;
  107. function TLLVMDefInfo.def_llvm_pointer_name(def: tdef): tasmsymbol;
  108. begin
  109. record_def(def);
  110. result:=def.llvm_pointername_sym;
  111. end;
  112. function TLLVMDefInfo.def_llvm_class_struct_name(def: tobjectdef): tasmsymbol;
  113. begin
  114. record_def(def);
  115. result:=def.llvm_class_struct_name_sym;
  116. end;
  117. function TLLVMDefInfo.def_llvm_vmt_name(def:tobjectdef) : tasmsymbol;
  118. begin
  119. record_def(def);
  120. result:=def.llvm_vmt_name_sym;
  121. end;
  122. constructor TLLVMDefInfo.Create;
  123. begin
  124. inherited Create;
  125. end;
  126. destructor TLLVMDefInfo.Destroy;
  127. begin
  128. inherited destroy;
  129. end;
  130. procedure TLLVMDefInfo.enum_membersyms_callback(p:TObject; arg: pointer);
  131. begin
  132. case tsym(p).typ of
  133. fieldvarsym:
  134. appendsym_fieldvar(TAsmList(arg),tfieldvarsym(p));
  135. end;
  136. end;
  137. procedure TLLVMDefInfo.appenddef_ord(list:TAsmList;def:torddef);
  138. begin
  139. case def.ordtype of
  140. s8bit,
  141. s16bit,
  142. s32bit,
  143. s64bit,
  144. u8bit,
  145. u16bit,
  146. u32bit,
  147. u64bit,
  148. uchar,
  149. uwidechar,
  150. pasbool,
  151. bool8bit,
  152. bool16bit,
  153. bool32bit,
  154. bool64bit,
  155. scurrency:
  156. begin
  157. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'i'+tostr(def.size*8)));
  158. end;
  159. uvoid :
  160. begin
  161. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'void'));
  162. end
  163. else
  164. internalerror(2008032901);
  165. end;
  166. end;
  167. procedure TLLVMDefInfo.appenddef_float(list:TAsmList;def:tfloatdef);
  168. begin
  169. case def.floattype of
  170. s32real:
  171. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'float'));
  172. s64real:
  173. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'double'));
  174. s80real:
  175. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'x86_fp80'));
  176. s64currency,
  177. s64comp:
  178. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'i64'));
  179. else
  180. internalerror(200601289);
  181. end;
  182. end;
  183. procedure TLLVMDefInfo.appenddef_enum(list:TAsmList;def:tenumdef);
  184. begin
  185. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'i'+tostr(def.size*8)));
  186. end;
  187. procedure TLLVMDefInfo.appenddef_array(list:TAsmList;def:tarraydef);
  188. var
  189. typename: ansistring;
  190. endstr: ansistring;
  191. indexrange: aint;
  192. {$ifndef llvm_has_packed_arrays}
  193. begin
  194. if is_packed_array(def) then
  195. begin
  196. { have to use an array of byte of the appropriate size, }
  197. { since llvm doesn't support packed arrays yet natively }
  198. typename:=def_llvm_name(s8inttype).name;
  199. indexrange:=def.size;
  200. end
  201. else
  202. begin
  203. typename:=def_llvm_name(def.elementdef).name;
  204. if not is_open_array(def) and
  205. not is_dynamic_array(def) then
  206. indexrange:=def.highrange-def.lowrange+1
  207. else
  208. indexrange:=0;
  209. end;
  210. if not is_dynamic_array(def) then
  211. endstr:=']'
  212. else
  213. endstr:=']*';
  214. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'['+tostr(indexrange)+' x '+typename+endstr))
  215. {$else not llvm_has_packed_arrays}
  216. var
  217. arrstart, arrend, typename: ansistring;
  218. begin
  219. typename:='';
  220. if not is_packed_array(def) then
  221. begin
  222. { regular array: '[' nritems 'x' type ']' }
  223. arrstart:='[';
  224. arrend:=']'
  225. end
  226. else
  227. begin
  228. { packed array: '<' nritems 'x' type '>' }
  229. arrstart:='< [';
  230. arrend:='] >';
  231. if is_ordinal(def.elementdef) then
  232. typename:='i'+tostr(def.elepackedbitsize);
  233. end;
  234. if (typename='') then
  235. typename:=def_llvm_name(def.elementdef).name
  236. if is_open_array(def) then
  237. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),arrstart+'0 x '+typename+arrend))
  238. else if is_dynamic_array(def) then
  239. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'[0 x '+typename+']'+'*'))
  240. else
  241. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),arrstart+tostr(def.highrange-def.lowrange+1)+' x '+typename+arrend))
  242. {$endif not llvm_has_packed_arrays}
  243. end;
  244. procedure TLLVMDefInfo.appenddef_abstractrecord(list:TAsmList;def:tabstractrecorddef);
  245. var
  246. defstr, endstr: ansistring;
  247. symdeflist: tfpobjectlist;
  248. i: longint;
  249. begin
  250. if (tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment) then
  251. begin
  252. { we handle the alignment/padding ourselves }
  253. defstr:='< ';
  254. endstr:=' >'
  255. end
  256. else
  257. begin
  258. { let llvm do everything }
  259. defstr:= '{ ';
  260. endstr:= ' }'
  261. end;
  262. if not assigned(tabstractrecordsymtable(def.symtable).llvmst) then
  263. tabstractrecordsymtable(def.symtable).llvmst:=tllvmshadowsymtable.create(tabstractrecordsymtable(def.symtable));
  264. symdeflist:=tabstractrecordsymtable(def.symtable).llvmst.symdeflist;
  265. i:=0;
  266. if (def.typ=objectdef) and
  267. assigned(tobjectdef(def).childof) and
  268. is_class_or_interface_or_dispinterface(tllvmshadowsymtableentry(symdeflist[0]).def) then
  269. begin
  270. { insert the struct for the class rather than a pointer to the struct }
  271. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  272. internalerror(2008070601);
  273. defstr:=defstr+def_llvm_class_struct_name(tobjectdef(tllvmshadowsymtableentry(symdeflist[0]).def)).name+', ';
  274. inc(i);
  275. end;
  276. while i< symdeflist.count do
  277. begin
  278. defstr:=defstr+def_llvm_name(tllvmshadowsymtableentry(symdeflist[i]).def).name+', ';
  279. inc(i);
  280. end;
  281. { remove last ', ' }
  282. setlength(defstr,length(defstr)-2);
  283. defstr:=defstr+endstr;
  284. if (def.typ <> objectdef) or
  285. not(tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_class]) then
  286. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),defstr))
  287. else
  288. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_class_struct_name(tobjectdef(def)),defstr))
  289. end;
  290. procedure TLLVMDefInfo.appenddef_record(list:TAsmList;def:trecorddef);
  291. begin
  292. appenddef_abstractrecord(list,def);
  293. end;
  294. procedure TLLVMDefInfo.appenddef_pointer(list:TAsmList;def:tpointerdef);
  295. begin
  296. { to avoid cluttering the source with pointer types, }
  297. { pointer type names directly are "pointeddef.name+'*'". }
  298. { So only register the pointeddef so it gets printed }
  299. record_def(def.pointeddef);
  300. end;
  301. procedure TLLVMDefInfo.appenddef_string(list:TAsmList;def:tstringdef);
  302. procedure addnormalstringdef(lendef: tdef);
  303. var
  304. defstr: ansistring;
  305. begin
  306. { record with length and array [maxlen x i8 ] }
  307. { (also ok for openstrings, as [0 x i8] means }
  308. { "array of unspecified size" in llvm) }
  309. defstr:='< '+def_llvm_name(lendef).name+', ['+tostr(def.len)+' x i8] >';
  310. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),defstr));
  311. end;
  312. begin
  313. case def.stringtype of
  314. st_shortstring:
  315. begin
  316. addnormalstringdef(u8inttype);
  317. end;
  318. st_longstring:
  319. begin
  320. {$ifdef cpu64bitaddr}
  321. addnormalstringdef(u64inttype);
  322. {$else cpu64bitaddr}
  323. addnormalstringdef(u32inttype);
  324. {$endif cpu64bitaddr}
  325. end;
  326. st_ansistring:
  327. begin
  328. { looks like a pchar }
  329. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'i8*'));
  330. end;
  331. st_unicodestring,
  332. st_widestring:
  333. begin
  334. { looks like a pwidechar }
  335. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'i16*'));
  336. end;
  337. end;
  338. end;
  339. procedure TLLVMDefInfo.appenddef_procvar(list:TAsmList;def:tprocvardef);
  340. begin
  341. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),getabstractprocdefstr(def)+'*'));
  342. end;
  343. procedure TLLVMDefInfo.beforeappenddef(list:TAsmList;def:tdef);
  344. var
  345. labsym : tasmsymbol;
  346. begin
  347. list.concat(tai_comment.Create(strpnew('LLVM definition '+def.typename)));
  348. end;
  349. procedure TLLVMDefInfo.afterappenddef(list:TAsmList;def:tdef);
  350. begin
  351. end;
  352. function TLLVMDefInfo.getabstractprocdefstr(def:tabstractprocdef): ansistring;
  353. var
  354. i : longint;
  355. begin
  356. { function result-by-reference is handled as a parameter }
  357. if (def.proctypeoption in [potype_constructor,potype_destructor]) or
  358. not paramanager.ret_in_param(def.returndef,def.proccalloption) then
  359. result:=def_llvm_name(def.returndef).name
  360. else
  361. result:='void';
  362. result:=result+' ( ';
  363. for i:=0 to def.paras.count-1 do
  364. with tparavarsym(def.paras[i]) do
  365. begin
  366. result:=result+def_llvm_name(vardef).name;
  367. if paramanager.push_addr_param(varspez,vardef,def.proccalloption) then
  368. begin
  369. result:=result+'*';
  370. if (vo_is_funcret in varoptions) then
  371. result:=result+' sret';
  372. end
  373. else
  374. begin
  375. { 'byval' means that the parameter is copied onto the stack at the }
  376. { right location at the caller side rather than that the calling }
  377. { conventions are used to determine whether the address or value }
  378. { of the parameter is passed }
  379. { I don't think we need this for something right now }
  380. // result:=result+' byval'
  381. end;
  382. result:=result+', '
  383. end;
  384. result[length(result)-1]:=')';
  385. end;
  386. procedure TLLVMDefInfo.appendprocdef_implicit(list:TAsmList;def:tprocdef);
  387. begin
  388. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),getabstractprocdefstr(def)));
  389. end;
  390. procedure TLLVMDefInfo.appendprocdef(list:TAsmList;def:tprocdef);
  391. var
  392. defstr : ansistring;
  393. i : longint;
  394. begin
  395. { the procdef itself is already written by appendprocdef_implicit }
  396. { last write the types from this procdef }
  397. if assigned(def.parast) then
  398. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
  399. if assigned(def.localst) and
  400. (def.localst.symtabletype=localsymtable) then
  401. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.localst);
  402. end;
  403. procedure TLLVMDefInfo.appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  404. var
  405. templist : TAsmList;
  406. blocksize : longint;
  407. dreg : byte;
  408. begin
  409. { external symbols can't be resolved at link time, so we
  410. can't generate stabs for them
  411. not sure if this applies to dwarf as well (FK)
  412. }
  413. if vo_is_external in sym.varoptions then
  414. exit;
  415. def_llvm_name(sym.vardef);
  416. { There is no space allocated for not referenced locals }
  417. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  418. exit;
  419. (*
  420. templist:=TAsmList.create;
  421. case sym.localloc.loc of
  422. LOC_REGISTER,
  423. LOC_CREGISTER,
  424. LOC_MMREGISTER,
  425. LOC_CMMREGISTER,
  426. LOC_FPUREGISTER,
  427. LOC_CFPUREGISTER :
  428. begin
  429. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  430. dreg:=dwarf_reg(sym.localloc.register);
  431. templist.concat(tai_const.create_uleb128bit(dreg));
  432. blocksize:=1+Lengthuleb128(dreg);
  433. end;
  434. else
  435. begin
  436. case sym.typ of
  437. staticvarsym:
  438. begin
  439. if (vo_is_thread_var in sym.varoptions) then
  440. begin
  441. {$warning !!! FIXME: dwarf for thread vars !!!
  442. }
  443. blocksize:=0;
  444. end
  445. else
  446. begin
  447. templist.concat(tai_const.create_8bit(3));
  448. templist.concat(tai_const.createname(sym.mangledname,0));
  449. blocksize:=1+sizeof(puint);
  450. end;
  451. end;
  452. paravarsym,
  453. localvarsym:
  454. begin
  455. dreg:=dwarf_reg(sym.localloc.reference.base);
  456. templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+dreg));
  457. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset));
  458. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset);
  459. end
  460. else
  461. internalerror(200601288);
  462. end;
  463. end;
  464. end;
  465. if sym.typ=paravarsym then
  466. tag:=DW_TAG_formal_parameter
  467. else
  468. tag:=DW_TAG_variable;
  469. if not(sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_MMREGISTER,
  470. LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
  471. ((sym.owner.symtabletype = globalsymtable) or
  472. (sp_static in sym.symoptions) or
  473. (vo_is_public in sym.varoptions)) then
  474. append_entry(tag,false,[
  475. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  476. {
  477. DW_AT_decl_file,DW_FORM_data1,0,
  478. DW_AT_decl_line,DW_FORM_data1,
  479. }
  480. DW_AT_external,DW_FORM_flag,true,
  481. { data continues below }
  482. DW_AT_location,DW_FORM_block1,blocksize
  483. ])
  484. {$ifdef gdb_supports_DW_AT_variable_parameter}
  485. else if (sym.typ=paravarsym) and
  486. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  487. not(vo_has_local_copy in sym.varoptions) and
  488. not is_open_string(sym.vardef) then
  489. append_entry(tag,false,[
  490. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  491. DW_AT_variable_parameter,DW_FORM_flag,true,
  492. {
  493. DW_AT_decl_file,DW_FORM_data1,0,
  494. DW_AT_decl_line,DW_FORM_data1,
  495. }
  496. { data continues below }
  497. DW_AT_location,DW_FORM_block1,blocksize
  498. ])
  499. {$endif gdb_supports_DW_AT_variable_parameter}
  500. else
  501. append_entry(tag,false,[
  502. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  503. {
  504. DW_AT_decl_file,DW_FORM_data1,0,
  505. DW_AT_decl_line,DW_FORM_data1,
  506. }
  507. { data continues below }
  508. DW_AT_location,DW_FORM_block1,blocksize
  509. ]);
  510. { append block data }
  511. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  512. {$ifndef gdb_supports_DW_AT_variable_parameter}
  513. if (sym.typ=paravarsym) and
  514. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  515. not(vo_has_local_copy in sym.varoptions) and
  516. not is_open_string(sym.vardef) then
  517. append_labelentry_ref(DW_AT_type,def_dwarf_ref_lab(sym.vardef))
  518. else
  519. {$endif not gdb_supports_DW_AT_variable_parameter}
  520. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  521. templist.free;
  522. finish_entry;
  523. *)
  524. end;
  525. procedure TLLVMDefInfo.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
  526. begin
  527. appendsym_var(list,sym);
  528. end;
  529. procedure TLLVMDefInfo.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
  530. begin
  531. appendsym_var(list,sym);
  532. end;
  533. procedure TLLVMDefInfo.appendsym_paravar(list:TAsmList;sym:tparavarsym);
  534. begin
  535. appendsym_var(list,sym);
  536. end;
  537. procedure TLLVMDefInfo.appendsym_fieldvar(list:TAsmList;sym: tfieldvarsym);
  538. var
  539. bitoffset,
  540. fieldoffset,
  541. fieldnatsize: aint;
  542. begin
  543. // list.concat(taillvm.op_ressym_string(LA_TYPE),'fieldvasym');
  544. (*
  545. if sp_static in sym.symoptions then
  546. exit;
  547. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) or
  548. { only ordinals are bitpacked }
  549. not is_ordinal(sym.vardef) then
  550. begin
  551. { other kinds of fields can however also appear in a bitpacked }
  552. { record, and then their offset is also specified in bits rather }
  553. { than in bytes }
  554. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) then
  555. fieldoffset:=sym.fieldoffset
  556. else
  557. fieldoffset:=sym.fieldoffset div 8;
  558. append_entry(DW_TAG_member,false,[
  559. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  560. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  561. ]);
  562. end
  563. else
  564. begin
  565. if (sym.vardef.packedbitsize > 255) then
  566. internalerror(2007061201);
  567. { we don't bitpack according to the ABI, but as close as }
  568. { possible, i.e., equivalent to gcc's }
  569. { __attribute__((__packed__)), which is also what gpc }
  570. { does. }
  571. fieldnatsize:=max(sizeof(pint),sym.vardef.size);
  572. fieldoffset:=(sym.fieldoffset div (fieldnatsize*8)) * fieldnatsize;
  573. bitoffset:=sym.fieldoffset mod (fieldnatsize*8);
  574. if (target_info.endian=endian_little) then
  575. bitoffset:=(fieldnatsize*8)-bitoffset-sym.vardef.packedbitsize;
  576. append_entry(DW_TAG_member,false,[
  577. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  578. { gcc also generates both a bit and byte size attribute }
  579. { we don't support ordinals >= 256 bits }
  580. DW_AT_byte_size,DW_FORM_data1,fieldnatsize,
  581. { nor >= 256 bits (not yet, anyway, see IE above) }
  582. DW_AT_bit_size,DW_FORM_data1,sym.vardef.packedbitsize,
  583. { data1 and data2 are unsigned, bitoffset can also be negative }
  584. DW_AT_bit_offset,DW_FORM_data4,bitoffset,
  585. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  586. ]);
  587. end;
  588. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  589. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(fieldoffset));
  590. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  591. finish_entry;
  592. *)
  593. end;
  594. procedure TLLVMDefInfo.appendsym_const(list:TAsmList;sym:tconstsym);
  595. begin
  596. // list.concat(taillvm.op_ressym_string(LA_TYPE),'constsym');
  597. (*
  598. append_entry(DW_TAG_constant,false,[
  599. DW_AT_name,DW_FORM_string,symname(sym)+#0
  600. ]);
  601. { for string constants, constdef isn't set because they have no real type }
  602. if not(sym.consttyp in [conststring,constresourcestring,constwstring]) then
  603. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.constdef));
  604. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_AT_const_value)));
  605. case sym.consttyp of
  606. conststring:
  607. begin
  608. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_string)));
  609. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(strpas(pchar(sym.value.valueptr))));
  610. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  611. end;
  612. constset,
  613. constwstring,
  614. constguid,
  615. constresourcestring:
  616. begin
  617. { write dummy for now }
  618. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_string)));
  619. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(''));
  620. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  621. end;
  622. constord:
  623. begin
  624. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_sdata)));
  625. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(sym.value.valueord.svalue));
  626. end;
  627. constnil:
  628. begin
  629. {$ifdef cpu64bitaddr}
  630. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  631. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(0));
  632. {$else cpu64bitaddr}
  633. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  634. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(0));
  635. {$endif cpu64bitaddr}
  636. end;
  637. constpointer:
  638. begin
  639. {$ifdef cpu64bitaddr}
  640. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  641. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(int64(sym.value.valueordptr)));
  642. {$else cpu64bitaddr}
  643. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  644. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(sym.value.valueordptr));
  645. {$endif cpu64bitaddr}
  646. end;
  647. constreal:
  648. begin
  649. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_block1)));
  650. case tfloatdef(sym.constdef).floattype of
  651. s32real:
  652. begin
  653. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(4));
  654. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_32bit.create(psingle(sym.value.valueptr)^));
  655. end;
  656. s64comp,
  657. s64currency,
  658. s64real:
  659. begin
  660. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  661. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_64bit.create(pdouble(sym.value.valueptr)^));
  662. end;
  663. s80real:
  664. begin
  665. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(10));
  666. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_80bit.create(pextended(sym.value.valueptr)^));
  667. end;
  668. else
  669. internalerror(200601291);
  670. end;
  671. end;
  672. else
  673. internalerror(200601292);
  674. end;
  675. finish_entry;
  676. *)
  677. end;
  678. procedure TLLVMDefInfo.appendsym_label(list:TAsmList;sym: tlabelsym);
  679. begin
  680. { ignore label syms for now, the problem is that a label sym
  681. can have more than one label associated e.g. in case of
  682. an inline procedure expansion }
  683. end;
  684. procedure TLLVMDefInfo.appendsym_property(list:TAsmList;sym: tpropertysym);
  685. begin
  686. { ignored for now }
  687. end;
  688. procedure TLLVMDefInfo.appendsym_type(list:TAsmList;sym: ttypesym);
  689. begin
  690. // list.concat(taillvm.op_ressym_string(LA_TYPE,'typesym');
  691. record_def(sym.typedef);
  692. end;
  693. procedure TLLVMDefInfo.appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);
  694. var
  695. templist : TAsmList;
  696. blocksize : longint;
  697. symlist : ppropaccesslistitem;
  698. begin
  699. // list.concat(taillvm.op_ressym_string(LA_TYPE),'absolutesym'));
  700. end;
  701. procedure TLLVMDefInfo.beforeappendsym(list:TAsmList;sym:tsym);
  702. begin
  703. end;
  704. procedure TLLVMDefInfo.insertmoduleinfo;
  705. begin
  706. end;
  707. procedure TLLVMDefInfo.inserttypeinfo;
  708. procedure write_defs_to_write;
  709. var
  710. n : integer;
  711. looplist,
  712. templist: TFPObjectList;
  713. def : tdef;
  714. begin
  715. templist := TFPObjectList.Create(False);
  716. looplist := deftowritelist;
  717. while looplist.count > 0 do
  718. begin
  719. deftowritelist := templist;
  720. for n := 0 to looplist.count - 1 do
  721. begin
  722. def := tdef(looplist[n]);
  723. case def.dbg_state of
  724. dbg_state_written:
  725. continue;
  726. dbg_state_writing:
  727. internalerror(200610052);
  728. dbg_state_unused:
  729. internalerror(200610053);
  730. dbg_state_used:
  731. appenddef(current_asmdata.asmlists[al_dwarf_info],def)
  732. else
  733. internalerror(200610054);
  734. end;
  735. end;
  736. looplist.clear;
  737. templist := looplist;
  738. looplist := deftowritelist;
  739. end;
  740. templist.free;
  741. end;
  742. var
  743. storefilepos : tfileposinfo;
  744. lenstartlabel : tasmlabel;
  745. i : longint;
  746. def: tdef;
  747. begin
  748. storefilepos:=current_filepos;
  749. current_filepos:=current_module.mainfilepos;
  750. defnumberlist:=TFPObjectList.create(false);
  751. deftowritelist:=TFPObjectList.create(false);
  752. { not exported (FK)
  753. FILEREC
  754. TEXTREC
  755. }
  756. vardatadef:=trecorddef(search_system_type('TVARDATA').typedef);
  757. { write all global/local variables. This will flag all required tdefs }
  758. if assigned(current_module.globalsymtable) then
  759. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  760. if assigned(current_module.localsymtable) then
  761. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  762. { write all procedures and methods. This will flag all required tdefs }
  763. if assigned(current_module.globalsymtable) then
  764. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  765. if assigned(current_module.localsymtable) then
  766. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  767. { reset unit type info flag }
  768. reset_unit_type_info;
  769. { write used types from the used units }
  770. write_used_unit_type_info(current_asmdata.asmlists[al_dwarf_info],current_module);
  771. { last write the types from this unit }
  772. if assigned(current_module.globalsymtable) then
  773. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  774. if assigned(current_module.localsymtable) then
  775. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  776. { write defs not written yet }
  777. write_defs_to_write;
  778. { reset all def labels }
  779. for i:=0 to defnumberlist.count-1 do
  780. begin
  781. def := tdef(defnumberlist[i]);
  782. if assigned(def) then
  783. begin
  784. def.dwarf_lab:=nil;
  785. def.dbg_state:=dbg_state_unused;
  786. end;
  787. end;
  788. defnumberlist.free;
  789. defnumberlist:=nil;
  790. deftowritelist.free;
  791. deftowritelist:=nil;
  792. current_filepos:=storefilepos;
  793. end;
  794. function TLLVMDefInfo.symname(sym: tsym): String;
  795. begin
  796. if (sym.typ=paravarsym) and
  797. (vo_is_self in tparavarsym(sym).varoptions) then
  798. result:='this'
  799. else
  800. result := sym.Name;
  801. end;
  802. procedure TLLVMDefInfo.appenddef_formal(list:TAsmList;def: tformaldef);
  803. begin
  804. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'undef*'));
  805. end;
  806. procedure TLLVMDefInfo.appenddef_object(list:TAsmList;def: tobjectdef);
  807. procedure doappend;
  808. begin
  809. appenddef_abstractrecord(list,def);
  810. end;
  811. procedure doappend_classvmt;
  812. var
  813. defstr: ansistring;
  814. i: longint;
  815. begin
  816. { a pointer to the VMT. Structure of the VMT: }
  817. { InstanceSize : ptrint }
  818. { -InstanceSize : ptrint }
  819. { Parent : ^parent }
  820. { ClassName : pointer }
  821. { DynamicTable : pointer }
  822. { MethodTable : pointer }
  823. { FieldTable : pointer }
  824. { TypeInfo : pointer }
  825. { InitTable : pointer }
  826. { AutoTable : pointer }
  827. { IntfTable : pointer }
  828. { MsgStrTable : pointer }
  829. { Methods : X times procvar }
  830. defstr:=def_llvm_name(ptrsinttype).name+', ';
  831. defstr:='< '+defstr+defstr;
  832. if assigned(def.childof) then
  833. defstr:=defstr+def_llvm_vmt_name(def.childof).name+'*, '
  834. else
  835. defstr:=defstr+'void*, ';
  836. { class name (length+string) }
  837. defstr:=defstr+'['+tostr(length(def.objrealname^)+1)+' x i8]*, ';
  838. { the other fields }
  839. for i:=1 to 8 do
  840. defstr:=defstr+'void*, ';
  841. if not assigned(def.VMTEntries) then
  842. with TVMTBuilder.create(def) do
  843. begin
  844. generate_vmt;
  845. free;
  846. end;
  847. for i:= 0 to def.VMTEntries.Count-1 do
  848. defstr:=defstr+def_llvm_pointer_name(tprocdef(def.VMTEntries[i])).name+', ';
  849. setlength(defstr,length(defstr)-2);
  850. defstr:=defstr+' >*';
  851. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_vmt_name(def),defstr));
  852. end;
  853. begin
  854. case def.objecttype of
  855. odt_cppclass,
  856. odt_object:
  857. doappend;
  858. odt_interfacecom,
  859. odt_interfacecorba,
  860. odt_dispinterface,
  861. odt_class:
  862. begin
  863. { implicit pointer }
  864. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),def_llvm_class_struct_name(def).name+'*'));
  865. doappend;
  866. doappend_classvmt;
  867. end;
  868. else
  869. internalerror(200602041);
  870. end;
  871. end;
  872. procedure TLLVMDefInfo.appenddef_set(list:TAsmList;def: tsetdef);
  873. begin
  874. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'[ '+tostr(def.size)+ 'x i8 ]'));
  875. end;
  876. procedure TLLVMDefInfo.appenddef_undefined(list:TAsmList;def: tundefineddef);
  877. begin
  878. list.concat(taillvm.op_ressym_string(LA_TYPE,def_llvm_name(def),'undef'));
  879. end;
  880. procedure TLLVMDefInfo.appenddef_variant(list:TAsmList;def: tvariantdef);
  881. begin
  882. appenddef_record(list,trecorddef(vardatadef));
  883. end;
  884. end.