llvmdef.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. {
  2. Copyright (c) 2013 by Jonas Maebe
  3. This unit implements some LLVM type helper routines.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. {$i fpcdefs.inc}
  18. unit llvmdef;
  19. interface
  20. uses
  21. cclasses,globtype,
  22. parabase,
  23. symbase,symtype,symdef,
  24. llvmbase;
  25. type
  26. { there are three different circumstances in which procdefs are used:
  27. a) definition of a procdef that's implemented in the current module or
  28. declaration of an external routine that's called in the current one
  29. b) alias declaration of a procdef implemented in the current module
  30. c) defining a procvar type
  31. The main differences between the contexts are:
  32. a) information about sign extension of result type, proc name, parameter names & types
  33. b) no information about sign extension of result type, proc name, no parameter names, parameter types
  34. c) information about sign extension of result type, no proc name, no parameter names, parameter types
  35. }
  36. tllvmprocdefdecltype = (lpd_decl,lpd_alias,lpd_procvar);
  37. { Encode a type into the internal format used by LLVM. }
  38. function llvmencodetype(def: tdef): TSymStr;
  39. { incremental version of llvmencodetype(). "inaggregate" indicates whether
  40. this was a recursive call to get the type of an entity part of an
  41. aggregate type (array, record, ...) }
  42. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  43. { encode a procdef/procvardef into the internal format used by LLVM }
  44. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  45. { incremental version of the above }
  46. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  47. { function result types may have to be represented differently, e.g. a
  48. record consisting of 4 longints must be returned as a record consisting of
  49. two int64's on x86-64. This function is used to create (and reuse)
  50. temporary recorddefs for such purposes.}
  51. function llvmgettemprecorddef(fieldtypes: tfplist; packrecords: shortint): trecorddef;
  52. { get the llvm type corresponding to a parameter, e.g. a record containing
  53. two integer int64 for an arbitrary record split over two individual int64
  54. parameters, or an int32 for an int16 parameter on a platform that requires
  55. such parameters to be zero/sign extended. The second parameter can be used
  56. to get the type before zero/sign extension, as e.g. required to generate
  57. function declarations. }
  58. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean): tdef;
  59. { can be used to extract the value extension info from acgpara. Pass in
  60. the def of the cgpara as first parameter and a local variable holding
  61. a copy of the def of the location (value extension only makes sense for
  62. ordinal parameters that are smaller than a single location). The routine
  63. will return the def of the location without sign extension (if applicable)
  64. and the kind of sign extension that was originally performed in the
  65. signext parameter }
  66. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  67. { returns whether a paraloc should be translated into an llvm "byval"
  68. parameter. These are declared as pointers to a particular type, but
  69. usually turned into copies onto the stack. The exact behaviour for
  70. parameters that should be passed in registers is undefined and depends on
  71. the platform, and furthermore this modifier sometimes inhibits
  72. optimizations. As a result,we only use it for aggregate parameters of
  73. which we know that they should be passed on the stack }
  74. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  75. { returns whether a def is representated by an aggregate type in llvm
  76. (struct, array) }
  77. function llvmaggregatetype(def: tdef): boolean;
  78. implementation
  79. uses
  80. cutils,constexp,
  81. verbose,systems,
  82. fmodule,
  83. symtable,symconst,symsym,
  84. llvmsym,
  85. defutil,cgbase,paramgr;
  86. {******************************************************************
  87. Type encoding
  88. *******************************************************************}
  89. function llvmaggregatetype(def: tdef): boolean;
  90. begin
  91. result:=
  92. (def.typ in [recorddef,filedef,variantdef]) or
  93. ((def.typ=arraydef) and
  94. not is_dynamic_array(def)) or
  95. ((def.typ=setdef) and
  96. not is_smallset(def)) or
  97. is_shortstring(def) or
  98. is_object(def) or
  99. ((def.typ=procvardef) and
  100. not tprocvardef(def).is_addressonly)
  101. end;
  102. function llvmbyvalparaloc(paraloc: pcgparalocation): boolean;
  103. begin
  104. { "byval" is broken for register paras on several platforms in llvm
  105. (search for "byval" in llvm's bug tracker). Additionally, it should only
  106. be used to pass aggregate parameters on the stack, because it reportedly
  107. inhibits llvm's midlevel optimizers.
  108. Exception (for now?): parameters that have special shifting
  109. requirements, because modelling those in llvm is not easy (and clang
  110. nor llvm-gcc seem to do so either) }
  111. result:=
  112. ((paraloc^.loc=LOC_REFERENCE) and
  113. llvmaggregatetype(paraloc^.def)) or
  114. (paraloc^.shiftval<>0)
  115. end;
  116. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr); forward;
  117. procedure llvmaddencodedtype_intern(def: tdef; inaggregate, noimplicitderef: boolean; var encodedstr: TSymStr);
  118. begin
  119. case def.typ of
  120. stringdef :
  121. begin
  122. case tstringdef(def).stringtype of
  123. st_widestring,
  124. st_unicodestring:
  125. { the variable does not point to the header, but to a
  126. null-terminated string/array with undefined bounds }
  127. encodedstr:=encodedstr+'[0 x i16]';
  128. st_ansistring:
  129. encodedstr:=encodedstr+'[0 x i8]';
  130. st_shortstring:
  131. { length byte followed by string bytes }
  132. if tstringdef(def).len>0 then
  133. encodedstr:=encodedstr+'{i8, ['+tostr(tstringdef(def).len)+' x i8]}'
  134. else
  135. encodedstr:=encodedstr+'{i8, [0 x i8]}';
  136. else
  137. internalerror(2013100201);
  138. end;
  139. end;
  140. enumdef:
  141. begin
  142. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  143. end;
  144. orddef :
  145. begin
  146. if is_void(def) then
  147. encodedstr:=encodedstr+'void'
  148. { mainly required because comparison operations return i1, and
  149. otherwise we always have to immediatel extend them to i8 for
  150. no good reason; besides, Pascal booleans can only contain 0
  151. or 1 in valid code anyway (famous last words...) }
  152. else if torddef(def).ordtype=pasbool8 then
  153. encodedstr:=encodedstr+'i1'
  154. else
  155. encodedstr:=encodedstr+'i'+tostr(def.size*8);
  156. end;
  157. pointerdef :
  158. begin
  159. if is_voidpointer(def) then
  160. encodedstr:=encodedstr+'i8*'
  161. else
  162. begin
  163. llvmaddencodedtype_intern(tpointerdef(def).pointeddef,inaggregate,false,encodedstr);
  164. encodedstr:=encodedstr+'*';
  165. end;
  166. end;
  167. floatdef :
  168. begin
  169. case tfloatdef(def).floattype of
  170. s32real:
  171. encodedstr:=encodedstr+'float';
  172. s64real:
  173. encodedstr:=encodedstr+'double';
  174. { necessary to be able to force our own size/alignment }
  175. s80real:
  176. { prevent llvm from allocating the standard ABI size for
  177. extended }
  178. if inaggregate then
  179. encodedstr:=encodedstr+'[10 x i8]'
  180. else
  181. encodedstr:=encodedstr+'x86_fp80';
  182. sc80real:
  183. encodedstr:=encodedstr+'x86_fp80';
  184. s64comp,
  185. s64currency:
  186. encodedstr:=encodedstr+'i64';
  187. s128real:
  188. {$if defined(powerpc) or defined(powerpc128)}
  189. encodedstr:=encodedstr+'ppc_fp128';
  190. {$else}
  191. encodedstr:=encodedstr+'fp128';
  192. {$endif}
  193. else
  194. internalerror(2013100202);
  195. end;
  196. end;
  197. filedef :
  198. begin
  199. case tfiledef(def).filetyp of
  200. ft_text :
  201. llvmaddencodedtype_intern(search_system_type('TEXTREC').typedef,inaggregate,false,encodedstr);
  202. ft_typed,
  203. ft_untyped :
  204. llvmaddencodedtype_intern(search_system_type('FILEREC').typedef,inaggregate,false,encodedstr);
  205. else
  206. internalerror(2013100203);
  207. end;
  208. end;
  209. recorddef :
  210. begin
  211. llvmaddencodedabstractrecordtype(trecorddef(def),encodedstr);
  212. end;
  213. variantdef :
  214. begin
  215. llvmaddencodedtype_intern(search_system_type('TVARDATA').typedef,inaggregate,false,encodedstr);
  216. end;
  217. classrefdef :
  218. begin
  219. { todo: define proper type for VMT and use that }
  220. encodedstr:=encodedstr+'i8*';
  221. end;
  222. setdef :
  223. begin
  224. { just an array as far as llvm is concerned; don't use a "packed
  225. array of i1" or so, this requires special support in backends
  226. and guarantees nothing about the internal format }
  227. encodedstr:=encodedstr+'['+tostr(tsetdef(def).size)+' x i8]';
  228. end;
  229. formaldef :
  230. begin
  231. { var/const/out x }
  232. encodedstr:=encodedstr+'i8*';
  233. end;
  234. arraydef :
  235. begin
  236. if is_array_of_const(def) then
  237. begin
  238. encodedstr:=encodedstr+'[0 x ';
  239. llvmaddencodedtype_intern(search_system_type('TVARREC').typedef,true,false,encodedstr);
  240. encodedstr:=encodedstr+']';
  241. end
  242. else if is_open_array(def) then
  243. begin
  244. encodedstr:=encodedstr+'[0 x ';
  245. llvmaddencodedtype_intern(tarraydef(def).elementdef,true,false,encodedstr);
  246. encodedstr:=encodedstr+']';
  247. end
  248. else if is_dynamic_array(def) then
  249. begin
  250. llvmaddencodedtype_intern(tarraydef(def).elementdef,inaggregate,false,encodedstr);
  251. encodedstr:=encodedstr+'*';
  252. end
  253. else if is_packed_array(def) then
  254. begin
  255. encodedstr:=encodedstr+'['+tostr(tarraydef(def).size div tarraydef(def).elementdef.packedbitsize)+' x ';
  256. { encode as an array of integers with the size on which we
  257. perform the packedbits operations }
  258. llvmaddencodedtype_intern(cgsize_orddef(int_cgsize(packedbitsloadsize(tarraydef(def).elementdef.packedbitsize))),true,false,encodedstr);
  259. encodedstr:=encodedstr+']';
  260. end
  261. else
  262. begin
  263. encodedstr:=encodedstr+'['+tostr(tarraydef(def).elecount)+' x ';
  264. llvmaddencodedtype_intern(tarraydef(def).elementdef,true,false,encodedstr);
  265. encodedstr:=encodedstr+']';
  266. end;
  267. end;
  268. procvardef :
  269. begin
  270. if tprocvardef(def).is_addressonly then
  271. begin
  272. llvmaddencodedproctype(tprocdef(def),'',lpd_procvar,encodedstr);
  273. encodedstr:=encodedstr+'*';
  274. end
  275. else
  276. begin
  277. encodedstr:=encodedstr+'{';
  278. { code pointer }
  279. llvmaddencodedproctype(tprocvardef(def),'',lpd_procvar,encodedstr);
  280. { data pointer (maybe todo: generate actual layout if
  281. available) }
  282. encodedstr:=encodedstr+'*, i8*}';
  283. end;
  284. end;
  285. objectdef :
  286. case tobjectdef(def).objecttype of
  287. odt_class,
  288. odt_objcclass,
  289. odt_object,
  290. odt_cppclass:
  291. begin
  292. { for now don't handle fields yet }
  293. encodedstr:=encodedstr+'{[i8 x '+tostr(def.size)+']}';
  294. if not noimplicitderef and
  295. is_implicit_pointer_object_type(def) then
  296. encodedstr:=encodedstr+'*'
  297. end;
  298. odt_interfacecom,
  299. odt_interfacecom_function,
  300. odt_interfacecom_property,
  301. odt_interfacecorba,
  302. odt_dispinterface,
  303. odt_objcprotocol:
  304. begin
  305. { opaque for now }
  306. encodedstr:=encodedstr+'i8*'
  307. end;
  308. else
  309. internalerror(2013100601);
  310. end;
  311. undefineddef,
  312. errordef :
  313. internalerror(2013100604);
  314. procdef :
  315. begin
  316. { should be handled via llvmencodeproctype/llvmaddencodedproctype }
  317. internalerror(2014012601);
  318. end;
  319. else
  320. internalerror(2013100603);
  321. end;
  322. end;
  323. procedure llvmaddencodedtype(def: tdef; inaggregate: boolean; var encodedstr: TSymStr);
  324. begin
  325. llvmaddencodedtype_intern(def,inaggregate,false,encodedstr);
  326. end;
  327. procedure llvmaddencodedabstractrecordtype(def: tabstractrecorddef; var encodedstr: TSymStr);
  328. var
  329. st: tllvmshadowsymtable;
  330. symdeflist: tfpobjectlist;
  331. i: longint;
  332. begin
  333. st:=tabstractrecordsymtable(def.symtable).llvmst;
  334. symdeflist:=st.symdeflist;
  335. if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
  336. encodedstr:=encodedstr+'<';
  337. encodedstr:=encodedstr+'{ ';
  338. if symdeflist.count>0 then
  339. begin
  340. i:=0;
  341. if (def.typ=objectdef) and
  342. assigned(tobjectdef(def).childof) and
  343. is_class_or_interface_or_dispinterface(tllvmshadowsymtableentry(symdeflist[0]).def) then
  344. begin
  345. { insert the struct for the class rather than a pointer to the struct }
  346. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  347. internalerror(2008070601);
  348. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[0]).def,true,true,encodedstr);
  349. inc(i);
  350. end;
  351. while i<symdeflist.count do
  352. begin
  353. if i<>0 then
  354. encodedstr:=encodedstr+', ';
  355. llvmaddencodedtype_intern(tllvmshadowsymtableentry(symdeflist[i]).def,true,false,encodedstr);
  356. inc(i);
  357. end;
  358. end;
  359. encodedstr:=encodedstr+' }';
  360. if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
  361. encodedstr:=encodedstr+'>';
  362. end;
  363. procedure llvmextractvalueextinfo(paradef: tdef; var paralocdef: tdef; out signext: tllvmvalueextension);
  364. begin
  365. { implicit zero/sign extension for ABI compliance? (yes, if the size
  366. of a paraloc is larger than the size of the entire parameter) }
  367. if is_ordinal(paradef) and
  368. is_ordinal(paralocdef) and
  369. (paradef.size<paralocdef.size) then
  370. begin
  371. paralocdef:=paradef;
  372. if is_signed(paradef) then
  373. signext:=lve_signext
  374. else
  375. signext:=lve_zeroext
  376. end
  377. else
  378. signext:=lve_none;
  379. end;
  380. procedure llvmaddencodedparaloctype(hp: tparavarsym; proccalloption: tproccalloption; withparaname: boolean; var first: boolean; var encodedstr: TSymStr);
  381. var
  382. paraloc: PCGParaLocation;
  383. signext: tllvmvalueextension;
  384. usedef: tdef;
  385. begin
  386. paraloc:=hp.paraloc[calleeside].location;
  387. repeat
  388. usedef:=paraloc^.def;
  389. llvmextractvalueextinfo(hp.vardef,usedef,signext);
  390. { implicit zero/sign extension for ABI compliance? }
  391. if not first then
  392. encodedstr:=encodedstr+', '
  393. else
  394. first:=false;
  395. llvmaddencodedtype(usedef,false,encodedstr);
  396. { in case signextstr<>'', there should be only one paraloc -> no need
  397. to clear (reason: it means that the paraloc is larger than the
  398. original parameter) }
  399. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  400. { sret: hidden pointer for structured function result }
  401. if vo_is_funcret in hp.varoptions then
  402. encodedstr:=encodedstr+' sret'
  403. else if not paramanager.push_addr_param(hp.varspez,hp.vardef,proccalloption) and
  404. llvmbyvalparaloc(paraloc) then
  405. encodedstr:=encodedstr+'* byval';
  406. if withparaname then
  407. begin
  408. if paraloc^.llvmloc.loc<>LOC_REFERENCE then
  409. internalerror(2014010803);
  410. encodedstr:=encodedstr+' '+paraloc^.llvmloc.sym.name;
  411. end;
  412. paraloc:=paraloc^.next;
  413. until not assigned(paraloc);
  414. end;
  415. function llvmencodeproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype): TSymStr;
  416. begin
  417. result:='';
  418. llvmaddencodedproctype(def,customname,pddecltype,result);
  419. end;
  420. procedure llvmaddencodedproctype(def: tabstractprocdef; const customname: TSymStr; pddecltype: tllvmprocdefdecltype; var encodedstr: TSymStr);
  421. var
  422. usedef: tdef;
  423. paranr: longint;
  424. hp: tparavarsym;
  425. signext: tllvmvalueextension;
  426. first: boolean;
  427. begin
  428. def.init_paraloc_info(calleeside);
  429. first:=true;
  430. { function result (return-by-ref is handled explicitly) }
  431. if not paramanager.ret_in_param(def.returndef,def) then
  432. begin
  433. usedef:=llvmgetcgparadef(def.funcretloc[calleeside],false);
  434. llvmextractvalueextinfo(def.returndef,usedef,signext);
  435. { specifying result sign extention information for an alias causes
  436. an error for some reason }
  437. if pddecltype in [lpd_decl,lpd_procvar] then
  438. encodedstr:=encodedstr+llvmvalueextension2str[signext];
  439. encodedstr:=encodedstr+' ';
  440. llvmaddencodedtype_intern(usedef,false,false,encodedstr);
  441. end
  442. else
  443. begin
  444. encodedstr:=encodedstr+' ';
  445. llvmaddencodedtype(voidtype,false,encodedstr);
  446. end;
  447. encodedstr:=encodedstr+' ';
  448. { add procname? }
  449. if (pddecltype in [lpd_decl]) and
  450. (def.typ=procdef) then
  451. if customname='' then
  452. encodedstr:=encodedstr+tprocdef(def).mangledname
  453. else
  454. encodedstr:=encodedstr+customname;
  455. encodedstr:=encodedstr+'(';
  456. { parameters }
  457. first:=true;
  458. for paranr:=0 to def.paras.count-1 do
  459. begin
  460. hp:=tparavarsym(def.paras[paranr]);
  461. llvmaddencodedparaloctype(hp,def.proccalloption,pddecltype in [lpd_decl],first,encodedstr);
  462. end;
  463. encodedstr:=encodedstr+')'
  464. end;
  465. function llvmgettemprecorddef(fieldtypes: tfplist; packrecords: shortint): trecorddef;
  466. var
  467. i: longint;
  468. res: PHashSetItem;
  469. oldsymtablestack: tsymtablestack;
  470. hrecst: trecordsymtable;
  471. hdef: tdef;
  472. hrecdef: trecorddef;
  473. sym: tfieldvarsym;
  474. typename: string;
  475. begin
  476. typename:='$llvmstruct_';
  477. for i:=0 to fieldtypes.count-1 do
  478. begin
  479. hdef:=tdef(fieldtypes[i]);
  480. case hdef.typ of
  481. orddef:
  482. case torddef(hdef).ordtype of
  483. s8bit,
  484. u8bit:
  485. typename:=typename+'i8';
  486. s16bit,
  487. u16bit:
  488. typename:=typename+'i16';
  489. s32bit,
  490. u32bit:
  491. typename:=typename+'i32';
  492. s64bit,
  493. u64bit:
  494. typename:=typename+'i64';
  495. else
  496. { other types should not appear currently, add as needed }
  497. internalerror(2014012001);
  498. end;
  499. floatdef:
  500. case tfloatdef(hdef).floattype of
  501. s32real:
  502. typename:=typename+'f32';
  503. s64real:
  504. typename:=typename+'f64';
  505. else
  506. { other types should not appear currently, add as needed }
  507. internalerror(2014012008);
  508. end;
  509. else
  510. { other types should not appear currently, add as needed }
  511. internalerror(2014012009);
  512. end;
  513. end;
  514. if not assigned(current_module) then
  515. internalerror(2014012002);
  516. res:=current_module.llvmdefs.FindOrAdd(@typename[1],length(typename));
  517. if not assigned(res^.Data) then
  518. begin
  519. oldsymtablestack:=symtablestack;
  520. { do not simply push/pop current_module.localsymtable, because
  521. that can have side-effects (e.g., it removes helpers) }
  522. symtablestack:=nil;
  523. hrecst:=trecordsymtable.create(typename,packrecords);
  524. hrecdef:=trecorddef.create(typename,hrecst);
  525. for i:=0 to fieldtypes.count-1 do
  526. begin
  527. sym:=tfieldvarsym.create('$f'+tostr(i),vs_value,tdef(fieldtypes[i]),[]);
  528. hrecst.insert(sym);
  529. hrecst.addfield(sym,vis_hidden);
  530. end;
  531. res^.Data:=hrecdef;
  532. if assigned(current_module.localsymtable) then
  533. current_module.localsymtable.insertdef(tdef(res^.Data))
  534. else
  535. current_module.globalsymtable.insertdef(tdef(res^.Data));
  536. symtablestack:=oldsymtablestack;
  537. end;
  538. result:=trecorddef(res^.Data);
  539. end;
  540. function llvmgetcgparadef(const cgpara: tcgpara; beforevalueext: boolean): tdef;
  541. var
  542. retdeflist: tfplist;
  543. retloc: pcgparalocation;
  544. usedef: tdef;
  545. valueext: tllvmvalueextension;
  546. begin
  547. { single location }
  548. if not assigned(cgpara.location^.next) then
  549. begin
  550. { def of the location, except in case of zero/sign-extension }
  551. usedef:=cgpara.location^.def;
  552. if beforevalueext then
  553. llvmextractvalueextinfo(cgpara.def,usedef,valueext);
  554. result:=usedef;
  555. exit
  556. end;
  557. { multiple locations -> create temp record }
  558. retdeflist:=tfplist.create;
  559. retloc:=cgpara.location;
  560. repeat
  561. retdeflist.add(retloc^.def);
  562. retloc:=retloc^.next;
  563. until not assigned(retloc);
  564. result:=llvmgettemprecorddef(retdeflist,C_alignment);
  565. end;
  566. function llvmencodetype(def: tdef): TSymStr;
  567. begin
  568. result:='';
  569. llvmaddencodedtype(def,false,result);
  570. end;
  571. end.