dbgllvm.pas 105 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664
  1. {
  2. Copyright (c) 2021-2022 by Jonas Maebe,
  3. member of the Free Pascal Compiler development team
  4. This units contains support for LLVM debug info generation
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {
  19. This units contains support for LLVM debug info generation.
  20. LLVM debug information is stored as metadata in the LLVM bitcode, and is
  21. loosely based on DWARF (it also reuses some DWARF constants)
  22. }
  23. unit dbgllvm;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. cclasses,globtype,
  28. cgbase,
  29. aasmbase,aasmtai,aasmdata,aasmcnst,aasmllvm,aasmllvmmetadata,
  30. symbase,symconst,symtype,symdef,symsym,
  31. finput,
  32. DbgBase, dbgdwarfconst;
  33. type
  34. TLLVMMetaDefHashSetItem = record
  35. { HashSetItem.Data: LLVM metadata which other types reference when
  36. referring to this type (usually a typedef) }
  37. HashSetItem: THashSetItem;
  38. { in case of a class, the field layout (since a class itself is just a
  39. pointer }
  40. struct_metadef: tai_llvmspecialisedmetadatanode;
  41. { the metadata actually containing the type definition (usually
  42. referenced by HashSetItem.Data), filled in by appenddef_* }
  43. implmetadef: tai_llvmspecialisedmetadatanode;
  44. end;
  45. PLLVMMetaDefHashSetItem = ^TLLVMMetaDefHashSetItem;
  46. TLLVMMetaDefHashSet = class(THashSet)
  47. class function SizeOfItem: Integer; override;
  48. end;
  49. TDebugInfoLLVM = class(TDebugInfo)
  50. strict private
  51. type
  52. tmembercallbackinfo = record
  53. structnode: tai_llvmspecialisedmetadatanode;
  54. list: tasmlist;
  55. end;
  56. pmembercallbackinfo = ^tmembercallbackinfo;
  57. var
  58. { lookup table for def -> LLVMMeta info }
  59. fdefmeta: TLLVMMetaDefHashSet;
  60. { lookup table for file -> LLVMMeta info (DIFile) }
  61. ffilemeta: THashSet;
  62. { lookup table for line,column,scope -> LLVMMeta info (DILocation) }
  63. flocationmeta: THashSet;
  64. { lookup table for scope,file -> LLVMMeta info (DILexicalBlockFile, for include files) }
  65. flexicalblockfilemeta: THashSet;
  66. { lookup table for tstaticvarsym -> taillvmdecl }
  67. fstaticvarsymdecl: THashSet;
  68. { lookup table for local/paravarsym -> metadata }
  69. flocalvarsymmeta: THashSet;
  70. fcunode: tai_llvmspecialisedmetadatanode;
  71. fenums: tai_llvmunnamedmetadatanode;
  72. fretainedtypes: tai_llvmunnamedmetadatanode;
  73. fglobals: tai_llvmunnamedmetadatanode;
  74. { reusable empty expression node }
  75. femptyexpression,
  76. { reusable deref node }
  77. fderefexpression : tai_llvmspecialisedmetadatanode;
  78. fllvm_dbg_addr_pd: tprocdef;
  79. function absolute_llvm_path(const s:tcmdstr):tcmdstr;
  80. protected
  81. vardatadef: trecorddef;
  82. procedure try_add_file_metaref(dinode: tai_llvmspecialisedmetadatanode; const fileinfo: tfileposinfo; includescope: boolean);
  83. function add_line_metanode(const fileinfo: tfileposinfo): tai_llvmspecialisedmetadatanode;
  84. function def_meta_impl(def: tdef) : tai_llvmspecialisedmetadatanode;
  85. function def_set_meta_impl(def: tdef; meta_impl: tai_llvmspecialisedmetadatanode): tai_llvmspecialisedmetadatanode;
  86. function def_meta_class_struct(def: tobjectdef) : tai_llvmbasemetadatanode;
  87. function def_meta_node(def: tdef): tai_llvmspecialisedmetadatanode;
  88. function def_meta_ref(def: tdef): tai_simpletypedconst;
  89. function file_getmetanode(moduleindex: tfileposmoduleindex; fileindex: tfileposfileindex): tai_llvmspecialisedmetadatanode;
  90. function filepos_getmetanode(const filepos: tfileposinfo; const functionfileinfo: tfileposinfo; const functionscope: tai_llvmspecialisedmetadatanode; nolineinfo: boolean): tai_llvmspecialisedmetadatanode;
  91. function get_def_metatai(def:tdef): PLLVMMetaDefHashSetItem;
  92. procedure staticvarsym_set_decl(sym: tsym; decl: taillvmdecl);
  93. function staticvarsym_get_decl(sym: tsym): taillvmdecl;
  94. function localvarsym_get_meta(sym: tsym; out is_new: boolean): tai_llvmspecialisedmetadatanode;
  95. procedure appenddef_array_internal(list: TAsmList; fordef: tdef; eledef: tdef; lowrange, highrange: asizeint);
  96. function getabstractprocdeftypes(list: TAsmList; def:tabstractprocdef): tai_llvmbasemetadatanode;
  97. procedure afterappenddef(list: TAsmList; def: tdef); override;
  98. procedure appenddef_ord(list:TAsmList;def:torddef);override;
  99. procedure appenddef_float(list:TAsmList;def:tfloatdef);override;
  100. procedure appenddef_enum(list:TAsmList;def:tenumdef);override;
  101. procedure appenddef_array(list:TAsmList;def:tarraydef);override;
  102. procedure appenddef_record_named(list: TAsmList; fordef: tdef; def: trecorddef; const name: TSymStr);
  103. procedure appenddef_record(list:TAsmList;def:trecorddef);override;
  104. procedure appenddef_pointer(list:TAsmList;def:tpointerdef);override;
  105. procedure appenddef_formal(list:TAsmList;def:tformaldef); override;
  106. procedure appenddef_string(list:TAsmList;def:tstringdef);override;
  107. procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
  108. procedure appenddef_file(list:TAsmList;def:tfiledef); override;
  109. procedure appenddef_object(list:TAsmList;def:tobjectdef); override;
  110. procedure appenddef_set(list:TAsmList;def:tsetdef); override;
  111. procedure appenddef_undefined(list:TAsmList;def:tundefineddef); override;
  112. procedure appenddef_classref(list: TAsmList; def: tclassrefdef); override;
  113. procedure appenddef_variant(list:TAsmList;def:tvariantdef); override;
  114. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  115. procedure adddefinitionlocal(dinode: tai_llvmspecialisedmetadatanode; definition, local, usedispflags: boolean; out dispFlags: tsymstr);
  116. function get_symlist_sym_offset(symlist: ppropaccesslistitem; out sym: tabstractvarsym; out offset: pint): boolean;
  117. procedure appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  118. procedure appendsym_var_with_name_type_offset(list:TAsmList; sym:tabstractnormalvarsym; const name: TSymStr; def: tdef; offset: pint(*; const flags: tdwarfvarsymflags*));
  119. { used for fields and properties mapped to fields }
  120. procedure appendsym_fieldvar_with_name_offset(list:TAsmList;sym: tfieldvarsym;const name: string; def: tdef; offset: pint);
  121. procedure appendsym_const_member(list:TAsmList;sym:tconstsym;ismember:boolean);
  122. procedure beforeappendsym(list:TAsmList;sym:tsym);override;
  123. procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
  124. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  125. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  126. procedure appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);override;
  127. procedure appendsym_const(list:TAsmList;sym:tconstsym);override;
  128. procedure appendsym_type(list:TAsmList;sym:ttypesym);override;
  129. procedure appendsym_label(list:TAsmList;sym:tlabelsym);override;
  130. procedure appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);override;
  131. procedure appendsym_property(list:TAsmList;sym:tpropertysym);override;
  132. function symdebugname(sym:tsym): TSymStr;
  133. function symname(sym: tsym; manglename: boolean): TSymStr; virtual;
  134. function visibilitydiflag(vis: tvisibility): TSymStr;
  135. procedure enum_membersyms_callback(p:TObject;arg:pointer);
  136. procedure ensuremetainit;
  137. procedure resetfornewmodule;
  138. procedure collectglobalsyms;
  139. procedure updatelocalvardbginfo(hp: taillvm; pd: tprocdef; functionscope: tai_llvmspecialisedmetadatanode);
  140. public
  141. constructor Create;override;
  142. destructor Destroy;override;
  143. procedure insertmoduleinfo;override;
  144. procedure inserttypeinfo;override;
  145. procedure insertlineinfo(list:TAsmList);override;
  146. function dwarf_version: Word; virtual; abstract;
  147. end;
  148. implementation
  149. uses
  150. sysutils,cutils,cfileutl,constexp,
  151. version,globals,verbose,systems,
  152. cpubase,cpuinfo,paramgr,
  153. fmodule,
  154. defutil,symtable,symcpu,ppu,
  155. llvminfo,llvmbase
  156. ;
  157. {$push}
  158. {$scopedenums on}
  159. type
  160. TLLVMDIFlags = (
  161. DIFlagNone = 0,
  162. DIFlagPrivate = 1,
  163. DIFlagProtected = 2,
  164. DIFlagPublic = 3,
  165. DIFlagFwdDecl = 1 shl 2,
  166. DIFlagAppleBlock = 1 shl 3,
  167. DIFlagReservedBit4 = 1 shl 4,
  168. { virtual inheritance at the C++ struct level, not at method level; use the SPFlag for that virtual methods) }
  169. DIFlagVirtual = 1 shl 5,
  170. DIFlagArtificial = 1 shl 6,
  171. DIFlagExplicit = 1 shl 7,
  172. DIFlagPrototyped = 1 shl 8,
  173. DIFlagObjcClassComplete = 1 shl 9,
  174. DIFlagObjectPointer = 1 shl 10,
  175. DIFlagVector = 1 shl 11,
  176. DIFlagStaticMember = 1 shl 12,
  177. DIFlagLValueReference = 1 shl 13,
  178. DIFlagRValueReference = 1 shl 14,
  179. DIFlagReserved = 1 shl 15,
  180. DIFlagSingleInheritance = 1 shl 16,
  181. DIFlagMultipleInheritance = 1 shl 17,
  182. DIFlagVirtualInheritance = 1 shl 18,
  183. DIFlagIntroducedVirtual = 1 shl 19,
  184. DIFlagBitField = 1 shl 20,
  185. DIFlagNoReturn = 1 shl 21,
  186. { at the type level, DWARF 5 DW_CC_pass_by_value }
  187. DIFlagTypePassByValue = 1 shl 22,
  188. { at the type level, DWARF 5 DW_CC_pass_by_reference }
  189. DIFlagTypePassByReference = 1 shl 23,
  190. DIFlagEnumClass = 1 shl 24,
  191. DIFlagThunk = 1 shl 25,
  192. { moved to DISPFlags in LLVM 8.0 }
  193. DIFlagMainSubprogram_Deprecated = 1 shl 21
  194. { introduced/renamed after LLVM 7.0, but nothing we need right now
  195. ,
  196. DIFlagNonTrivial,
  197. DIFlagBigEndian,
  198. DIFlagLittleEndian
  199. }
  200. );
  201. TLLVMDISPFlags = (
  202. DISPFlagVirtual = 1,
  203. DISPFlagPureVirtual = 2,
  204. DISPFlagLocalToUnit = 1 shl 2,
  205. DISPFlagDefinition = 1 shl 3,
  206. DISPFlagOptimized = 1 shl 4,
  207. DISPFlagPure = 1 shl 5,
  208. DISPFlagElemental = 1 shl 6,
  209. DISPFlagRecursive = 1 shl 7,
  210. DISPFlagMainSubprogram = 1 shl 8,
  211. DISPFlagDeleted = 1 shl 9,
  212. DISPFlagObjCDirect = 1 shl 11
  213. );
  214. {$pop}
  215. TLLVMLocationAtom = (
  216. DW_OP_LLVM_fragment = $1000, ///< Only used in LLVM metadata.
  217. DW_OP_LLVM_convert = $1001, ///< Only used in LLVM metadata.
  218. DW_OP_LLVM_tag_offset = $1002, ///< Only used in LLVM metadata.
  219. DW_OP_LLVM_entry_value = $1003, ///< Only used in LLVM metadata.
  220. DW_OP_LLVM_implicit_pointer = $1004, ///< Only used in LLVM metadata.
  221. DW_OP_LLVM_arg = $1005 ///< Only used in LLVM metadata.
  222. );
  223. {****************************************************************************
  224. TLLVMMetaDefHashSet
  225. ****************************************************************************}
  226. class function TLLVMMetaDefHashSet.SizeOfItem: Integer;
  227. begin
  228. Result:=sizeof(TLLVMMetaDefHashSetItem);
  229. end;
  230. {****************************************************************************
  231. TDebugInfoLLVM
  232. ****************************************************************************}
  233. function TDebugInfoLLVM.absolute_llvm_path(const s:tcmdstr):tcmdstr;
  234. begin
  235. { Remove trailing / and ./ prefixes and always use a / }
  236. result:=BsToSlash(ExcludeTrailingPathDelimiter(FixFileName(ExpandFileName(s))));
  237. end;
  238. function TDebugInfoLLVM.get_def_metatai(def:tdef): PLLVMMetaDefHashSetItem;
  239. var
  240. needstructdeflab: boolean;
  241. begin
  242. if def.dbg_state=dbg_state_unused then
  243. def.dbg_state:=dbg_state_used;
  244. { Need a new meta item? }
  245. result:=PLLVMMetaDefHashSetItem(fdefmeta.FindOrAdd(@def,sizeof(def)));
  246. { the other fields besides Data are not initialised }
  247. if not assigned(result^.HashSetItem.Data) then
  248. begin
  249. { will be turned into a pointerdef (in case of Objective-C types) or
  250. typedef later on. We only really need a typedef if this def has
  251. a typesym (to add the name), but it allows us to create a generic
  252. specialised metatype node that can represent any type. Otherwise
  253. we have to duplicate the logic here to determine whether it's a
  254. basic, derived or composite type.
  255. exception: procdefs because we cannot make typedefs for those}
  256. if def.typ<>procdef then
  257. begin
  258. result^.HashSetItem.Data:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType);
  259. if is_implicit_pointer_object_type(def) then
  260. result^.struct_metadef:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType)
  261. else
  262. result^.struct_metadef:=nil;
  263. result^.implmetadef:=nil;
  264. end
  265. else
  266. begin
  267. result^.HashSetItem.Data:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubprogram);
  268. result^.struct_metadef:=nil;
  269. result^.implmetadef:=nil;
  270. end;
  271. if def.dbg_state=dbg_state_used then
  272. deftowritelist.Add(def);
  273. defnumberlist.Add(def);
  274. end;
  275. end;
  276. procedure TDebugInfoLLVM.staticvarsym_set_decl(sym: tsym; decl: taillvmdecl);
  277. var
  278. entry: PHashSetItem;
  279. begin
  280. entry:=fstaticvarsymdecl.FindOrAdd(@sym,sizeof(sym));
  281. if assigned(entry^.Data) then
  282. internalerror(2022051701);
  283. entry^.Data:=decl;
  284. end;
  285. function TDebugInfoLLVM.staticvarsym_get_decl(sym: tsym): taillvmdecl;
  286. var
  287. entry: PHashSetItem;
  288. begin
  289. result:=nil;
  290. entry:=fstaticvarsymdecl.Find(@sym,sizeof(sym));
  291. if assigned(entry) then
  292. result:=taillvmdecl(entry^.Data);
  293. end;
  294. function TDebugInfoLLVM.localvarsym_get_meta(sym: tsym; out is_new: boolean): tai_llvmspecialisedmetadatanode;
  295. var
  296. entry: PHashSetItem;
  297. begin
  298. entry:=fstaticvarsymdecl.FindOrAdd(@sym,sizeof(sym));
  299. if not assigned(entry^.Data) then
  300. begin
  301. result:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILocalVariable);
  302. current_asmdata.AsmLists[al_dwarf_info].concat(result);
  303. entry^.Data:=result;
  304. is_new:=true;
  305. exit;
  306. end;
  307. is_new:=false;
  308. result:=tai_llvmspecialisedmetadatanode(entry^.Data);
  309. end;
  310. procedure TDebugInfoLLVM.appenddef_array_internal(list: TAsmList; fordef: tdef; eledef: tdef; lowrange, highrange: asizeint);
  311. var
  312. dinode,
  313. subrangenode,
  314. exprnode: tai_llvmspecialisedmetadatanode;
  315. arrayrangenode: tai_llvmunnamedmetadatanode;
  316. begin
  317. { range of the array }
  318. subrangenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubrange);
  319. { include length }
  320. subrangenode.addqword('lowerBound',lowRange);
  321. if highrange>=0 then
  322. subrangenode.addqword('count',qword(highRange)+1)
  323. else
  324. subrangenode.addint64('count',highRange+1);
  325. list.concat(subrangenode);
  326. { collection containing the one range }
  327. arrayrangenode:=tai_llvmunnamedmetadatanode.create;
  328. arrayrangenode.addvalue(llvm_getmetadatareftypedconst(subrangenode));
  329. list.concat(arrayrangenode);
  330. { the array definition }
  331. dinode:=def_set_meta_impl(fordef,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  332. dinode.addqword('tag',ord(DW_TAG_array_type));
  333. dinode.addmetadatarefto('baseType',def_meta_node(eledef));
  334. dinode.addqword('size',eledef.size*(highrange-lowrange+1)*8);
  335. dinode.addmetadatarefto('elements',arrayrangenode);
  336. list.concat(dinode);
  337. end;
  338. function TDebugInfoLLVM.getabstractprocdeftypes(list: TAsmList; def: tabstractprocdef): tai_llvmbasemetadatanode;
  339. var
  340. types: tai_llvmunnamedmetadatanode;
  341. i: longint;
  342. begin
  343. types:=tai_llvmunnamedmetadatanode.create;
  344. list.concat(types);
  345. { we still need a DISubProgramType in this case, but not the list of types }
  346. if not(cs_debuginfo in current_settings.moduleswitches) then
  347. exit;
  348. if is_void(def.returndef) then
  349. types.addvalue(tai_simpletypedconst.create(llvm_metadatatype,nil))
  350. else
  351. types.addvalue(def_meta_ref(def.returndef));
  352. for i:=0 to def.paras.count-1 do
  353. begin
  354. types.addvalue(def_meta_ref(tparavarsym(def.paras[i]).vardef));
  355. end;
  356. result:=types;
  357. end;
  358. function TDebugInfoLLVM.def_meta_impl(def: tdef): tai_llvmspecialisedmetadatanode;
  359. begin
  360. result:=tai_llvmspecialisedmetadatanode(get_def_metatai(def)^.implmetadef);
  361. end;
  362. function TDebugInfoLLVM.def_set_meta_impl(def: tdef; meta_impl: tai_llvmspecialisedmetadatanode): tai_llvmspecialisedmetadatanode;
  363. begin
  364. tai_llvmspecialisedmetadatanode(get_def_metatai(def)^.implmetadef):=meta_impl;
  365. result:=meta_impl;
  366. end;
  367. function TDebugInfoLLVM.def_meta_class_struct(def: tobjectdef): tai_llvmbasemetadatanode;
  368. begin
  369. result:=tai_llvmbasemetadatanode(get_def_metatai(def)^.struct_metadef);
  370. end;
  371. function TDebugInfoLLVM.def_meta_node(def: tdef): tai_llvmspecialisedmetadatanode;
  372. begin
  373. if not is_void(def) then
  374. result:=tai_llvmspecialisedmetadatanode(get_def_metatai(def)^.HashSetItem.Data)
  375. else
  376. result:=nil;
  377. end;
  378. function TDebugInfoLLVM.def_meta_ref(def: tdef): tai_simpletypedconst;
  379. begin
  380. result:=llvm_getmetadatareftypedconst(def_meta_node(def));
  381. end;
  382. constructor TDebugInfoLLVM.Create;
  383. begin
  384. inherited Create;
  385. fenums:=nil;
  386. fretainedtypes:=nil;
  387. fglobals:=nil;
  388. femptyexpression:=nil;
  389. fderefexpression:=nil;
  390. fcunode:=nil;
  391. ffilemeta:=thashset.Create(10000,true,false);
  392. flocationmeta:=thashset.Create(10000,true,false);
  393. flexicalblockfilemeta:=thashset.Create(100,true,false);
  394. fdefmeta:=TLLVMMetaDefHashSet.Create(10000,true,false);
  395. fstaticvarsymdecl:=thashset.create(10000,true,false);
  396. defnumberlist:=TFPObjectList.create(false);
  397. deftowritelist:=TFPObjectList.create(false);
  398. vardatadef:=nil;
  399. end;
  400. destructor TDebugInfoLLVM.Destroy;
  401. begin
  402. // don't free fenums/fretainedtypes/fglobals, they get emitted in the assembler list
  403. ffilemeta.free;
  404. ffilemeta:=nil;
  405. flocationmeta.free;
  406. flocationmeta:=nil;
  407. flexicalblockfilemeta.free;
  408. flexicalblockfilemeta:=nil;
  409. fdefmeta.free;
  410. fdefmeta:=nil;
  411. fstaticvarsymdecl.free;
  412. fstaticvarsymdecl:=nil;
  413. flocalvarsymmeta.free;
  414. flocalvarsymmeta:=nil;
  415. defnumberlist.free;
  416. defnumberlist:=nil;
  417. deftowritelist.free;
  418. deftowritelist:=nil;
  419. fcunode.free;
  420. fcunode:=nil;
  421. inherited Destroy;
  422. end;
  423. procedure TDebugInfoLLVM.enum_membersyms_callback(p:TObject; arg: pointer);
  424. begin
  425. (*
  426. case tsym(p).typ of
  427. fieldvarsym:
  428. appendsym_fieldvar(pmembercallbackinfo(arg)^.list,pmembercallbackinfo(arg)^.structnode,tfieldvarsym(p));
  429. propertysym:
  430. appendsym_property(pmembercallbackinfo(arg)^.list,pmembercallbackinfo(arg)^.structnode,tpropertysym(p));
  431. constsym:
  432. appendsym_const_member(pmembercallbackinfo(arg)^.list,pmembercallbackinfo(arg)^.structnode,tconstsym(p),true);
  433. else
  434. ;
  435. end;
  436. *)
  437. end;
  438. procedure TDebugInfoLLVM.ensuremetainit;
  439. begin
  440. if not assigned(fllvm_dbg_addr_pd) then
  441. fllvm_dbg_addr_pd:=search_system_proc('llvm_dbg_addr');
  442. if not assigned(fenums) then
  443. begin
  444. fenums:=tai_llvmunnamedmetadatanode.create;
  445. fretainedtypes:=tai_llvmunnamedmetadatanode.create;
  446. fglobals:=tai_llvmunnamedmetadatanode.create;
  447. femptyexpression:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
  448. fderefexpression:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
  449. fderefexpression.addenum('','DW_OP_deref');
  450. fcunode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompileUnit);
  451. end;
  452. end;
  453. procedure TDebugInfoLLVM.resetfornewmodule;
  454. var
  455. i: longint;
  456. begin
  457. { for LLVM, we need to generate the procdef type info (or at least
  458. temporary references to it) already during the generation of the line
  459. info (all line info metadata needs a reference to its parent scope,
  460. the procdef). Since the line info is generated per procedure and
  461. the type info only at the end, we can't allocate the type info
  462. structures at the start of the type info generation like for other
  463. debug info producers. Instead, we have to initialise everything in the
  464. constructor, and then reset it at the end of the debug info pass
  465. (inserting the module info) }
  466. ffilemeta.Clear;
  467. flocationmeta.Clear;
  468. flexicalblockfilemeta.Clear;
  469. fdefmeta.free;
  470. fstaticvarsymdecl.Clear;
  471. { one item per def, plus some extra space in case of nested types,
  472. externally used types etc (it will grow further if necessary) }
  473. i:=current_module.localsymtable.DefList.count*4;
  474. if assigned(current_module.globalsymtable) then
  475. inc(i,current_module.globalsymtable.DefList.count*2);
  476. fdefmeta:=TLLVMMetaDefHashSet.Create(i,true,false);
  477. defnumberlist.Clear;
  478. deftowritelist.Clear;
  479. fcunode:=nil;
  480. fenums:=nil;
  481. fretainedtypes:=nil;
  482. fglobals:=nil;
  483. femptyexpression:=nil;
  484. fderefexpression:=nil;
  485. end;
  486. procedure TDebugInfoLLVM.collectglobalsyms;
  487. var
  488. i: TAsmListType;
  489. hp: tai;
  490. begin
  491. for i in globaldataasmlisttypes do
  492. begin
  493. if not assigned(current_asmdata.AsmLists[i]) then
  494. continue;
  495. hp:=tai(current_asmdata.AsmLists[i].First);
  496. while assigned(hp) do
  497. begin
  498. if (hp.typ=ait_llvmdecl) and
  499. assigned(taillvmdecl(hp).sym) then
  500. staticvarsym_set_decl(taillvmdecl(hp).sym,taillvmdecl(hp));
  501. hp:=tai(hp.next);
  502. end;
  503. end;
  504. end;
  505. procedure TDebugInfoLLVM.updatelocalvardbginfo(hp: taillvm; pd: tprocdef; functionscope: tai_llvmspecialisedmetadatanode);
  506. var
  507. opindex, callparaindex: longint;
  508. paras: tfplist;
  509. sympara,
  510. exprpara: pllvmcallpara;
  511. sym: tabstractnormalvarsym;
  512. dilocalvar: tai_llvmspecialisedmetadatanode;
  513. isnewlocalvardi,
  514. deref: boolean;
  515. begin
  516. { not really clean since hardcoding the structure of the call
  517. instruction's procdef encoding, but quick }
  518. if (hp.oper[taillvm.callpdopernr]^.def.typ<>pointerdef) or
  519. (tpointerdef(hp.oper[taillvm.callpdopernr]^.def).pointeddef<>fllvm_dbg_addr_pd) then
  520. exit;
  521. deref:=false;
  522. sympara:=hp.getcallpara(1);
  523. exprpara:=hp.getcallpara(2);
  524. if sympara^.val.typ<>top_local then
  525. internalerror(2022052613);
  526. sym:=tabstractnormalvarsym(sympara^.val.localsym);
  527. dilocalvar:=localvarsym_get_meta(sym,isnewlocalvardi);
  528. sympara^.loadtai(llvm_getmetadatareftypedconst(dilocalvar));
  529. if isnewlocalvardi then
  530. begin
  531. dilocalvar.addstring('name',symname(sym,false));
  532. if sym.typ=paravarsym then
  533. begin
  534. dilocalvar.addint64('arg',tparavarsym(sym).paranr);
  535. if paramanager.push_addr_param(sym.varspez,sym.vardef,pd.proccalloption) then
  536. deref:=true;
  537. end;
  538. dilocalvar.addmetadatarefto('scope',functionscope);
  539. try_add_file_metaref(dilocalvar,sym.fileinfo,false);
  540. dilocalvar.addmetadatarefto('type',def_meta_node(sym.vardef));
  541. end
  542. else
  543. begin
  544. if (sym.typ=paravarsym) and
  545. paramanager.push_addr_param(sym.varspez,sym.vardef,pd.proccalloption) then
  546. deref:=true;
  547. end;
  548. if not deref then
  549. exprpara^.loadtai(llvm_getmetadatareftypedconst(femptyexpression))
  550. else
  551. exprpara^.loadtai(llvm_getmetadatareftypedconst(fderefexpression));
  552. end;
  553. function TDebugInfoLLVM.file_getmetanode(moduleindex: tfileposmoduleindex; fileindex: tfileposfileindex): tai_llvmspecialisedmetadatanode;
  554. var
  555. infile: tinputfile;
  556. dirname: TSymStr;
  557. item: PHashSetItem;
  558. metaitem: tai_llvmspecialisedmetadatanode;
  559. modfileindex: packed record
  560. moduleindex: tfileposmoduleindex;
  561. fileindex: tfileposfileindex;
  562. end;
  563. begin
  564. modfileindex.moduleindex:=moduleindex;
  565. modfileindex.fileindex:=fileindex;
  566. item:=ffilemeta.FindOrAdd(@modfileindex,sizeof(modfileindex));
  567. if not assigned(item^.Data) then
  568. begin
  569. infile:=get_module(moduleindex).sourcefiles.get_file(fileindex);
  570. if not assigned(infile) then
  571. begin
  572. result:=nil;
  573. exit;
  574. end;
  575. if infile.path = '' then
  576. dirname:=absolute_llvm_path('.')
  577. else
  578. begin
  579. { add the canonical form here already to avoid problems with }
  580. { paths such as './' etc }
  581. dirname:=absolute_llvm_path(infile.path);
  582. end;
  583. if dirname='' then
  584. dirname:='.';
  585. metaitem:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIFile);
  586. metaitem.addstring('filename',infile.name);
  587. metaitem.addstring('directory',dirname);
  588. current_asmdata.AsmLists[al_dwarf_line].concat(metaitem);
  589. item^.Data:=metaitem;
  590. end;
  591. result:=tai_llvmspecialisedmetadatanode(item^.Data);
  592. end;
  593. function TDebugInfoLLVM.filepos_getmetanode(const filepos: tfileposinfo; const functionfileinfo: tfileposinfo; const functionscope: tai_llvmspecialisedmetadatanode; nolineinfo: boolean): tai_llvmspecialisedmetadatanode;
  594. var
  595. item: PHashSetItem;
  596. filemeta,
  597. locationscopemeta: tai_llvmspecialisedmetadatanode;
  598. lexicalblockkey: packed record
  599. scopemeta,
  600. filemeta: tai_llvmspecialisedmetadatanode;
  601. end;
  602. locationkey: packed record
  603. scope: tai_llvmspecialisedmetadatanode;
  604. line: tfileposline;
  605. column: tfileposcolumn;
  606. end;
  607. begin
  608. result:=nil;
  609. if (filepos.fileindex<>0) then
  610. filemeta:=file_getmetanode(filepos.moduleindex,filepos.fileindex)
  611. else
  612. filemeta:=file_getmetanode(functionfileinfo.moduleindex,functionfileinfo.fileindex);
  613. if not assigned(filemeta) then
  614. exit;
  615. if (filepos.fileindex<>0) and
  616. (filepos.fileindex<>functionfileinfo.fileindex) then
  617. begin
  618. lexicalblockkey.scopemeta:=functionscope;
  619. lexicalblockkey.filemeta:=filemeta;
  620. item:=flexicalblockfilemeta.FindOrAdd(@lexicalblockkey,sizeof(lexicalblockkey));
  621. if not assigned(item^.Data) then
  622. begin
  623. locationscopemeta:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILexicalBlockFile);
  624. locationscopemeta.addmetadatarefto('scope',functionscope);
  625. locationscopemeta.addmetadatarefto('file',filemeta);
  626. locationscopemeta.addint64('discriminator',0);
  627. current_asmdata.AsmLists[al_dwarf_line].concat(locationscopemeta);
  628. item^.Data:=locationscopemeta;
  629. end
  630. else
  631. locationscopemeta:=tai_llvmspecialisedmetadatanode(item^.Data);
  632. end
  633. else
  634. locationscopemeta:=functionscope;
  635. locationkey.scope:=locationscopemeta;
  636. if not nolineinfo then
  637. begin
  638. locationkey.line:=filepos.line;
  639. locationkey.column:=filepos.column;
  640. end
  641. else
  642. begin
  643. locationkey.line:=0;
  644. locationkey.column:=0;
  645. end;
  646. item:=flocationmeta.FindOrAdd(@locationkey,sizeof(locationkey));
  647. if not assigned(item^.Data) then
  648. begin
  649. result:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILocation);
  650. if not nolineinfo then
  651. begin
  652. result.addqword('line',filepos.line);
  653. result.addqword('column',filepos.column);
  654. end
  655. else
  656. result.addqword('line',0);
  657. result.addmetadatarefto('scope',locationscopemeta);
  658. current_asmdata.AsmLists[al_dwarf_line].concat(result);
  659. item^.Data:=result;
  660. end
  661. else
  662. result:=tai_llvmspecialisedmetadatanode(item^.Data);
  663. end;
  664. procedure TDebugInfoLLVM.try_add_file_metaref(dinode: tai_llvmspecialisedmetadatanode; const fileinfo: tfileposinfo; includescope: boolean);
  665. var
  666. filemeta: tai_llvmbasemetadatanode;
  667. begin
  668. filemeta:=file_getmetanode(fileinfo.moduleindex,fileinfo.fileindex);
  669. if assigned(filemeta) then
  670. begin
  671. if includescope then
  672. begin
  673. dinode.addmetadatarefto('scope',filemeta);
  674. end;
  675. dinode.addmetadatarefto('file',filemeta);
  676. dinode.addqword('line',fileinfo.line);
  677. end;
  678. end;
  679. function TDebugInfoLLVM.add_line_metanode(const fileinfo: tfileposinfo): tai_llvmspecialisedmetadatanode;
  680. var
  681. filemeta: tai_llvmbasemetadatanode;
  682. begin
  683. filemeta:=file_getmetanode(fileinfo.moduleindex,fileinfo.fileindex);
  684. if not assigned(filemeta) then
  685. internalerror(2022041701);
  686. result:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILocation);
  687. result.addqword('line',fileinfo.line);
  688. result.addqword('column',fileinfo.column);
  689. result.addmetadatarefto('scope',filemeta);
  690. current_asmdata.AsmLists[al_dwarf_line].concat(result);
  691. end;
  692. procedure TDebugInfoLLVM.appenddef_ord(list:TAsmList;def:torddef);
  693. var
  694. ordtype: tordtype;
  695. dinode: tai_llvmspecialisedmetadatanode;
  696. begin
  697. { nothing, must be referenced as "null" in the using declaration }
  698. if is_void(def) then
  699. exit;
  700. ordtype:=def.ordtype;
  701. if ordtype=customint then
  702. ordtype:=range_to_basetype(def.low,def.high);
  703. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIBasicType));
  704. case ordtype of
  705. s8bit,
  706. s16bit,
  707. s32bit,
  708. u8bit,
  709. u16bit,
  710. u32bit,
  711. u64bit,
  712. s64bit,
  713. u128bit,
  714. s128bit:
  715. begin
  716. dinode.addqword('size',def.size*8);
  717. if def.alignment<>def.size then
  718. dinode.addqword('align',def.alignment*8);
  719. { generate proper signed/unsigned info for types like 0..3 }
  720. { these are s8bit, but should be identified as unsigned }
  721. { because otherwise they are interpreted wrongly when used }
  722. { in a bitpacked record }
  723. if def.low<0 then
  724. dinode.addqword('encoding',ord(DW_ATE_signed))
  725. else
  726. dinode.addqword('encoding',ord(DW_ATE_unsigned));
  727. end;
  728. uvoid :
  729. begin
  730. { checked above }
  731. end;
  732. uchar,
  733. uwidechar :
  734. begin
  735. dinode.addqword('size',def.size*8);
  736. dinode.addint64('encoding',ord(DW_ATE_unsigned_char));
  737. end;
  738. pasbool1,
  739. pasbool8,
  740. bool8bit,
  741. pasbool16,
  742. bool16bit,
  743. pasbool32,
  744. bool32bit,
  745. pasbool64,
  746. bool64bit:
  747. begin
  748. dinode.addqword('size',def.size*8);
  749. dinode.addint64('encoding',ord(DW_ATE_boolean));
  750. end;
  751. scurrency:
  752. begin
  753. { we should use DW_ATE_signed_fixed, however it isn't supported yet by LLVM }
  754. dinode.addqword('size',def.size*8);
  755. dinode.addint64('encoding',ord(DW_ATE_signed));
  756. end;
  757. customint:
  758. internalerror(2021111502);
  759. end;
  760. list.concat(dinode);
  761. end;
  762. procedure TDebugInfoLLVM.appenddef_float(list:TAsmList;def:tfloatdef);
  763. var
  764. dinode: tai_llvmspecialisedmetadatanode;
  765. begin
  766. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIBasicType));
  767. case def.floattype of
  768. s32real,
  769. s64real,
  770. s80real,
  771. sc80real,
  772. s128real:
  773. begin
  774. dinode.addqword('size',def.size*8);
  775. if def.alignment<>def.size then
  776. dinode.addqword('align',def.alignment*8);
  777. dinode.addint64('encoding',ord(DW_ATE_float));
  778. end;
  779. s64currency:
  780. begin
  781. { we should use DW_ATE_signed_fixed, however it isn't supported yet by LLVM }
  782. dinode.addqword('size',def.size*8);
  783. dinode.addint64('encoding',ord(DW_ATE_signed));
  784. end;
  785. s64comp:
  786. begin
  787. { we should use DW_ATE_signed_fixed, however it isn't supported yet by LLVM }
  788. dinode.addqword('size',def.size*8);
  789. dinode.addint64('encoding',ord(DW_ATE_signed));
  790. end;
  791. end;
  792. list.concat(dinode);
  793. end;
  794. procedure TDebugInfoLLVM.appenddef_enum(list:TAsmList;def:tenumdef);
  795. var
  796. hp : tenumsym;
  797. i : longint;
  798. dinode: tai_llvmspecialisedmetadatanode;
  799. enumelem: tai_llvmspecialisedmetadatanode;
  800. enumlist: tai_llvmunnamedmetadatanode;
  801. begin
  802. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  803. dinode.addqword('tag',ord(DW_TAG_enumeration_type));
  804. dinode.addqword('size',def.size*8);
  805. dinode.addstring('identifier',def.mangledparaname);
  806. { register in module's list of enums (to ensure the debug info gets
  807. emitted even if the enum is not used in the current module) }
  808. fenums.addvalue(llvm_getmetadatareftypedconst(dinode));
  809. enumlist:=tai_llvmunnamedmetadatanode.create;
  810. { add enum symbols }
  811. for i:=0 to def.symtable.SymList.Count-1 do
  812. begin
  813. hp:=tenumsym(def.symtable.SymList[i]);
  814. if hp.value<def.minval then
  815. continue
  816. else if hp.value>def.maxval then
  817. break;
  818. enumelem:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIEnumerator);
  819. enumelem.addstring('name',symname(hp, false));
  820. enumelem.addint64('value',hp.value);
  821. list.concat(enumelem);
  822. enumlist.addvalue(llvm_getmetadatareftypedconst(enumelem));
  823. end;
  824. if enumlist.valuecount<>0 then
  825. begin
  826. list.concat(enumlist);
  827. dinode.addmetadatarefto('elements',enumlist);
  828. end
  829. else
  830. begin
  831. enumlist.free;
  832. end;
  833. list.concat(dinode);
  834. end;
  835. procedure TDebugInfoLLVM.appenddef_array(list:TAsmList;def:tarraydef);
  836. var
  837. dinode,
  838. subrangenode,
  839. exprnode: tai_llvmspecialisedmetadatanode;
  840. arrayrangenode: tai_llvmunnamedmetadatanode;
  841. size : qword;
  842. nesteddef: tdef;
  843. power: longint;
  844. flags: TLLVMDIFlags;
  845. begin
  846. if is_dynamic_array(def) { and
  847. not(llvmflag_array_datalocation in llvmversion_properties[current_settings.llvmversion]) } then
  848. begin
  849. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  850. dinode.addqword('tag',ord(DW_TAG_pointer_type));
  851. dinode.addmetadatarefto('baseType',def_meta_node(def.elementdef));
  852. dinode.addqword('size',def.size*8);
  853. list.concat(dinode);
  854. exit;
  855. end;
  856. { open arrays etc need to access the high parameter to define their range,
  857. which is not possible here since we need the parasym rather than the def }
  858. if is_open_array(def) then
  859. begin
  860. (*
  861. if llvmflag_array_datalocation in llvmversion_properties[current_settings.llvmversion] then
  862. begin
  863. dinode:=def_meta_impl(def);
  864. { should be generated as part of the parasym }
  865. if not assigned(dinode) then
  866. internalerror(2021112002);
  867. end
  868. else *)
  869. begin
  870. { no idea about the size, generate an array of 1 element -- although it could be empty }
  871. appenddef_array_internal(list,def,def.elementdef,0,1);
  872. end;
  873. exit;
  874. end;
  875. if is_array_of_const(def) then
  876. begin
  877. { no idea about the size, generate an array of 1 element -- although it could be empty }
  878. appenddef_array_internal(list,def,def.elementdef,0,1);
  879. exit;
  880. end;
  881. if is_special_array(def)
  882. and not((llvmflag_array_datalocation in llvmversion_properties[current_settings.llvmversion]) and
  883. is_dynamic_array(def)) then
  884. internalerror(2021121902);
  885. { todo: proper support for bitpacked arrays }
  886. if is_packed_array(def) and
  887. (((def.elementdef.packedbitsize mod 8)<>0) or
  888. not ispowerof2(def.elementdef.packedbitsize div 8,power)) then
  889. begin
  890. { for now just encode as an array of bytes }
  891. appenddef_array_internal(list,def,u8inttype,0,def.size-1);
  892. exit;
  893. end;
  894. { collection of all ranges of the array (to support multi-dimensional arrays) }
  895. arrayrangenode:=tai_llvmunnamedmetadatanode.create;
  896. list.concat(arrayrangenode);
  897. { range of the array }
  898. subrangenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubrange);
  899. if is_dynamic_array(def) then
  900. begin
  901. exprnode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
  902. exprnode.addint64('',ord(DW_OP_push_object_address));
  903. exprnode.addint64('',ord(DW_OP_constu));
  904. exprnode.addint64('',ord(sizeof(pint)));
  905. exprnode.addint64('',ord(DW_OP_minus));
  906. exprnode.addint64('',ord(DW_OP_deref));
  907. list.concat(exprnode);
  908. subrangenode.addmetadatarefto('upperBound',exprnode);
  909. subrangenode.addint64('lowerBound',def.lowrange);
  910. end
  911. else
  912. begin
  913. subrangenode.addqword('count',def.highrange-def.lowrange+1);
  914. subrangenode.addint64('lowerBound',def.lowrange);
  915. end;
  916. list.concat(subrangenode);
  917. nesteddef:=def.elementdef;
  918. arrayrangenode.addvalue(llvm_getmetadatareftypedconst(subrangenode));
  919. while (nesteddef.typ=arraydef) and
  920. not is_special_array(nesteddef) do
  921. begin
  922. subrangenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubrange);
  923. subrangenode.addqword('count',tarraydef(nesteddef).highrange-tarraydef(nesteddef).lowrange+1);
  924. subrangenode.addint64('lowerBound',tarraydef(nesteddef).lowrange);
  925. list.concat(subrangenode);
  926. arrayrangenode.addvalue(llvm_getmetadatareftypedconst(subrangenode));
  927. nesteddef:=tarraydef(nesteddef).elementdef;
  928. end;
  929. { the array definition }
  930. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  931. dinode.addqword('tag',ord(DW_TAG_array_type));
  932. dinode.addmetadatarefto('baseType',def_meta_node(nesteddef));
  933. dinode.addmetadatarefto('elements',arrayrangenode);
  934. if is_vector(def) then
  935. dinode.addenum('flags','DIFlagVector');
  936. if not is_dynamic_array(def) then
  937. if def.size<(qword(1) shl 61) then
  938. dinode.addqword('size',def.size*8)
  939. else
  940. { LLVM internally "only" supports sizes up to 1 shl 61, because they
  941. store all sizes in bits in a qword; the rationale is that there
  942. is no hardware supporting a full 64 bit address space either }
  943. dinode.addqword('size',qword(1) shl 61)
  944. else
  945. begin
  946. exprnode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
  947. exprnode.addqword('',ord(DW_OP_LLVM_implicit_pointer));
  948. list.concat(exprnode);
  949. dinode.addmetadatarefto('dataLocation',exprnode);
  950. end;
  951. list.concat(dinode);
  952. end;
  953. procedure TDebugInfoLLVM.appenddef_record(list:TAsmList;def:trecorddef);
  954. begin
  955. if assigned(def.objname) then
  956. appenddef_record_named(list,def,def,def.objname^)
  957. else
  958. appenddef_record_named(list,def,def,'');
  959. end;
  960. procedure TDebugInfoLLVM.appenddef_record_named(list:TAsmList; fordef: tdef; def:trecorddef; const name: TSymStr);
  961. var
  962. dinode: tai_llvmspecialisedmetadatanode;
  963. begin
  964. dinode:=def_set_meta_impl(fordef,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  965. dinode.addint64('tag',ord(DW_TAG_structure_type));
  966. if (name<>'') then
  967. dinode.addstring('name',name);
  968. if def.size<(qword(1) shl 61) then
  969. dinode.addqword('size',def.size*8)
  970. else
  971. { LLVM internally "only" supports sizes up to 1 shl 61, because they
  972. store all sizes in bits in a qword; the rationale is that there
  973. is no hardware supporting a full 64 bit address space either }
  974. dinode.addqword('size',qword(1) shl 61);
  975. list.concat(dinode);
  976. // def.symtable.symList.ForEachCall(@enum_membersyms_callback,dinode);
  977. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.symtable);
  978. end;
  979. procedure TDebugInfoLLVM.appenddef_pointer(list:TAsmList;def:tpointerdef);
  980. var
  981. dinode: tai_llvmspecialisedmetadatanode;
  982. begin
  983. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  984. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  985. if not(is_voidpointer(def)) then
  986. dinode.addmetadatarefto('baseType',def_meta_node(def.pointeddef))
  987. else
  988. dinode.addmetadatarefto('baseType',nil);
  989. list.concat(dinode);
  990. end;
  991. procedure TDebugInfoLLVM.appenddef_formal(list: TAsmList; def: tformaldef);
  992. var
  993. dinode: tai_llvmspecialisedmetadatanode;
  994. begin
  995. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  996. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  997. dinode.addmetadatarefto('baseType',nil);
  998. list.concat(dinode);
  999. end;
  1000. procedure TDebugInfoLLVM.appenddef_string(list:TAsmList;def:tstringdef);
  1001. procedure addnormalstringdef(const name: TSymStr; lendef: tdef; maxlen: asizeuint);
  1002. var
  1003. dinode,
  1004. subrangenode,
  1005. exprnode: tai_llvmspecialisedmetadatanode;
  1006. arrayrangenode: tai_aggregatetypedconst;
  1007. { maxlen can be > high(int64) }
  1008. slen : asizeuint;
  1009. arr : tasmlabel;
  1010. begin
  1011. { fix length of openshortstring }
  1012. slen:=aword(def.len);
  1013. if (slen=0) or
  1014. (slen>maxlen) then
  1015. slen:=maxlen;
  1016. appenddef_array_internal(list,def,cansichartype,0,slen);
  1017. end;
  1018. var
  1019. dinode: tai_llvmspecialisedmetadatanode;
  1020. begin
  1021. case def.stringtype of
  1022. st_shortstring:
  1023. begin
  1024. addnormalstringdef('ShortString',u8inttype,255);
  1025. end;
  1026. st_longstring:
  1027. begin
  1028. { a) we don't actually support variables of this type currently
  1029. b) this type is only used as the type for constant strings
  1030. > 255 characters
  1031. c) in such a case, gdb will allocate and initialise enough
  1032. memory to hold the maximum size for such a string
  1033. -> don't use high(qword)/high(cardinal) as maximum, since that
  1034. will cause exhausting the VM space, but some "reasonably high"
  1035. number that should be enough for most constant strings
  1036. }
  1037. {$ifdef cpu64bitaddr}
  1038. addnormalstringdef('LongString',u64inttype,qword(1024*1024));
  1039. {$endif cpu64bitaddr}
  1040. {$ifdef cpu32bitaddr}
  1041. addnormalstringdef('LongString',u32inttype,cardinal(1024*1024));
  1042. {$endif cpu32bitaddr}
  1043. {$ifdef cpu16bitaddr}
  1044. addnormalstringdef('LongString',u16inttype,cardinal(1024));
  1045. {$endif cpu16bitaddr}
  1046. end;
  1047. st_ansistring:
  1048. begin
  1049. // Todo: dynamic length "array"
  1050. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1051. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1052. dinode.addmetadatarefto('baseType',def_meta_node(cansichartype));
  1053. list.concat(dinode);
  1054. end;
  1055. st_unicodestring,
  1056. st_widestring:
  1057. begin
  1058. // Todo: dynamic length "array"
  1059. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1060. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1061. dinode.addmetadatarefto('baseType',def_meta_node(cwidechartype));
  1062. list.concat(dinode);
  1063. end;
  1064. end;
  1065. end;
  1066. procedure TDebugInfoLLVM.appenddef_procvar(list:TAsmList;def:tprocvardef);
  1067. var
  1068. dinode: tai_llvmspecialisedmetadatanode;
  1069. begin
  1070. { plain pointer for now }
  1071. if def.is_addressonly then
  1072. begin
  1073. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1074. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1075. dinode.addmetadatarefto('baseType',nil);
  1076. list.concat(dinode);
  1077. end
  1078. else
  1079. begin
  1080. appenddef_array_internal(list,def,voidcodepointertype,1,2);
  1081. end;
  1082. end;
  1083. procedure TDebugInfoLLVM.appenddef_file(list: TAsmList; def: tfiledef);
  1084. var
  1085. dinode: tai_llvmspecialisedmetadatanode;
  1086. begin
  1087. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  1088. dinode.addint64('tag',ord(DW_TAG_structure_type));
  1089. if assigned(def.typesym) then
  1090. dinode.addstring('name',symname(def.typesym, false));
  1091. dinode.addqword('size',def.size*8);
  1092. list.concat(dinode);
  1093. end;
  1094. procedure TDebugInfoLLVM.appenddef_object(list: TAsmList; def: tobjectdef);
  1095. var
  1096. dinode: tai_llvmspecialisedmetadatanode;
  1097. begin
  1098. if is_implicit_pointer_object_type(def) then
  1099. begin
  1100. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1101. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1102. dinode.addmetadatarefto('baseType',nil);
  1103. end
  1104. else
  1105. begin
  1106. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  1107. dinode.addint64('tag',ord(DW_TAG_structure_type));
  1108. if assigned(def.typesym) then
  1109. dinode.addstring('name',symname(def.typesym, false));
  1110. dinode.addqword('size',def.size*8);
  1111. end;
  1112. list.concat(dinode);
  1113. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.symtable);
  1114. end;
  1115. procedure TDebugInfoLLVM.appenddef_set(list: TAsmList; def: tsetdef);
  1116. begin
  1117. appenddef_array_internal(list,def,u8inttype,0,def.size-1);
  1118. end;
  1119. procedure TDebugInfoLLVM.appenddef_undefined(list: TAsmList; def: tundefineddef);
  1120. var
  1121. dinode: tai_llvmspecialisedmetadatanode;
  1122. begin
  1123. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1124. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1125. dinode.addmetadatarefto('baseType',nil);
  1126. list.concat(dinode);
  1127. end;
  1128. procedure TDebugInfoLLVM.appenddef_classref(list: TAsmList; def: tclassrefdef);
  1129. var
  1130. dinode: tai_llvmspecialisedmetadatanode;
  1131. begin
  1132. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1133. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1134. dinode.addmetadatarefto('baseType',nil);
  1135. list.concat(dinode);
  1136. end;
  1137. procedure TDebugInfoLLVM.appenddef_variant(list: TAsmList; def: tvariantdef);
  1138. begin
  1139. if assigned(vardatadef) then
  1140. appenddef_record_named(list,def,trecorddef(vardatadef),'Variant');
  1141. end;
  1142. procedure TDebugInfoLLVM.afterappenddef(list:TAsmList;def:tdef);
  1143. var
  1144. tempdinode,
  1145. refdinode,
  1146. impldinode: tai_llvmspecialisedmetadatanode;
  1147. begin
  1148. if def.typ=procdef then
  1149. exit;
  1150. if is_void(def) then
  1151. exit;
  1152. refdinode:=def_meta_node(def);
  1153. if is_objc_class_or_protocol(def) then
  1154. begin
  1155. { for Objective-C classes, the named typedef must refer to the
  1156. struct itself, not to the pointer of the struct; Objective-C
  1157. classes are not implicit pointers in Objective-C itself, only
  1158. in FPC. So make the def label point to a pointer to the
  1159. typedef, which in turn refers to the actual struct (for Delphi-
  1160. style classes, the def points to the typedef, which refers to
  1161. a pointer to the actual struct) }
  1162. { implicit pointer }
  1163. tempdinode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType);
  1164. refdinode.addint64('tag',ord(DW_TAG_pointer_type));
  1165. refdinode.addmetadatarefto('baseType',tempdinode);
  1166. list.concat(refdinode);
  1167. { typedef }
  1168. refdinode:=tempdinode;
  1169. end;
  1170. refdinode.addint64('tag',ord(DW_TAG_typedef));
  1171. if assigned(def.typesym) and
  1172. not(df_generic in def.defoptions) then
  1173. begin
  1174. refdinode.addstring('name',symname(def.typesym,false));
  1175. try_add_file_metaref(refdinode,def.typesym.fileinfo,false);
  1176. end;
  1177. impldinode:=def_meta_impl(def);
  1178. if not assigned(impldinode) then
  1179. internalerror(2021120501);
  1180. refdinode.addmetadatarefto('baseType',impldinode);
  1181. list.concat(refdinode);
  1182. end;
  1183. procedure TDebugInfoLLVM.appendprocdef(list:TAsmList; def:tprocdef);
  1184. procedure adddispflags(dinode: tai_llvmspecialisedmetadatanode; is_definition, is_virtual: boolean);
  1185. var
  1186. dispflags: TSymStr;
  1187. islocal: boolean;
  1188. begin
  1189. islocal:=
  1190. not((po_global in def.procoptions) and
  1191. (def.parast.symtablelevel<=normal_function_level));
  1192. adddefinitionlocal(dinode,is_definition,islocal,not(llvmflag_NoDISPFlags in llvmversion_properties[current_settings.llvmversion]),dispflags);
  1193. if llvmflag_NoDISPFlags in llvmversion_properties[current_settings.llvmversion] then
  1194. begin
  1195. if is_virtual then
  1196. begin
  1197. if not(po_abstractmethod in def.procoptions) then
  1198. dinode.addenum('virtuality','DW_VIRTUALITY_virtual')
  1199. else
  1200. dinode.addenum('virtuality','DW_VIRTUALITY_pure_virtual');
  1201. end;
  1202. exit;
  1203. end;
  1204. if is_virtual then
  1205. begin
  1206. if dispflags<>'' then
  1207. dispflags:=dispflags+'|';
  1208. if not(po_abstractmethod in def.procoptions) then
  1209. dispflags:=dispflags+'DISPFlagVirtual'
  1210. else
  1211. dispflags:=dispflags+'DISPFlagPureVirtual';
  1212. end
  1213. else
  1214. begin
  1215. { this one will always be a definition, so no need to check
  1216. whether result is empty }
  1217. if not(llvmflag_NoDISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and
  1218. (def.proctypeoption=potype_proginit) then
  1219. dispflags:=dispflags+'|DISPFlagMainSubprogram';
  1220. end;
  1221. if dispflags<>'' then
  1222. dinode.addenum('spFlags',dispflags);
  1223. end;
  1224. procedure adddiflags(dinode: tai_llvmspecialisedmetadatanode; is_definition: boolean);
  1225. var
  1226. diflags: TSymStr;
  1227. begin
  1228. if (llvmflag_NoDISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and
  1229. (def.proctypeoption=potype_proginit) then
  1230. diflags:='DIFlagMainSubprogram'
  1231. else if def.owner.symtabletype in [objectsymtable,recordsymtable] then
  1232. diflags:=visibilitydiflag(def.visibility)
  1233. else
  1234. diflags:='';
  1235. if diflags<>'' then
  1236. dinode.addenum('flags',diflags);
  1237. end;
  1238. var
  1239. dinode,
  1240. ditypenode : tai_llvmspecialisedmetadatanode;
  1241. fileref : tai_simpletypedconst;
  1242. procdeftai : tai;
  1243. st : tsymtable;
  1244. vmtoffset : pint;
  1245. flags : TSymStr;
  1246. in_currentunit,
  1247. is_virtual : boolean;
  1248. begin
  1249. { only write debug info for procedures defined in the current module,
  1250. except in case of methods (clang-compatible)
  1251. }
  1252. in_currentunit:=def.in_currentunit;
  1253. if not in_currentunit and
  1254. not (def.owner.symtabletype in [objectsymtable,recordsymtable]) then
  1255. exit;
  1256. { happens for init procdef of units without init section }
  1257. if in_currentunit and
  1258. not assigned(def.procstarttai) then
  1259. exit;
  1260. { These don't contain a taillvmdecl, they are completely generated
  1261. in native assembly. If we want to add debug information to these,
  1262. we have to do it using the regular debug info generation }
  1263. if po_assembler in def.procoptions then
  1264. exit;
  1265. if df_generic in def.defoptions then
  1266. exit;
  1267. { Procdefs are not handled by the regular def writing code, so
  1268. dbg_state is not set/checked for them. Do it here. }
  1269. if (def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  1270. exit;
  1271. defnumberlist.Add(def);
  1272. def.dbg_state:=dbg_state_writing;
  1273. { difference compared to other kinds of defs: the DISubProgram gets
  1274. created directly in get_def_metatai because a typedef for a
  1275. DISubProgram does not make sense and is not supported by LLVM ->
  1276. don't set the implementation of the metadata def here and just use
  1277. the regular node }
  1278. dinode:=def_meta_node(def);
  1279. list.concat(dinode);
  1280. { we have to attach the debug info to the definition instruction of the
  1281. proc }
  1282. procdeftai:=nil;
  1283. if in_currentunit then
  1284. begin
  1285. procdeftai:=def.procstarttai;
  1286. if (procdeftai.typ<>ait_llvmdecl) or
  1287. (taillvmdecl(procdeftai).def<>def) then
  1288. internalerror(2022022010);
  1289. taillvmdecl(procdeftai).addinsmetadata(tai_llvmmetadatareferenceoperand.createreferenceto('dbg',dinode));
  1290. end;
  1291. dinode.addstring('name',symdebugname(def.procsym));
  1292. try_add_file_metaref(dinode,def.fileinfo,true);
  1293. if not(cs_debuginfo in current_settings.moduleswitches) then
  1294. begin
  1295. def.dbg_state:=dbg_state_written;
  1296. exit;
  1297. end;
  1298. is_virtual:=
  1299. (([po_abstractmethod, po_virtualmethod, po_overridingmethod]*def.procoptions)<>[]) and
  1300. not is_objc_class_or_protocol(def.struct) and
  1301. not is_objectpascal_helper(def.struct);
  1302. adddispflags(dinode,in_currentunit,is_virtual);
  1303. if is_virtual then
  1304. begin
  1305. { the sizeof(pint) is a bit iffy, since vmtmethodoffset() calculates
  1306. using a combination of voidcodepointer.size, voidpointer.size, and
  1307. sizeof(pint). But that's what the debugger will use }
  1308. dinode.addint64('virtualIndex',tobjectdef(def.owner.defowner).vmtmethodoffset(def.extnumber) div sizeof(pint));
  1309. {$ifdef extdebug}
  1310. if (tobjectdef(def.owner.defowner).vmtmethodoffset(def.extnumber) mod sizeof(pint))<>0 then
  1311. internalerror(2022043001);
  1312. {$endif}
  1313. end;
  1314. adddiflags(dinode,in_currentunit);
  1315. dinode.addmetadatarefto('unit',fcunode);
  1316. ditypenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubroutineType);
  1317. ditypenode.addmetadatarefto('types',getabstractprocdeftypes(list,def));
  1318. list.concat(ditypenode);
  1319. dinode.addmetadatarefto('type',ditypenode);
  1320. (*
  1321. if assigned(def.parast) then
  1322. begin
  1323. { First insert self, because gdb uses the fact whether or not the
  1324. first parameter of a method is artificial to distinguish static
  1325. from regular methods. }
  1326. { fortunately, self is the always the first parameter in the
  1327. paralist, since it has the lowest paranr. Note that this is not
  1328. true for Objective-C, but those methods are detected in
  1329. another way (by reading the ObjC run time information) }
  1330. write_symtable_parasyms(current_asmdata.asmlists[al_dwarf_info],def.paras);
  1331. end;
  1332. { local type defs and vars should not be written
  1333. inside the main proc }
  1334. if in_currentunit and
  1335. assigned(def.localst) and
  1336. (def.localst.symtabletype=localsymtable) then
  1337. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],def.localst);
  1338. { last write the types from this procdef }
  1339. if assigned(def.parast) then
  1340. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
  1341. { only try to write the localst if the routine is implemented here }
  1342. if in_currentunit and
  1343. assigned(def.localst) and
  1344. (def.localst.symtabletype=localsymtable) then
  1345. begin
  1346. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.localst);
  1347. { Write nested procedures -- disabled, see scope check at the
  1348. beginning; currently, these are still written in the global
  1349. scope. }
  1350. // write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.localst);
  1351. end;
  1352. finish_children;
  1353. *)
  1354. def.dbg_state:=dbg_state_written;
  1355. end;
  1356. procedure TDebugInfoLLVM.adddefinitionlocal(dinode: tai_llvmspecialisedmetadatanode; definition, local, usedispflags: boolean; out dispFlags: tsymstr);
  1357. begin
  1358. dispflags:='';
  1359. if not usedispflags then
  1360. begin
  1361. dinode.addboolean('isDefinition',definition);
  1362. if definition then
  1363. begin
  1364. dinode.addboolean('isLocal',local);
  1365. end;
  1366. exit;
  1367. end;
  1368. if definition then
  1369. begin
  1370. dispflags:='DISPFlagDefinition';
  1371. if local then
  1372. dispflags:=dispflags+'|DISPFlagLocalToUnit';
  1373. end;
  1374. end;
  1375. function TDebugInfoLLVM.get_symlist_sym_offset(symlist: ppropaccesslistitem; out sym: tabstractvarsym; out offset: pint): boolean;
  1376. (*
  1377. var
  1378. elesize : pint;
  1379. currdef : tdef;
  1380. indirection: boolean;
  1381. *)
  1382. begin
  1383. result:=false;
  1384. (*
  1385. if not assigned(symlist) then
  1386. exit;
  1387. sym:=nil;
  1388. offset:=0;
  1389. currdef:=nil;
  1390. indirection:=false;
  1391. repeat
  1392. case symlist^.sltype of
  1393. sl_load:
  1394. begin
  1395. if assigned(sym) then
  1396. internalerror(2009031203);
  1397. if not(symlist^.sym.typ in [paravarsym,localvarsym,staticvarsym,fieldvarsym]) then
  1398. { can't handle... }
  1399. exit;
  1400. sym:=tabstractvarsym(symlist^.sym);
  1401. currdef:=tabstractvarsym(sym).vardef;
  1402. if ((sym.typ=paravarsym) and
  1403. paramanager.push_addr_param(tparavarsym(sym).varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption)) then
  1404. indirection:=true;
  1405. end;
  1406. sl_subscript:
  1407. begin
  1408. if not assigned(currdef) then
  1409. internalerror(2009031301);
  1410. if (symlist^.sym.typ<>fieldvarsym) then
  1411. internalerror(2009031202);
  1412. { can't handle offsets with indirections yet }
  1413. if indirection then
  1414. exit;
  1415. if is_packed_record_or_object(currdef) then
  1416. begin
  1417. { can't calculate the address of a non-byte aligned field }
  1418. if (tfieldvarsym(symlist^.sym).fieldoffset mod 8) <> 0 then
  1419. exit;
  1420. inc(offset,tfieldvarsym(symlist^.sym).fieldoffset div 8)
  1421. end
  1422. else
  1423. inc(offset,tfieldvarsym(symlist^.sym).fieldoffset);
  1424. currdef:=tfieldvarsym(symlist^.sym).vardef;
  1425. end;
  1426. sl_absolutetype,
  1427. sl_typeconv:
  1428. begin
  1429. currdef:=symlist^.def;
  1430. { ignore, these don't change the address }
  1431. end;
  1432. sl_vec:
  1433. begin
  1434. if not assigned(currdef) or
  1435. (currdef.typ<>arraydef) then
  1436. internalerror(2009031201);
  1437. { can't handle offsets with indirections yet }
  1438. if indirection then
  1439. exit;
  1440. if not is_packed_array(currdef) then
  1441. elesize:=tarraydef(currdef).elesize
  1442. else
  1443. begin
  1444. elesize:=tarraydef(currdef).elepackedbitsize;
  1445. { can't calculate the address of a non-byte aligned element }
  1446. if (elesize mod 8)<>0 then
  1447. exit;
  1448. elesize:=elesize div 8;
  1449. end;
  1450. inc(offset,(symlist^.value.svalue-tarraydef(currdef).lowrange)*elesize);
  1451. currdef:=tarraydef(currdef).elementdef;
  1452. end;
  1453. else
  1454. internalerror(2009031403);
  1455. end;
  1456. symlist:=symlist^.next;
  1457. until not assigned(symlist);
  1458. if not assigned(sym) then
  1459. internalerror(2009031205);
  1460. result:=true;
  1461. *)
  1462. end;
  1463. procedure TDebugInfoLLVM.appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  1464. begin
  1465. // appendsym_var_with_name_type_offset(list,sym,symname(sym, false),sym.vardef,0,[]);
  1466. end;
  1467. procedure TDebugInfoLLVM.appendsym_var_with_name_type_offset(list:TAsmList; sym:tabstractnormalvarsym; const name: TSymStr; def: tdef; offset: pint(*; const flags: tdwarfvarsymflags*));
  1468. (*
  1469. var
  1470. templist : TAsmList;
  1471. blocksize,size_of_int : longint;
  1472. tag : tdwarf_tag;
  1473. has_high_reg : boolean;
  1474. dreg,dreghigh : shortint;
  1475. {$ifdef i8086}
  1476. has_segment_sym_name : boolean=false;
  1477. segment_sym_name : TSymStr='';
  1478. segment_reg: TRegister=NR_NO;
  1479. {$endif i8086}
  1480. *)
  1481. begin
  1482. (*
  1483. if vo_is_external in sym.varoptions then
  1484. exit;
  1485. blocksize:=0;
  1486. dreghigh:=0;
  1487. { There is no space allocated for not referenced locals }
  1488. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  1489. exit;
  1490. templist:=TAsmList.create;
  1491. case sym.localloc.loc of
  1492. LOC_REGISTER,
  1493. LOC_CREGISTER,
  1494. LOC_MMREGISTER,
  1495. LOC_CMMREGISTER,
  1496. LOC_FPUREGISTER,
  1497. LOC_CFPUREGISTER :
  1498. begin
  1499. { dwarf_reg_no_error might return -1
  1500. in case the register variable has been optimized out }
  1501. dreg:=dwarf_reg_no_error(sym.localloc.register);
  1502. has_high_reg:=(sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER]) and (sym.localloc.registerhi<>NR_NO);
  1503. if has_high_reg then
  1504. dreghigh:=dwarf_reg_no_error(sym.localloc.registerhi);
  1505. if dreghigh=-1 then
  1506. has_high_reg:=false;
  1507. if (sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER]) and
  1508. (sym.typ=paravarsym) and
  1509. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1510. not(vo_has_local_copy in sym.varoptions) and
  1511. not is_open_string(sym.vardef) and (dreg>=0) then
  1512. begin
  1513. templist.concat(tai_const.create_8bit(ord(DW_OP_bregx)));
  1514. templist.concat(tai_const.create_uleb128bit(dreg));
  1515. templist.concat(tai_const.create_sleb128bit(0));
  1516. blocksize:=1+Lengthuleb128(dreg)+LengthSleb128(0);
  1517. end
  1518. else
  1519. begin
  1520. if has_high_reg then
  1521. begin
  1522. templist.concat(tai_comment.create(strpnew('high:low reg pair variable')));
  1523. size_of_int:=sizeof(aint);
  1524. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1525. templist.concat(tai_const.create_uleb128bit(dreg));
  1526. blocksize:=1+Lengthuleb128(dreg);
  1527. templist.concat(tai_const.create_8bit(ord(DW_OP_piece)));
  1528. templist.concat(tai_const.create_uleb128bit(size_of_int));
  1529. blocksize:=blocksize+1+Lengthuleb128(size_of_int);
  1530. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1531. templist.concat(tai_const.create_uleb128bit(dreghigh));
  1532. blocksize:=blocksize+1+Lengthuleb128(dreghigh);
  1533. templist.concat(tai_const.create_8bit(ord(DW_OP_piece)));
  1534. templist.concat(tai_const.create_uleb128bit(size_of_int));
  1535. blocksize:=blocksize+1+Lengthuleb128(size_of_int);
  1536. end
  1537. else if (dreg>=0) then
  1538. begin
  1539. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1540. templist.concat(tai_const.create_uleb128bit(dreg));
  1541. blocksize:=1+Lengthuleb128(dreg);
  1542. end;
  1543. end;
  1544. end;
  1545. else
  1546. begin
  1547. case sym.typ of
  1548. staticvarsym:
  1549. begin
  1550. if vo_is_thread_var in sym.varoptions then
  1551. begin
  1552. if tf_section_threadvars in target_info.flags then
  1553. begin
  1554. case sizeof(puint) of
  1555. 2:
  1556. templist.concat(tai_const.create_8bit(ord(DW_OP_const2u)));
  1557. 4:
  1558. templist.concat(tai_const.create_8bit(ord(DW_OP_const4u)));
  1559. 8:
  1560. templist.concat(tai_const.create_8bit(ord(DW_OP_const8u)));
  1561. else
  1562. Internalerror(2019100501);
  1563. end;
  1564. {$push}
  1565. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  1566. templist.concat(tai_const.Create_type_name(aitconst_dtpoff,sym.mangledname,0));
  1567. { so far, aitconst_dtpoff is solely 32 bit }
  1568. if (sizeof(puint)=8) and (target_info.endian=endian_little) then
  1569. templist.concat(tai_const.create_32bit(0));
  1570. templist.concat(tai_const.create_8bit(ord(DW_OP_GNU_push_tls_address)));
  1571. if (sizeof(puint)=8) and (target_info.endian=endian_big) then
  1572. templist.concat(tai_const.create_32bit(0));
  1573. {$pop}
  1574. blocksize:=2+sizeof(puint);
  1575. end
  1576. else
  1577. begin
  1578. { TODO: !!! FIXME: dwarf for thread vars !!!}
  1579. { This is only a minimal change to at least be able to get a value
  1580. in only one thread is present PM 2014-11-21, like for stabs format }
  1581. templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
  1582. templist.concat(tai_const.Create_type_name(aitconst_ptr_unaligned,sym.mangledname,
  1583. offset+sizeof(pint)));
  1584. blocksize:=1+sizeof(puint);
  1585. end;
  1586. end
  1587. else
  1588. begin
  1589. templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
  1590. templist.concat(tai_const.Create_type_name(aitconst_ptr_unaligned,sym.mangledname,offset));
  1591. blocksize:=1+sizeof(puint);
  1592. {$ifdef i8086}
  1593. segment_sym_name:=sym.mangledname;
  1594. has_segment_sym_name:=true;
  1595. {$endif i8086}
  1596. end;
  1597. end;
  1598. paravarsym,
  1599. localvarsym:
  1600. begin
  1601. { Happens when writing debug info for paras of procdefs not
  1602. implemented in the current module. Can't add a general check
  1603. for LOC_INVALID above, because staticvarsyms may also have it.
  1604. }
  1605. if sym.localloc.loc<> LOC_INVALID then
  1606. begin
  1607. if is_fbreg(sym.localloc.reference.base) then
  1608. begin
  1609. templist.concat(tai_const.create_8bit(ord(DW_OP_fbreg)));
  1610. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset+offset));
  1611. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset+offset);
  1612. end
  1613. else
  1614. begin
  1615. dreg:=dwarf_reg(sym.localloc.reference.base);
  1616. if dreg<=31 then
  1617. begin
  1618. templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+dreg));
  1619. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset+offset));
  1620. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset+offset);
  1621. end
  1622. else
  1623. begin
  1624. templist.concat(tai_const.create_8bit(ord(DW_OP_bregx)));
  1625. templist.concat(tai_const.create_uleb128bit(dreg));
  1626. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset+offset));
  1627. blocksize:=1+Lengthuleb128(dreg)+LengthSleb128(sym.localloc.reference.offset+offset);
  1628. end;
  1629. end;
  1630. {$ifdef i8086}
  1631. segment_reg:=sym.localloc.reference.segment;
  1632. {$endif i8086}
  1633. {$ifndef gdb_supports_DW_AT_variable_parameter}
  1634. { Parameters which are passed by reference. (var and the like)
  1635. Hide the reference-pointer and dereference the pointer
  1636. in the DW_AT_location block.
  1637. }
  1638. if (sym.typ=paravarsym) and
  1639. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1640. not(vo_has_local_copy in sym.varoptions) and
  1641. not is_open_string(sym.vardef) then
  1642. begin
  1643. templist.concat(tai_const.create_8bit(ord(DW_OP_deref)));
  1644. inc(blocksize);
  1645. end
  1646. {$endif not gdb_supports_DW_AT_variable_parameter}
  1647. end;
  1648. end
  1649. else
  1650. internalerror(200601288);
  1651. end;
  1652. end;
  1653. end;
  1654. { function results must not be added to the parameter list,
  1655. as they are not part of the signature of the function
  1656. (gdb automatically adds them according to the ABI specifications
  1657. when calling the function)
  1658. }
  1659. if (sym.typ=paravarsym) and
  1660. not(dvf_force_local_var in flags) and
  1661. not(vo_is_funcret in sym.varoptions) then
  1662. tag:=DW_TAG_formal_parameter
  1663. else
  1664. tag:=DW_TAG_variable;
  1665. { must be parasym of externally implemented procdef, but
  1666. the parasymtable can con also contain e.g. absolutevarsyms
  1667. -> check symtabletype}
  1668. if (sym.owner.symtabletype=parasymtable) and
  1669. (sym.localloc.loc=LOC_INVALID) then
  1670. begin
  1671. if (sym.owner.symtabletype<>parasymtable) then
  1672. internalerror(2009101001);
  1673. append_entry(tag,false,[
  1674. DW_AT_name,DW_FORM_string,name+#0
  1675. {
  1676. DW_AT_decl_file,DW_FORM_data1,0,
  1677. DW_AT_decl_line,DW_FORM_data1,
  1678. }
  1679. ])
  1680. end
  1681. else if not(sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_MMREGISTER,
  1682. LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
  1683. ((sym.owner.symtabletype = globalsymtable) or
  1684. (sp_static in sym.symoptions) or
  1685. (vo_is_public in sym.varoptions)) then
  1686. append_entry(tag,false,[
  1687. DW_AT_name,DW_FORM_string,name+#0,
  1688. {
  1689. DW_AT_decl_file,DW_FORM_data1,0,
  1690. DW_AT_decl_line,DW_FORM_data1,
  1691. }
  1692. DW_AT_external,DW_FORM_flag,true,
  1693. { data continues below }
  1694. DW_AT_location,DW_FORM_block1,blocksize
  1695. ])
  1696. {$ifdef gdb_supports_DW_AT_variable_parameter}
  1697. else if (sym.typ=paravarsym) and
  1698. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1699. not(vo_has_local_copy in sym.varoptions) and
  1700. not is_open_string(sym.vardef) then
  1701. append_entry(tag,false,[
  1702. DW_AT_name,DW_FORM_string,name+#0,
  1703. DW_AT_variable_parameter,DW_FORM_flag,true,
  1704. {
  1705. DW_AT_decl_file,DW_FORM_data1,0,
  1706. DW_AT_decl_line,DW_FORM_data1,
  1707. }
  1708. { data continues below }
  1709. DW_AT_location,DW_FORM_block1,blocksize
  1710. ])
  1711. {$endif gdb_supports_DW_AT_variable_parameter}
  1712. else
  1713. append_entry(tag,false,[
  1714. DW_AT_name,DW_FORM_string,name+#0,
  1715. {
  1716. DW_AT_decl_file,DW_FORM_data1,0,
  1717. DW_AT_decl_line,DW_FORM_data1,
  1718. }
  1719. { data continues below }
  1720. DW_AT_location,DW_FORM_block1,blocksize
  1721. ]);
  1722. { append block data }
  1723. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  1724. { Mark self as artificial for methods, because gdb uses the fact
  1725. whether or not the first parameter of a method is artificial to
  1726. distinguish regular from static methods (since there are no
  1727. no vo_is_self parameters for static methods, we don't have to check
  1728. that). }
  1729. if (vo_is_self in sym.varoptions) then
  1730. append_attribute(DW_AT_artificial,DW_FORM_flag,[true]);
  1731. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def));
  1732. {$ifdef i8086}
  1733. if has_segment_sym_name then
  1734. append_seg_name(segment_sym_name)
  1735. else if segment_reg<>NR_NO then
  1736. append_seg_reg(segment_reg);
  1737. {$endif i8086}
  1738. templist.free;
  1739. finish_entry;
  1740. *)
  1741. end;
  1742. procedure TDebugInfoLLVM.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
  1743. var
  1744. decl: taillvmdecl;
  1745. globalvarexpression, globalvar: tai_llvmspecialisedmetadatanode;
  1746. dispflags: tsymstr;
  1747. islocal: boolean;
  1748. begin
  1749. decl:=staticvarsym_get_decl(sym);
  1750. if not assigned(decl) then
  1751. begin
  1752. list.concat(tai_comment.create(strpnew('no declaration found for '+sym.mangledname)));
  1753. exit;
  1754. end;
  1755. globalvar:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIGlobalVariable);
  1756. list.concat(globalvar);
  1757. globalvarexpression:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIGlobalVariableExpression);
  1758. globalvarexpression.addmetadatarefto('var',globalvar);
  1759. globalvarexpression.addmetadatarefto('expr',femptyexpression);
  1760. list.concat(globalvarexpression);
  1761. fglobals.addvalue(llvm_getmetadatareftypedconst(globalvarexpression));
  1762. decl.addinsmetadata(tai_llvmmetadatareferenceoperand.createreferenceto('dbg',globalvarexpression));
  1763. globalvar.addstring('name',symname(sym,false));
  1764. if not assigned(sym.owner.defowner) then
  1765. globalvar.addmetadatarefto('scope',fcunode)
  1766. else
  1767. globalvar.addmetadatarefto('scope',def_meta_node(tdef(sym.owner.defowner)));
  1768. try_add_file_metaref(globalvar,sym.fileinfo,false);
  1769. globalvar.addmetadatarefto('type',def_meta_node(sym.vardef));
  1770. islocal:=not(
  1771. ((sym.owner.symtabletype = globalsymtable) or
  1772. (sp_static in sym.symoptions) or
  1773. (vo_is_public in sym.varoptions))
  1774. );
  1775. adddefinitionlocal(globalvar,not(vo_is_external in sym.varoptions),islocal,false,dispflags);
  1776. if dispflags<>'' then
  1777. globalvar.addenum('spFlags',dispflags);
  1778. end;
  1779. procedure TDebugInfoLLVM.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
  1780. begin
  1781. // appendsym_var(list,sym);
  1782. end;
  1783. procedure TDebugInfoLLVM.appendsym_paravar(list:TAsmList;sym:tparavarsym);
  1784. begin
  1785. // appendsym_var(list,sym);
  1786. end;
  1787. procedure TDebugInfoLLVM.appendsym_fieldvar(list:TAsmList;sym: tfieldvarsym);
  1788. begin
  1789. appendsym_fieldvar_with_name_offset(list,sym,symname(sym, false),sym.vardef,0);
  1790. end;
  1791. procedure TDebugInfoLLVM.appendsym_fieldvar_with_name_offset(list:TAsmList;sym: tfieldvarsym;const name: string; def: tdef; offset: pint);
  1792. var
  1793. bitoffset,
  1794. fieldoffset,
  1795. fieldnatsize: asizeint;
  1796. begin
  1797. (*
  1798. if (sp_static in sym.symoptions) or
  1799. (sym.visibility=vis_hidden) then
  1800. exit;
  1801. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) or
  1802. { only ordinals are bitpacked }
  1803. not is_ordinal(sym.vardef) then
  1804. begin
  1805. { other kinds of fields can however also appear in a bitpacked }
  1806. { record, and then their offset is also specified in bits rather }
  1807. { than in bytes }
  1808. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) then
  1809. fieldoffset:=sym.fieldoffset
  1810. else
  1811. fieldoffset:=sym.fieldoffset div 8;
  1812. inc(fieldoffset,offset);
  1813. append_entry(DW_TAG_member,false,[
  1814. DW_AT_name,DW_FORM_string,name+#0,
  1815. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  1816. ]);
  1817. end
  1818. else
  1819. begin
  1820. if (sym.vardef.packedbitsize > 255) then
  1821. internalerror(2007061201);
  1822. { we don't bitpack according to the ABI, but as close as }
  1823. { possible, i.e., equivalent to gcc's }
  1824. { __attribute__((__packed__)), which is also what gpc }
  1825. { does. }
  1826. fieldnatsize:=max(sizeof(pint),sym.vardef.size);
  1827. fieldoffset:=(sym.fieldoffset div (fieldnatsize*8)) * fieldnatsize;
  1828. inc(fieldoffset,offset);
  1829. bitoffset:=sym.fieldoffset mod (fieldnatsize*8);
  1830. if (target_info.endian=endian_little) then
  1831. bitoffset:=(fieldnatsize*8)-bitoffset-sym.vardef.packedbitsize;
  1832. append_entry(DW_TAG_member,false,[
  1833. DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
  1834. { gcc also generates both a bit and byte size attribute }
  1835. { we don't support ordinals >= 256 bits }
  1836. DW_AT_byte_size,DW_FORM_data1,fieldnatsize,
  1837. { nor >= 256 bits (not yet, anyway, see IE above) }
  1838. DW_AT_bit_size,DW_FORM_data1,sym.vardef.packedbitsize,
  1839. { data1 and data2 are unsigned, bitoffset can also be negative }
  1840. DW_AT_bit_offset,DW_FORM_data4,bitoffset,
  1841. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  1842. ]);
  1843. end;
  1844. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1845. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(fieldoffset));
  1846. if (sym.owner.symtabletype in [objectsymtable,recordsymtable]) then
  1847. append_visibility(sym.visibility);
  1848. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def));
  1849. finish_entry;
  1850. *)
  1851. end;
  1852. procedure TDebugInfoLLVM.appendsym_const(list:TAsmList;sym:tconstsym);
  1853. begin
  1854. appendsym_const_member(list,sym,false);
  1855. end;
  1856. procedure TDebugInfoLLVM.appendsym_const_member(list:TAsmList;sym:tconstsym;ismember:boolean);
  1857. var
  1858. i,
  1859. size: aint;
  1860. usedef: tdef;
  1861. begin
  1862. (*
  1863. { These are default values of parameters. These should be encoded
  1864. via DW_AT_default_value, not as a separate sym. Moreover, their
  1865. type is not available when writing the debug info for external
  1866. procedures.
  1867. }
  1868. if (sym.owner.symtabletype=parasymtable) then
  1869. exit;
  1870. if ismember then
  1871. append_entry(DW_TAG_member,false,[
  1872. DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
  1873. { The DW_AT_declaration tag is invalid according to the DWARF specifications.
  1874. But gcc adds this to static const members and gdb checks
  1875. for this flag. So we have to set it also.
  1876. }
  1877. DW_AT_declaration,DW_FORM_flag,true,
  1878. DW_AT_external,DW_FORM_flag,true
  1879. ])
  1880. else
  1881. append_entry(DW_TAG_variable,false,[
  1882. DW_AT_name,DW_FORM_string,symname(sym, false)+#0
  1883. ]);
  1884. { for string constants, constdef isn't set because they have no real type }
  1885. case sym.consttyp of
  1886. conststring:
  1887. begin
  1888. { if DW_FORM_string is used below one day, this usedef should
  1889. probably become nil }
  1890. { note: < 255 instead of <= 255 because we have to store the
  1891. entire length of the string as well, and 256 does not fit in
  1892. a byte }
  1893. if (sym.value.len<255) then
  1894. usedef:=cshortstringtype
  1895. else
  1896. usedef:=clongstringtype;
  1897. end;
  1898. constresourcestring,
  1899. constwstring:
  1900. usedef:=nil;
  1901. else
  1902. usedef:=sym.constdef;
  1903. end;
  1904. if assigned(usedef) then
  1905. append_labelentry_ref(DW_AT_type,def_dwarf_lab(usedef));
  1906. AddConstToAbbrev(ord(DW_AT_const_value));
  1907. case sym.consttyp of
  1908. conststring:
  1909. begin
  1910. { DW_FORM_string isn't supported yet by the Pascal value printer
  1911. -> create a string using raw bytes }
  1912. if (sym.value.len<255) then
  1913. begin
  1914. AddConstToAbbrev(ord(DW_FORM_block1));
  1915. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sym.value.len+1));
  1916. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sym.value.len));
  1917. end
  1918. else
  1919. begin
  1920. AddConstToAbbrev(ord(DW_FORM_block));
  1921. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sym.value.len+sizesinttype.size));
  1922. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.Create_sizeint_unaligned(sym.value.len));
  1923. end;
  1924. i:=0;
  1925. size:=sym.value.len;
  1926. while(i<size) do
  1927. begin
  1928. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit((pbyte(sym.value.valueptr+i)^)));
  1929. inc(i);
  1930. end;
  1931. end;
  1932. constguid,
  1933. constset:
  1934. begin
  1935. AddConstToAbbrev(ord(DW_FORM_block1));
  1936. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(usedef.size));
  1937. i:=0;
  1938. size:=sym.constdef.size;
  1939. while (i<size) do
  1940. begin
  1941. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit((pbyte(sym.value.valueptr+i)^)));
  1942. inc(i);
  1943. end;
  1944. end;
  1945. constwstring,
  1946. constresourcestring:
  1947. begin
  1948. { write dummy for now }
  1949. AddConstToAbbrev(ord(DW_FORM_string));
  1950. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(''));
  1951. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  1952. end;
  1953. constord:
  1954. begin
  1955. if (sym.value.valueord<0) then
  1956. begin
  1957. AddConstToAbbrev(ord(DW_FORM_sdata));
  1958. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(sym.value.valueord.svalue));
  1959. end
  1960. else
  1961. begin
  1962. AddConstToAbbrev(ord(DW_FORM_udata));
  1963. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sym.value.valueord.uvalue));
  1964. end;
  1965. end;
  1966. constnil:
  1967. begin
  1968. {$ifdef cpu64bitaddr}
  1969. AddConstToAbbrev(ord(DW_FORM_data8));
  1970. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit_unaligned(0));
  1971. {$else cpu64bitaddr}
  1972. AddConstToAbbrev(ord(DW_FORM_data4));
  1973. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit_unaligned(0));
  1974. {$endif cpu64bitaddr}
  1975. end;
  1976. constpointer:
  1977. begin
  1978. {$ifdef cpu64bitaddr}
  1979. AddConstToAbbrev(ord(DW_FORM_data8));
  1980. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit_unaligned(int64(sym.value.valueordptr)));
  1981. {$else cpu64bitaddr}
  1982. AddConstToAbbrev(ord(DW_FORM_data4));
  1983. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit_unaligned(longint(sym.value.valueordptr)));
  1984. {$endif cpu64bitaddr}
  1985. end;
  1986. constreal:
  1987. begin
  1988. AddConstToAbbrev(ord(DW_FORM_block1));
  1989. case tfloatdef(sym.constdef).floattype of
  1990. s32real:
  1991. begin
  1992. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(4));
  1993. current_asmdata.asmlists[al_dwarf_info].concat(tai_realconst.create_s32real(pbestreal(sym.value.valueptr)^));
  1994. end;
  1995. s64real:
  1996. begin
  1997. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  1998. current_asmdata.asmlists[al_dwarf_info].concat(tai_realconst.create_s64real(pbestreal(sym.value.valueptr)^));
  1999. end;
  2000. s64comp,
  2001. s64currency:
  2002. begin
  2003. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  2004. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit_unaligned(trunc(pbestreal(sym.value.valueptr)^)));
  2005. end;
  2006. s80real,
  2007. sc80real:
  2008. begin
  2009. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sym.constdef.size));
  2010. current_asmdata.asmlists[al_dwarf_info].concat(tai_realconst.create_s80real(pextended(sym.value.valueptr)^,sym.constdef.size));
  2011. end;
  2012. else
  2013. internalerror(200601291);
  2014. end;
  2015. end;
  2016. else
  2017. internalerror(200601292);
  2018. end;
  2019. finish_entry;
  2020. *)
  2021. end;
  2022. procedure TDebugInfoLLVM.appendsym_label(list:TAsmList;sym: tlabelsym);
  2023. begin
  2024. { ignore label syms for now, the problem is that a label sym
  2025. can have more than one label associated e.g. in case of
  2026. an inline procedure expansion }
  2027. end;
  2028. procedure TDebugInfoLLVM.appendsym_property(list:TAsmList;sym: tpropertysym);
  2029. var
  2030. symlist: ppropaccesslistitem;
  2031. tosym: tabstractvarsym;
  2032. offset: pint;
  2033. begin
  2034. (*
  2035. if assigned(sym.propaccesslist[palt_read]) and
  2036. not assigned(sym.propaccesslist[palt_read].procdef) then
  2037. symlist:=sym.propaccesslist[palt_read].firstsym
  2038. else
  2039. { can't handle }
  2040. exit;
  2041. if not get_symlist_sym_offset(symlist,tosym,offset) then
  2042. exit;
  2043. if not (tosym.owner.symtabletype in [objectsymtable,recordsymtable]) then
  2044. begin
  2045. if (tosym.typ=fieldvarsym) then
  2046. internalerror(2009031404);
  2047. appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym, false),sym.propdef,offset,[])
  2048. end
  2049. else
  2050. appendsym_fieldvar_with_name_offset(list,tfieldvarsym(tosym),symname(sym, false),sym.propdef,offset)
  2051. *)
  2052. end;
  2053. function TDebugInfoLLVM.symdebugname(sym: tsym): TSymStr;
  2054. begin
  2055. if ds_dwarf_cpp in current_settings.debugswitches then
  2056. begin
  2057. result:=sym.RealName;
  2058. if (result<>'') and
  2059. (result[1]='$') then
  2060. delete(result,1,1);
  2061. end
  2062. else
  2063. result:=sym.name
  2064. end;
  2065. procedure TDebugInfoLLVM.appendsym_type(list:TAsmList;sym: ttypesym);
  2066. begin
  2067. { just queue the def if needed, beforeappenddef will
  2068. emit the typedef if necessary }
  2069. get_def_metatai(sym.typedef);
  2070. {
  2071. if FindUnitSymtable(sym.Owner).iscurrentunit then
  2072. fretainedtypes.addvalue(def_meta_ref(sym.typedef));
  2073. }
  2074. end;
  2075. procedure TDebugInfoLLVM.appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);
  2076. (*
  2077. var
  2078. templist : TAsmList;
  2079. blocksize : longint;
  2080. symlist : ppropaccesslistitem;
  2081. tosym: tabstractvarsym;
  2082. offset: pint;
  2083. flags: tdwarfvarsymflags;
  2084. *)
  2085. begin
  2086. (*
  2087. templist:=TAsmList.create;
  2088. case tabsolutevarsym(sym).abstyp of
  2089. toaddr :
  2090. begin
  2091. { MWE: replaced ifdef i368 }
  2092. {
  2093. if target_cpu = cpu_i386 then
  2094. begin
  2095. { in theory, we could write a DW_AT_segment entry here for sym.absseg,
  2096. however I doubt that gdb supports this (FK) }
  2097. end;
  2098. }
  2099. templist.concat(tai_const.create_8bit(3));
  2100. {$ifdef avr}
  2101. // Add $800000 to indicate that the address is in memory space
  2102. templist.concat(tai_const.create_int_dataptr_unaligned(sym.addroffset + $800000, aitconst_ptr_unaligned));
  2103. {$else}
  2104. templist.concat(tai_const.create_int_dataptr_unaligned(sym.addroffset));
  2105. {$endif}
  2106. blocksize:=1+sizeof(puint);
  2107. end;
  2108. toasm :
  2109. begin
  2110. templist.concat(tai_const.create_8bit(3));
  2111. templist.concat(tai_const.create_type_name(aitconst_ptr_unaligned,sym.mangledname,0));
  2112. blocksize:=1+sizeof(puint);
  2113. end;
  2114. tovar:
  2115. begin
  2116. symlist:=tabsolutevarsym(sym).ref.firstsym;
  2117. if get_symlist_sym_offset(symlist,tosym,offset) then
  2118. begin
  2119. if (tosym.typ=fieldvarsym) then
  2120. internalerror(2009031402);
  2121. flags:=[];
  2122. if (sym.owner.symtabletype=localsymtable) then
  2123. include(flags,dvf_force_local_var);
  2124. appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym, false),tabstractvarsym(sym).vardef,offset,flags);
  2125. end;
  2126. templist.free;
  2127. exit;
  2128. end;
  2129. end;
  2130. append_entry(DW_TAG_variable,false,[
  2131. DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
  2132. {
  2133. DW_AT_decl_file,DW_FORM_data1,0,
  2134. DW_AT_decl_line,DW_FORM_data1,
  2135. }
  2136. DW_AT_external,DW_FORM_flag,true,
  2137. { data continues below }
  2138. DW_AT_location,DW_FORM_block1,blocksize
  2139. ]);
  2140. { append block data }
  2141. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  2142. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  2143. templist.free;
  2144. finish_entry;
  2145. *)
  2146. end;
  2147. procedure TDebugInfoLLVM.beforeappendsym(list:TAsmList;sym:tsym);
  2148. begin
  2149. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Symbol '+symname(sym, true))));
  2150. end;
  2151. procedure TDebugInfoLLVM.insertmoduleinfo;
  2152. var
  2153. culist: tai_llvmnamedmetadatanode;
  2154. dwarfversionflag: tai_llvmbasemetadatanode;
  2155. lang: tdwarf_source_language;
  2156. objcruntimeversion: longint;
  2157. begin
  2158. ensuremetainit;
  2159. if (ds_dwarf_cpp in current_settings.debugswitches) then
  2160. lang:=DW_LANG_C_plus_plus
  2161. else
  2162. lang:=DW_LANG_Pascal83;
  2163. { debug info header }
  2164. fcunode.addint64('language',ord(lang));
  2165. fcunode.addmetadatarefto('file',file_getmetanode(current_filepos.moduleindex,current_filepos.fileindex));
  2166. fcunode.addstring('producer','Free Pascal Compiler '+full_version_string);
  2167. fcunode.addboolean('isOptimized',cs_opt_level2 in current_settings.optimizerswitches);
  2168. if target_info.system in systems_objc_supported then
  2169. begin
  2170. if ([m_objectivec1,m_objectivec2]*current_settings.modeswitches)<>[] then
  2171. if target_info.system in systems_objc_nfabi then
  2172. objcruntimeversion:=2
  2173. else
  2174. objcruntimeversion:=1
  2175. else
  2176. objcruntimeversion:=0;
  2177. fcunode.addint64('runtimeVersion',objcruntimeversion);
  2178. end;
  2179. if cs_debuginfo in current_settings.moduleswitches then
  2180. fcunode.addenum('emissionKind','FullDebug')
  2181. else
  2182. fcunode.addenum('emissionKind','LineTablesOnly');
  2183. if fenums.valuecount<>0 then
  2184. begin
  2185. fcunode.addmetadatarefto('enums',fenums);
  2186. current_asmdata.AsmLists[al_dwarf_info].Concat(fenums);
  2187. end
  2188. else
  2189. begin
  2190. fcunode.addmetadatarefto('enums',nil);
  2191. fenums.free;
  2192. end;
  2193. fenums:=nil;
  2194. if fretainedtypes.valuecount<>0 then
  2195. begin
  2196. fcunode.addmetadatarefto('retainedTypes',fretainedtypes);
  2197. current_asmdata.AsmLists[al_dwarf_info].Concat(fretainedtypes);
  2198. end
  2199. else
  2200. begin
  2201. fcunode.addmetadatarefto('retainedTypes',nil);
  2202. fretainedtypes.free;
  2203. end;
  2204. fretainedtypes:=nil;
  2205. if fglobals.valuecount<>0 then
  2206. begin
  2207. fcunode.addmetadatarefto('globals',fglobals);
  2208. current_asmdata.AsmLists[al_dwarf_info].Concat(fglobals);
  2209. end
  2210. else
  2211. begin
  2212. fcunode.addmetadatarefto('globals',nil);
  2213. fglobals.free;
  2214. end;
  2215. fglobals:=nil;
  2216. current_asmdata.AsmLists[al_dwarf_info].Concat(femptyexpression);
  2217. femptyexpression:=nil;
  2218. current_asmdata.AsmLists[al_dwarf_info].Concat(fderefexpression);
  2219. fderefexpression:=nil;
  2220. if target_info.system in systems_darwin then
  2221. fcunode.addenum('nameTableKind','GNU');
  2222. current_asmdata.AsmLists[al_dwarf_info].Concat(fcunode);
  2223. culist:=tai_llvmnamedmetadatanode.create('llvm.dbg.cu');
  2224. current_asmdata.AsmLists[al_dwarf_info].Concat(culist);
  2225. culist.addvalue(llvm_getmetadatareftypedconst(fcunode));
  2226. resetfornewmodule;
  2227. end;
  2228. procedure TDebugInfoLLVM.inserttypeinfo;
  2229. var
  2230. storefilepos : tfileposinfo;
  2231. i : longint;
  2232. (*
  2233. lenstartlabel,arangestartlabel: tasmlabel;
  2234. *)
  2235. def: tdef;
  2236. (*
  2237. dbgname: string;
  2238. *)
  2239. vardatatype: ttypesym;
  2240. begin
  2241. ensuremetainit;
  2242. storefilepos:=current_filepos;
  2243. current_filepos:=current_module.mainfilepos;
  2244. vardatatype:=try_search_system_type('TVARDATA');
  2245. if assigned(vardatatype) then
  2246. vardatadef:=trecorddef(vardatatype.typedef);
  2247. collectglobalsyms;
  2248. { write all global/local variables. This will flag all required tdefs }
  2249. if assigned(current_module.globalsymtable) then
  2250. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  2251. if assigned(current_module.localsymtable) then
  2252. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  2253. { write all procedures and methods. This will flag all required tdefs }
  2254. if assigned(current_module.globalsymtable) then
  2255. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  2256. if assigned(current_module.localsymtable) then
  2257. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  2258. { reset unit type info flag }
  2259. reset_unit_type_info;
  2260. { write used types from the used units }
  2261. write_used_unit_type_info(current_asmdata.asmlists[al_dwarf_info],current_module);
  2262. { last write the types from this unit }
  2263. if assigned(current_module.globalsymtable) then
  2264. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  2265. if assigned(current_module.localsymtable) then
  2266. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  2267. { write defs not written yet }
  2268. write_remaining_defs_to_write(current_asmdata.asmlists[al_dwarf_info]);
  2269. { reset all def debug states for LLVMTypeInfo (which also uses this
  2270. field, to track for which types type info has been inserted already }
  2271. for i:=0 to defnumberlist.count-1 do
  2272. begin
  2273. def := tdef(defnumberlist[i]);
  2274. if assigned(def) then
  2275. def.dbg_state:=dbg_state_unused;
  2276. end;
  2277. current_filepos:=storefilepos;
  2278. end;
  2279. function TDebugInfoLLVM.symname(sym: tsym; manglename: boolean): TSymStr;
  2280. begin
  2281. if (sym.typ=paravarsym) and
  2282. (vo_is_self in tparavarsym(sym).varoptions) then
  2283. { We use 'this' for regular methods because that's what gdb triggers
  2284. on to automatically search fields. Don't do this for class methods,
  2285. because search class fields is not supported, and gdb 7.0+ fails
  2286. in this case because "this" is not a record in that case (it's a
  2287. pointer to a vmt) }
  2288. if not is_objc_class_or_protocol(tdef(sym.owner.defowner.owner.defowner)) and
  2289. not(po_classmethod in tabstractprocdef(sym.owner.defowner).procoptions) then
  2290. result:='this'
  2291. else
  2292. result:='self'
  2293. else if (sym.typ=typesym) and
  2294. is_objc_class_or_protocol(ttypesym(sym).typedef) then
  2295. result:=tobjectdef(ttypesym(sym).typedef).objextname^
  2296. else if (ds_dwarf_method_class_prefix in current_settings.debugswitches) and
  2297. (sym.typ=procsym) and
  2298. (tprocsym(sym).owner.symtabletype in [objectsymtable,recordsymtable]) then
  2299. begin
  2300. result:=tprocsym(sym).owner.name^+'__';
  2301. if manglename then
  2302. result := result + sym.name
  2303. else
  2304. result := result + symdebugname(sym);
  2305. end
  2306. else
  2307. begin
  2308. if manglename then
  2309. result := sym.name
  2310. else
  2311. result := symdebugname(sym);
  2312. end;
  2313. end;
  2314. function TDebugInfoLLVM.visibilitydiflag(vis: tvisibility): TSymStr;
  2315. begin
  2316. case vis of
  2317. vis_hidden,
  2318. vis_private,
  2319. vis_strictprivate:
  2320. result:='DIFlagPrivate';
  2321. vis_protected,
  2322. vis_strictprotected:
  2323. result:='DIFlagProtected';
  2324. vis_published,
  2325. vis_public:
  2326. result:='DIFlagPublic';
  2327. vis_none:
  2328. internalerror(2022050101);
  2329. end;
  2330. end;
  2331. procedure TDebugInfoLLVM.insertlineinfo(list:TAsmList);
  2332. var
  2333. hp: tai;
  2334. functionscope,
  2335. positionmeta: tai_llvmspecialisedmetadatanode;
  2336. pd: tprocdef;
  2337. procdeffileinfo: tfileposinfo;
  2338. nolineinfolevel : longint;
  2339. firstline: boolean;
  2340. begin
  2341. ensuremetainit;
  2342. hp:=tai(list.first);
  2343. while assigned(hp) and
  2344. ((hp.typ<>ait_llvmdecl) or
  2345. (taillvmdecl(hp).def.typ<>procdef)) do
  2346. begin
  2347. hp:=tai(hp.next);
  2348. end;
  2349. if not assigned(hp) then
  2350. exit;
  2351. pd:=tprocdef(taillvmdecl(hp).def);
  2352. procdeffileinfo:=pd.fileinfo;
  2353. { might trigger for certain kinds of internally generated code }
  2354. if procdeffileinfo.fileindex=0 then
  2355. exit;
  2356. flocalvarsymmeta.free;
  2357. flocalvarsymmeta:=THashSet.Create((pd.localst.SymList.count+pd.parast.SymList.count)*4+1,true,false);
  2358. functionscope:=def_meta_node(pd);
  2359. nolineinfolevel:=0;
  2360. hp:=tai(hp.next);
  2361. firstline:=true;
  2362. while assigned(hp) do
  2363. begin
  2364. case hp.typ of
  2365. ait_marker:
  2366. begin
  2367. case tai_marker(hp).kind of
  2368. mark_NoLineInfoStart:
  2369. inc(nolineinfolevel);
  2370. mark_NoLineInfoEnd:
  2371. dec(nolineinfolevel);
  2372. else
  2373. ;
  2374. end;
  2375. end;
  2376. else
  2377. ;
  2378. end;
  2379. if (hp.typ=ait_llvmins) and
  2380. ((nolineinfolevel=0) or
  2381. (taillvm(hp).llvmopcode=la_call)) then
  2382. begin
  2383. positionmeta:=nil;
  2384. { valid file -> add info }
  2385. if (tailineinfo(hp).fileinfo.fileindex<>0) then
  2386. begin
  2387. if firstline and
  2388. (nolineinfolevel=0) then
  2389. begin
  2390. functionscope.addint64('scopeLine',tailineinfo(hp).fileinfo.line);
  2391. firstline:=false;
  2392. end;
  2393. positionmeta:=filepos_getmetanode(tailineinfo(hp).fileinfo,procdeffileinfo,functionscope,nolineinfolevel<>0);
  2394. end
  2395. { LLVM requires line info for call instructions that may
  2396. potentially be inlined }
  2397. else if taillvm(hp).llvmopcode=la_call then
  2398. begin
  2399. positionmeta:=filepos_getmetanode(tailineinfo(hp).fileinfo,procdeffileinfo,functionscope,true);
  2400. end;
  2401. if assigned(positionmeta) then
  2402. taillvm(hp).addinsmetadata(tai_llvmmetadatareferenceoperand.createreferenceto('dbg',positionmeta));
  2403. if (cs_debuginfo in current_settings.moduleswitches) and
  2404. (taillvm(hp).llvmopcode=la_call) then
  2405. updatelocalvardbginfo(taillvm(hp),pd,functionscope);
  2406. end;
  2407. hp:=tai(hp.next);
  2408. end;
  2409. end;
  2410. {****************************************************************************
  2411. ****************************************************************************}
  2412. const
  2413. dbg_llvm_info : tdbginfo =
  2414. (
  2415. id : dbg_llvm;
  2416. idtxt : 'LLVM';
  2417. );
  2418. initialization
  2419. RegisterDebugInfo(dbg_llvm_info,TDebugInfoLLVM);
  2420. end.