llvmdef.pas 37 KB

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