llvmdef.pas 36 KB

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