symsym.pas 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  3. Implementation for the symbols types of the symtable
  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. unit symsym;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cutils,
  23. { target }
  24. globtype,globals,widestr,constexp,
  25. { symtable }
  26. symconst,symbase,symtype,symdef,defcmp,
  27. { ppu }
  28. ppu,finput,
  29. cclasses,symnot,
  30. { aasm }
  31. aasmbase,
  32. cpuinfo,cpubase,cgbase,cgutils,parabase
  33. ;
  34. type
  35. { this class is the base for all symbol objects }
  36. tstoredsym = class(tsym)
  37. public
  38. constructor create(st:tsymtyp;const n : string);
  39. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  40. destructor destroy;override;
  41. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  42. end;
  43. tlabelsym = class(tstoredsym)
  44. used,
  45. defined,
  46. nonlocal : boolean;
  47. { points to the matching node, only valid resultdef pass is run and
  48. the goto<->label relation in the node tree is created, should
  49. be a tnode }
  50. code : pointer;
  51. { points to the jump buffer }
  52. jumpbuf : tstoredsym;
  53. { when the label is defined in an asm block, this points to the
  54. generated asmlabel }
  55. asmblocklabel : tasmlabel;
  56. constructor create(const n : string);
  57. constructor ppuload(ppufile:tcompilerppufile);
  58. procedure ppuwrite(ppufile:tcompilerppufile);override;
  59. function mangledname:string;override;
  60. end;
  61. tunitsym = class(Tstoredsym)
  62. module : tobject; { tmodule }
  63. constructor create(const n : string;amodule : tobject);
  64. constructor ppuload(ppufile:tcompilerppufile);
  65. destructor destroy;override;
  66. procedure ppuwrite(ppufile:tcompilerppufile);override;
  67. end;
  68. terrorsym = class(Tsym)
  69. constructor create;
  70. end;
  71. { tprocsym }
  72. tprocsym = class(tstoredsym)
  73. protected
  74. FProcdefList : TFPObjectList;
  75. FProcdefDerefList : TFPList;
  76. public
  77. constructor create(const n : string);
  78. constructor ppuload(ppufile:tcompilerppufile);
  79. destructor destroy;override;
  80. { writes all declarations except the specified one }
  81. procedure write_parameter_lists(skipdef:tprocdef);
  82. { tests, if all procedures definitions are defined and not }
  83. { only forward }
  84. procedure check_forward;
  85. procedure ppuwrite(ppufile:tcompilerppufile);override;
  86. procedure buildderef;override;
  87. procedure deref;override;
  88. function find_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  89. function find_procdef_bypara(para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  90. function find_procdef_byoptions(ops:tprocoptions): Tprocdef;
  91. function find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  92. function find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  93. function find_procdef_enumerator_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  94. property ProcdefList:TFPObjectList read FProcdefList;
  95. end;
  96. ttypesym = class(Tstoredsym)
  97. typedef : tdef;
  98. typedefderef : tderef;
  99. fprettyname : ansistring;
  100. constructor create(const n : string;def:tdef);
  101. constructor ppuload(ppufile:tcompilerppufile);
  102. procedure ppuwrite(ppufile:tcompilerppufile);override;
  103. procedure buildderef;override;
  104. procedure deref;override;
  105. function prettyname : string;override;
  106. end;
  107. tabstractvarsym = class(tstoredsym)
  108. varoptions : tvaroptions;
  109. notifications : Tlinkedlist;
  110. varspez : tvarspez; { sets the type of access }
  111. varregable : tvarregable;
  112. varstate : tvarstate;
  113. { Has the address of this variable potentially escaped the }
  114. { block in which is was declared? }
  115. { could also be part of tabstractnormalvarsym, but there's }
  116. { one byte left here till the next 4 byte alignment }
  117. addr_taken : boolean;
  118. constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  119. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  120. destructor destroy;override;
  121. procedure ppuwrite(ppufile:tcompilerppufile);override;
  122. procedure buildderef;override;
  123. procedure deref;override;
  124. function getsize : asizeint;
  125. function getpackedbitsize : longint;
  126. function is_regvar(refpara: boolean):boolean;
  127. procedure trigger_notifications(what:Tnotification_flag);
  128. function register_notification(flags:Tnotification_flags;
  129. callback:Tnotification_callback):cardinal;
  130. procedure unregister_notification(id:cardinal);
  131. function jvmmangledbasename:string;
  132. private
  133. _vardef : tdef;
  134. vardefderef : tderef;
  135. procedure setvardef(def:tdef);
  136. public
  137. property vardef: tdef read _vardef write setvardef;
  138. end;
  139. tfieldvarsym = class(tabstractvarsym)
  140. fieldoffset : asizeint; { offset in record/object }
  141. cachedmangledname: pshortstring; { mangled name for ObjC or Java }
  142. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  143. constructor ppuload(ppufile:tcompilerppufile);
  144. procedure ppuwrite(ppufile:tcompilerppufile);override;
  145. function mangledname:string;override;
  146. destructor destroy;override;
  147. end;
  148. tabstractnormalvarsym = class(tabstractvarsym)
  149. defaultconstsym : tsym;
  150. defaultconstsymderef : tderef;
  151. localloc : TLocation; { register/reference for local var }
  152. initialloc : TLocation; { initial location so it can still be initialized later after the location was changed by SSA }
  153. constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  154. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  155. procedure ppuwrite(ppufile:tcompilerppufile);override;
  156. procedure buildderef;override;
  157. procedure deref;override;
  158. end;
  159. tlocalvarsym = class(tabstractnormalvarsym)
  160. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  161. constructor ppuload(ppufile:tcompilerppufile);
  162. procedure ppuwrite(ppufile:tcompilerppufile);override;
  163. end;
  164. tparavarsym = class(tabstractnormalvarsym)
  165. paraloc : array[tcallercallee] of TCGPara;
  166. paranr : word; { position of this parameter }
  167. { in MacPas mode, "univ" parameters mean that type checking should
  168. be disabled, except that the size of the passed parameter must
  169. match the size of the formal parameter }
  170. univpara : boolean;
  171. {$ifdef EXTDEBUG}
  172. eqval : tequaltype;
  173. {$endif EXTDEBUG}
  174. constructor create(const n : string;nr:word;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  175. constructor ppuload(ppufile:tcompilerppufile);
  176. destructor destroy;override;
  177. procedure ppuwrite(ppufile:tcompilerppufile);override;
  178. end;
  179. tstaticvarsym = class(tabstractnormalvarsym)
  180. private
  181. _mangledname : pshortstring;
  182. public
  183. section : ansistring;
  184. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  185. constructor create_dll(const n : string;vsp:tvarspez;def:tdef);
  186. constructor create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
  187. constructor ppuload(ppufile:tcompilerppufile);
  188. destructor destroy;override;
  189. procedure ppuwrite(ppufile:tcompilerppufile);override;
  190. function mangledname:string;override;
  191. procedure set_mangledname(const s:string);
  192. end;
  193. tabsolutevarsym = class(tabstractvarsym)
  194. public
  195. abstyp : absolutetyp;
  196. {$ifdef i386}
  197. absseg : boolean;
  198. {$endif i386}
  199. asmname : pshortstring;
  200. addroffset : aword;
  201. ref : tpropaccesslist;
  202. constructor create(const n : string;def:tdef);
  203. constructor create_ref(const n : string;def:tdef;_ref:tpropaccesslist);
  204. destructor destroy;override;
  205. constructor ppuload(ppufile:tcompilerppufile);
  206. procedure buildderef;override;
  207. procedure deref;override;
  208. function mangledname : string;override;
  209. procedure ppuwrite(ppufile:tcompilerppufile);override;
  210. end;
  211. tpropaccesslisttypes=(palt_none,palt_read,palt_write,palt_stored);
  212. tpropertysym = class(Tstoredsym)
  213. propoptions : tpropertyoptions;
  214. overriddenpropsym : tpropertysym;
  215. overriddenpropsymderef : tderef;
  216. propdef : tdef;
  217. propdefderef : tderef;
  218. indexdef : tdef;
  219. indexdefderef : tderef;
  220. index,
  221. default : longint;
  222. dispid : longint;
  223. propaccesslist: array[tpropaccesslisttypes] of tpropaccesslist;
  224. constructor create(const n : string);
  225. destructor destroy;override;
  226. constructor ppuload(ppufile:tcompilerppufile);
  227. function getsize : asizeint;
  228. procedure ppuwrite(ppufile:tcompilerppufile);override;
  229. procedure buildderef;override;
  230. procedure deref;override;
  231. end;
  232. tconstvalue = record
  233. case integer of
  234. 0: (valueord : tconstexprint);
  235. 1: (valueordptr : tconstptruint);
  236. 2: (valueptr : pointer; len : longint);
  237. end;
  238. tconstsym = class(tstoredsym)
  239. constdef : tdef;
  240. constdefderef : tderef;
  241. consttyp : tconsttyp;
  242. value : tconstvalue;
  243. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint;def:tdef);
  244. constructor create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;def:tdef);
  245. constructor create_ptr(const n : string;t : tconsttyp;v : pointer;def:tdef);
  246. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  247. constructor create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
  248. constructor ppuload(ppufile:tcompilerppufile);
  249. destructor destroy;override;
  250. procedure buildderef;override;
  251. procedure deref;override;
  252. procedure ppuwrite(ppufile:tcompilerppufile);override;
  253. end;
  254. tenumsym = class(Tstoredsym)
  255. value : longint;
  256. definition : tenumdef;
  257. definitionderef : tderef;
  258. constructor create(const n : string;def : tenumdef;v : longint);
  259. constructor ppuload(ppufile:tcompilerppufile);
  260. procedure ppuwrite(ppufile:tcompilerppufile);override;
  261. procedure buildderef;override;
  262. procedure deref;override;
  263. end;
  264. tsyssym = class(Tstoredsym)
  265. number : longint;
  266. constructor create(const n : string;l : longint);
  267. constructor ppuload(ppufile:tcompilerppufile);
  268. destructor destroy;override;
  269. procedure ppuwrite(ppufile:tcompilerppufile);override;
  270. end;
  271. const
  272. maxmacrolen=16*1024;
  273. type
  274. pmacrobuffer = ^tmacrobuffer;
  275. tmacrobuffer = array[0..maxmacrolen-1] of char;
  276. tmacro = class(tstoredsym)
  277. {Normally true, but false when a previously defined macro is undef-ed}
  278. defined : boolean;
  279. {True if this is a mac style compiler variable, in which case no macro
  280. substitutions shall be done.}
  281. is_compiler_var : boolean;
  282. {Whether the macro was used. NOTE: A use of a macro which was never defined}
  283. {e. g. an IFDEF which returns false, will not be registered as used,}
  284. {since there is no place to register its use. }
  285. is_used : boolean;
  286. buftext : pchar;
  287. buflen : longint;
  288. constructor create(const n : string);
  289. constructor ppuload(ppufile:tcompilerppufile);
  290. procedure ppuwrite(ppufile:tcompilerppufile);override;
  291. destructor destroy;override;
  292. function GetCopy:tmacro;
  293. end;
  294. var
  295. generrorsym : tsym;
  296. implementation
  297. uses
  298. { global }
  299. verbose,
  300. { target }
  301. systems,
  302. { symtable }
  303. defutil,symtable,jvmdef,
  304. fmodule,
  305. { tree }
  306. node,
  307. { aasm }
  308. aasmtai,aasmdata,
  309. { codegen }
  310. paramgr,
  311. procinfo
  312. ;
  313. {****************************************************************************
  314. Helpers
  315. ****************************************************************************}
  316. {****************************************************************************
  317. TSYM (base for all symtypes)
  318. ****************************************************************************}
  319. constructor tstoredsym.create(st:tsymtyp;const n : string);
  320. begin
  321. inherited create(st,n);
  322. { Register in current_module }
  323. if assigned(current_module) then
  324. begin
  325. current_module.symlist.Add(self);
  326. SymId:=current_module.symlist.Count-1;
  327. end;
  328. end;
  329. constructor tstoredsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  330. begin
  331. SymId:=ppufile.getlongint;
  332. inherited Create(st,ppufile.getstring);
  333. { Register symbol }
  334. current_module.symlist[SymId]:=self;
  335. ppufile.getposinfo(fileinfo);
  336. visibility:=tvisibility(ppufile.getbyte);
  337. ppufile.getsmallset(symoptions);
  338. if sp_has_deprecated_msg in symoptions then
  339. deprecatedmsg:=stringdup(ppufile.getstring)
  340. else
  341. deprecatedmsg:=nil;
  342. end;
  343. procedure tstoredsym.ppuwrite(ppufile:tcompilerppufile);
  344. begin
  345. ppufile.putlongint(SymId);
  346. ppufile.putstring(realname);
  347. ppufile.putposinfo(fileinfo);
  348. ppufile.putbyte(byte(visibility));
  349. ppufile.putsmallset(symoptions);
  350. if sp_has_deprecated_msg in symoptions then
  351. ppufile.putstring(deprecatedmsg^);
  352. end;
  353. destructor tstoredsym.destroy;
  354. begin
  355. inherited destroy;
  356. end;
  357. {****************************************************************************
  358. TLABELSYM
  359. ****************************************************************************}
  360. constructor tlabelsym.create(const n : string);
  361. begin
  362. inherited create(labelsym,n);
  363. used:=false;
  364. defined:=false;
  365. nonlocal:=false;
  366. code:=nil;
  367. end;
  368. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  369. begin
  370. inherited ppuload(labelsym,ppufile);
  371. code:=nil;
  372. used:=false;
  373. nonlocal:=false;
  374. defined:=true;
  375. end;
  376. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  377. begin
  378. if owner.symtabletype=globalsymtable then
  379. Message(sym_e_ill_label_decl)
  380. else
  381. begin
  382. inherited ppuwrite(ppufile);
  383. ppufile.writeentry(iblabelsym);
  384. end;
  385. end;
  386. function tlabelsym.mangledname:string;
  387. begin
  388. if not(defined) then
  389. begin
  390. defined:=true;
  391. if nonlocal then
  392. current_asmdata.getglobaljumplabel(asmblocklabel)
  393. else
  394. current_asmdata.getjumplabel(asmblocklabel);
  395. end;
  396. result:=asmblocklabel.name;
  397. end;
  398. {****************************************************************************
  399. TUNITSYM
  400. ****************************************************************************}
  401. constructor tunitsym.create(const n : string;amodule : tobject);
  402. begin
  403. inherited create(unitsym,n);
  404. module:=amodule;
  405. end;
  406. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  407. begin
  408. inherited ppuload(unitsym,ppufile);
  409. module:=nil;
  410. end;
  411. destructor tunitsym.destroy;
  412. begin
  413. inherited destroy;
  414. end;
  415. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  416. begin
  417. inherited ppuwrite(ppufile);
  418. ppufile.writeentry(ibunitsym);
  419. end;
  420. {****************************************************************************
  421. TPROCSYM
  422. ****************************************************************************}
  423. constructor tprocsym.create(const n : string);
  424. begin
  425. inherited create(procsym,n);
  426. FProcdefList:=TFPObjectList.Create(false);
  427. FProcdefderefList:=nil;
  428. { the tprocdef have their own symoptions, make the procsym
  429. always visible }
  430. visibility:=vis_public;
  431. end;
  432. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  433. var
  434. pdderef : tderef;
  435. i,
  436. pdcnt : longint;
  437. begin
  438. inherited ppuload(procsym,ppufile);
  439. FProcdefList:=TFPObjectList.Create(false);
  440. FProcdefDerefList:=TFPList.Create;
  441. pdcnt:=ppufile.getword;
  442. for i:=1 to pdcnt do
  443. begin
  444. ppufile.getderef(pdderef);
  445. FProcdefDerefList.Add(Pointer(PtrInt(pdderef.dataidx)));
  446. end;
  447. end;
  448. destructor tprocsym.destroy;
  449. begin
  450. FProcdefList.Free;
  451. if assigned(FProcdefDerefList) then
  452. FProcdefDerefList.Free;
  453. inherited destroy;
  454. end;
  455. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  456. var
  457. i : longint;
  458. d : tderef;
  459. begin
  460. inherited ppuwrite(ppufile);
  461. ppufile.putword(FProcdefDerefList.Count);
  462. for i:=0 to FProcdefDerefList.Count-1 do
  463. begin
  464. d.dataidx:=PtrInt(FProcdefDerefList[i]);
  465. ppufile.putderef(d);
  466. end;
  467. ppufile.writeentry(ibprocsym);
  468. end;
  469. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  470. var
  471. i : longint;
  472. pd : tprocdef;
  473. begin
  474. for i:=0 to ProcdefList.Count-1 do
  475. begin
  476. pd:=tprocdef(ProcdefList[i]);
  477. if pd<>skipdef then
  478. MessagePos1(pd.fileinfo,sym_h_param_list,pd.fullprocname(false));
  479. end;
  480. end;
  481. procedure tprocsym.check_forward;
  482. var
  483. i : longint;
  484. pd : tprocdef;
  485. begin
  486. for i:=0 to ProcdefList.Count-1 do
  487. begin
  488. pd:=tprocdef(ProcdefList[i]);
  489. if (pd.owner=owner) and (pd.forwarddef) then
  490. begin
  491. { For mode macpas. Make implicit externals (procedures declared in the interface
  492. section which do not have a counterpart in the implementation)
  493. to be an imported procedure }
  494. if (m_mac in current_settings.modeswitches) and
  495. (pd.interfacedef) then
  496. begin
  497. pd.setmangledname(target_info.CPrefix+tprocdef(pd).procsym.realname);
  498. if (not current_module.interface_only) then
  499. MessagePos1(pd.fileinfo,sym_w_forward_not_resolved,pd.fullprocname(false));
  500. end
  501. else
  502. begin
  503. MessagePos1(pd.fileinfo,sym_e_forward_not_resolved,pd.fullprocname(false));
  504. end;
  505. { Turn further error messages off }
  506. pd.forwarddef:=false;
  507. end;
  508. end;
  509. end;
  510. procedure tprocsym.buildderef;
  511. var
  512. i : longint;
  513. pd : tprocdef;
  514. d : tderef;
  515. begin
  516. if not assigned(FProcdefDerefList) then
  517. FProcdefDerefList:=TFPList.Create
  518. else
  519. FProcdefDerefList.Clear;
  520. for i:=0 to ProcdefList.Count-1 do
  521. begin
  522. pd:=tprocdef(ProcdefList[i]);
  523. { only write the proc definitions that belong
  524. to this procsym and are in the global symtable }
  525. if pd.owner=owner then
  526. begin
  527. d.build(pd);
  528. FProcdefDerefList.Add(Pointer(PtrInt(d.dataidx)));
  529. end;
  530. end;
  531. end;
  532. procedure tprocsym.deref;
  533. var
  534. i : longint;
  535. pd : tprocdef;
  536. d : tderef;
  537. begin
  538. { Clear all procdefs }
  539. ProcdefList.Clear;
  540. if not assigned(FProcdefDerefList) then
  541. internalerror(200611031);
  542. for i:=0 to FProcdefDerefList.Count-1 do
  543. begin
  544. d.dataidx:=PtrInt(FProcdefDerefList[i]);
  545. pd:=tprocdef(d.resolve);
  546. ProcdefList.Add(pd);
  547. end;
  548. end;
  549. function Tprocsym.Find_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  550. var
  551. i : longint;
  552. pd : tprocdef;
  553. begin
  554. result:=nil;
  555. for i:=0 to ProcdefList.Count-1 do
  556. begin
  557. pd:=tprocdef(ProcdefList[i]);
  558. if pd.proctypeoption=pt then
  559. begin
  560. result:=pd;
  561. exit;
  562. end;
  563. end;
  564. end;
  565. function Tprocsym.Find_procdef_bypara(para:TFPObjectList;retdef:tdef;
  566. cpoptions:tcompare_paras_options):Tprocdef;
  567. var
  568. i : longint;
  569. pd : tprocdef;
  570. eq : tequaltype;
  571. begin
  572. result:=nil;
  573. for i:=0 to ProcdefList.Count-1 do
  574. begin
  575. pd:=tprocdef(ProcdefList[i]);
  576. if assigned(retdef) then
  577. eq:=compare_defs(retdef,pd.returndef,nothingn)
  578. else
  579. eq:=te_equal;
  580. if (eq>=te_equal) or
  581. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  582. begin
  583. eq:=compare_paras(para,pd.paras,cp_value_equal_const,cpoptions);
  584. if (eq>=te_equal) or
  585. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  586. begin
  587. result:=pd;
  588. exit;
  589. end;
  590. end;
  591. end;
  592. end;
  593. function tprocsym.find_procdef_byoptions(ops: tprocoptions): Tprocdef;
  594. var
  595. i : longint;
  596. pd : tprocdef;
  597. begin
  598. result:=nil;
  599. for i:=0 to ProcdefList.Count-1 do
  600. begin
  601. pd:=tprocdef(ProcdefList[i]);
  602. if ops * pd.procoptions = ops then
  603. begin
  604. result:=pd;
  605. exit;
  606. end;
  607. end;
  608. end;
  609. function Tprocsym.Find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  610. var
  611. i : longint;
  612. bestpd,
  613. pd : tprocdef;
  614. eq,besteq : tequaltype;
  615. begin
  616. { This function will return the pprocdef of pprocsym that
  617. is the best match for procvardef. When there are multiple
  618. matches it returns nil.}
  619. result:=nil;
  620. bestpd:=nil;
  621. besteq:=te_incompatible;
  622. for i:=0 to ProcdefList.Count-1 do
  623. begin
  624. pd:=tprocdef(ProcdefList[i]);
  625. eq:=proc_to_procvar_equal(pd,d,false);
  626. if eq>=te_convert_l1 then
  627. begin
  628. { multiple procvars with the same equal level }
  629. if assigned(bestpd) and
  630. (besteq=eq) then
  631. exit;
  632. if eq>besteq then
  633. begin
  634. besteq:=eq;
  635. bestpd:=pd;
  636. end;
  637. end;
  638. end;
  639. result:=bestpd;
  640. end;
  641. function Tprocsym.Find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  642. var
  643. paraidx, realparamcount,
  644. i, j : longint;
  645. bestpd,
  646. hpd,
  647. pd : tprocdef;
  648. convtyp : tconverttype;
  649. eq : tequaltype;
  650. begin
  651. { This function will return the pprocdef of pprocsym that
  652. is the best match for fromdef and todef. }
  653. result:=nil;
  654. bestpd:=nil;
  655. besteq:=te_incompatible;
  656. for i:=0 to ProcdefList.Count-1 do
  657. begin
  658. pd:=tprocdef(ProcdefList[i]);
  659. if (pd.owner.symtabletype=staticsymtable) and not pd.owner.iscurrentunit then
  660. continue;
  661. if (equal_defs(todef,pd.returndef) or
  662. { shortstrings of different lengths are ok as result }
  663. (is_shortstring(todef) and is_shortstring(pd.returndef))) and
  664. { the result type must be always really equal and not an alias,
  665. if you mess with this code, check tw4093 }
  666. ((todef=pd.returndef) or
  667. (
  668. not(df_unique in todef.defoptions) and
  669. not(df_unique in pd.returndef.defoptions)
  670. )
  671. ) then
  672. begin
  673. paraidx:=0;
  674. { ignore vs_hidden parameters }
  675. while (paraidx<pd.paras.count) and
  676. assigned(pd.paras[paraidx]) and
  677. (vo_is_hidden_para in tparavarsym(pd.paras[paraidx]).varoptions) do
  678. inc(paraidx);
  679. realparamcount:=0;
  680. for j := 0 to pd.paras.Count-1 do
  681. if assigned(pd.paras[j]) and not (vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
  682. inc(realparamcount);
  683. if (paraidx<pd.paras.count) and
  684. assigned(pd.paras[paraidx]) and
  685. (realparamcount = 1) then
  686. begin
  687. eq:=compare_defs_ext(fromdef,tparavarsym(pd.paras[paraidx]).vardef,nothingn,convtyp,hpd,[]);
  688. { alias? if yes, only l1 choice,
  689. if you mess with this code, check tw4093 }
  690. if (eq=te_exact) and
  691. (fromdef<>tparavarsym(pd.paras[paraidx]).vardef) and
  692. ((df_unique in fromdef.defoptions) or
  693. (df_unique in tparavarsym(pd.paras[paraidx]).vardef.defoptions)) then
  694. eq:=te_convert_l1;
  695. if eq=te_exact then
  696. begin
  697. besteq:=eq;
  698. result:=pd;
  699. exit;
  700. end;
  701. if eq>besteq then
  702. begin
  703. bestpd:=pd;
  704. besteq:=eq;
  705. end;
  706. end;
  707. end;
  708. end;
  709. result:=bestpd;
  710. end;
  711. function Tprocsym.find_procdef_enumerator_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  712. var
  713. paraidx, realparamcount,
  714. i, j : longint;
  715. bestpd,
  716. hpd,
  717. pd : tprocdef;
  718. current : tpropertysym;
  719. convtyp : tconverttype;
  720. eq : tequaltype;
  721. begin
  722. { This function will return the pprocdef of pprocsym that
  723. is the best match for fromdef and todef. }
  724. result:=nil;
  725. bestpd:=nil;
  726. besteq:=te_incompatible;
  727. for i:=0 to ProcdefList.Count-1 do
  728. begin
  729. pd:=tprocdef(ProcdefList[i]);
  730. if (pd.owner.symtabletype=staticsymtable) and not pd.owner.iscurrentunit then
  731. continue;
  732. if not (is_class_or_interface_or_object(pd.returndef) or is_record(pd.returndef)) then
  733. continue;
  734. current := tpropertysym(tabstractrecorddef(pd.returndef).search_enumerator_current);
  735. if (current = nil) then
  736. continue;
  737. // compare current result def with the todef
  738. if (equal_defs(todef, current.propdef) or
  739. { shortstrings of different lengths are ok as result }
  740. (is_shortstring(todef) and is_shortstring(current.propdef))) and
  741. { the result type must be always really equal and not an alias,
  742. if you mess with this code, check tw4093 }
  743. ((todef=current.propdef) or
  744. (
  745. not(df_unique in todef.defoptions) and
  746. not(df_unique in current.propdef.defoptions)
  747. )
  748. ) then
  749. begin
  750. paraidx:=0;
  751. { ignore vs_hidden parameters }
  752. while (paraidx<pd.paras.count) and
  753. assigned(pd.paras[paraidx]) and
  754. (vo_is_hidden_para in tparavarsym(pd.paras[paraidx]).varoptions) do
  755. inc(paraidx);
  756. realparamcount:=0;
  757. for j := 0 to pd.paras.Count-1 do
  758. if assigned(pd.paras[j]) and not (vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
  759. inc(realparamcount);
  760. if (paraidx<pd.paras.count) and
  761. assigned(pd.paras[paraidx]) and
  762. (realparamcount = 1) then
  763. begin
  764. eq:=compare_defs_ext(fromdef,tparavarsym(pd.paras[paraidx]).vardef,nothingn,convtyp,hpd,[]);
  765. { alias? if yes, only l1 choice,
  766. if you mess with this code, check tw4093 }
  767. if (eq=te_exact) and
  768. (fromdef<>tparavarsym(pd.paras[paraidx]).vardef) and
  769. ((df_unique in fromdef.defoptions) or
  770. (df_unique in tparavarsym(pd.paras[paraidx]).vardef.defoptions)) then
  771. eq:=te_convert_l1;
  772. if eq=te_exact then
  773. begin
  774. besteq:=eq;
  775. result:=pd;
  776. exit;
  777. end;
  778. if eq>besteq then
  779. begin
  780. bestpd:=pd;
  781. besteq:=eq;
  782. end;
  783. end;
  784. end;
  785. end;
  786. result:=bestpd;
  787. end;
  788. {****************************************************************************
  789. TERRORSYM
  790. ****************************************************************************}
  791. constructor terrorsym.create;
  792. begin
  793. inherited create(errorsym,'');
  794. end;
  795. {****************************************************************************
  796. TPROPERTYSYM
  797. ****************************************************************************}
  798. constructor tpropertysym.create(const n : string);
  799. var
  800. pap : tpropaccesslisttypes;
  801. begin
  802. inherited create(propertysym,n);
  803. propoptions:=[];
  804. index:=0;
  805. default:=0;
  806. propdef:=nil;
  807. indexdef:=nil;
  808. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  809. propaccesslist[pap]:=tpropaccesslist.create;
  810. end;
  811. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  812. var
  813. pap : tpropaccesslisttypes;
  814. begin
  815. inherited ppuload(propertysym,ppufile);
  816. ppufile.getsmallset(propoptions);
  817. ppufile.getderef(overriddenpropsymderef);
  818. ppufile.getderef(propdefderef);
  819. index:=ppufile.getlongint;
  820. default:=ppufile.getlongint;
  821. ppufile.getderef(indexdefderef);
  822. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  823. propaccesslist[pap]:=ppufile.getpropaccesslist;
  824. end;
  825. destructor tpropertysym.destroy;
  826. var
  827. pap : tpropaccesslisttypes;
  828. begin
  829. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  830. propaccesslist[pap].free;
  831. inherited destroy;
  832. end;
  833. procedure tpropertysym.buildderef;
  834. var
  835. pap : tpropaccesslisttypes;
  836. begin
  837. overriddenpropsymderef.build(overriddenpropsym);
  838. propdefderef.build(propdef);
  839. indexdefderef.build(indexdef);
  840. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  841. propaccesslist[pap].buildderef;
  842. end;
  843. procedure tpropertysym.deref;
  844. var
  845. pap : tpropaccesslisttypes;
  846. begin
  847. overriddenpropsym:=tpropertysym(overriddenpropsymderef.resolve);
  848. indexdef:=tdef(indexdefderef.resolve);
  849. propdef:=tdef(propdefderef.resolve);
  850. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  851. propaccesslist[pap].resolve;
  852. end;
  853. function tpropertysym.getsize : asizeint;
  854. begin
  855. getsize:=0;
  856. end;
  857. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  858. var
  859. pap : tpropaccesslisttypes;
  860. begin
  861. inherited ppuwrite(ppufile);
  862. ppufile.putsmallset(propoptions);
  863. ppufile.putderef(overriddenpropsymderef);
  864. ppufile.putderef(propdefderef);
  865. ppufile.putlongint(index);
  866. ppufile.putlongint(default);
  867. ppufile.putderef(indexdefderef);
  868. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  869. ppufile.putpropaccesslist(propaccesslist[pap]);
  870. ppufile.writeentry(ibpropertysym);
  871. end;
  872. {****************************************************************************
  873. TABSTRACTVARSYM
  874. ****************************************************************************}
  875. constructor tabstractvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  876. begin
  877. inherited create(st,n);
  878. vardef:=def;
  879. varspez:=vsp;
  880. varstate:=vs_declared;
  881. varoptions:=vopts;
  882. end;
  883. constructor tabstractvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  884. begin
  885. inherited ppuload(st,ppufile);
  886. varstate:=vs_readwritten;
  887. varspez:=tvarspez(ppufile.getbyte);
  888. varregable:=tvarregable(ppufile.getbyte);
  889. addr_taken:=boolean(ppufile.getbyte);
  890. ppufile.getderef(vardefderef);
  891. ppufile.getsmallset(varoptions);
  892. end;
  893. destructor tabstractvarsym.destroy;
  894. begin
  895. if assigned(notifications) then
  896. notifications.destroy;
  897. inherited destroy;
  898. end;
  899. procedure tabstractvarsym.buildderef;
  900. begin
  901. vardefderef.build(vardef);
  902. end;
  903. procedure tabstractvarsym.deref;
  904. var
  905. oldvarregable: tvarregable;
  906. begin
  907. { setting the vardef also updates varregable. We just loaded this }
  908. { value from a ppu, so it must not be changed (e.g. tw7817a.pp/ }
  909. { tw7817b.pp: the address is taken of a local variable in an }
  910. { inlined procedure -> must remain non-regable when inlining) }
  911. oldvarregable:=varregable;
  912. vardef:=tdef(vardefderef.resolve);
  913. varregable:=oldvarregable;
  914. end;
  915. procedure tabstractvarsym.ppuwrite(ppufile:tcompilerppufile);
  916. var
  917. oldintfcrc : boolean;
  918. begin
  919. inherited ppuwrite(ppufile);
  920. ppufile.putbyte(byte(varspez));
  921. oldintfcrc:=ppufile.do_crc;
  922. ppufile.do_crc:=false;
  923. ppufile.putbyte(byte(varregable));
  924. ppufile.putbyte(byte(addr_taken));
  925. ppufile.do_crc:=oldintfcrc;
  926. ppufile.putderef(vardefderef);
  927. ppufile.putsmallset(varoptions);
  928. end;
  929. function tabstractvarsym.getsize : asizeint;
  930. begin
  931. if assigned(vardef) and
  932. ((vardef.typ<>arraydef) or
  933. is_dynamic_array(vardef) or
  934. (tarraydef(vardef).highrange>=tarraydef(vardef).lowrange)) then
  935. result:=vardef.size
  936. else
  937. result:=0;
  938. end;
  939. function tabstractvarsym.getpackedbitsize : longint;
  940. begin
  941. { bitpacking is only done for ordinals }
  942. if not is_ordinal(vardef) then
  943. internalerror(2006082010);
  944. result:=vardef.packedbitsize;
  945. end;
  946. function tabstractvarsym.is_regvar(refpara: boolean):boolean;
  947. begin
  948. { Register variables are not allowed in the following cases:
  949. - regvars are disabled
  950. - exceptions are used (after an exception is raised the contents of the
  951. registers is not valid anymore)
  952. - it has a local copy
  953. - the value needs to be in memory (i.e. reference counted) }
  954. result:=(cs_opt_regvar in current_settings.optimizerswitches) and
  955. not(pi_has_assembler_block in current_procinfo.flags) and
  956. not(pi_uses_exceptions in current_procinfo.flags) and
  957. not(pi_has_interproclabel in current_procinfo.flags) and
  958. not(vo_has_local_copy in varoptions) and
  959. ((refpara and
  960. (varregable <> vr_none)) or
  961. (not refpara and
  962. not(varregable in [vr_none,vr_addr])))
  963. {$if not defined(powerpc) and not defined(powerpc64)}
  964. and ((vardef.typ <> recorddef) or
  965. (varregable = vr_addr) or
  966. not(varstate in [vs_written,vs_readwritten]));
  967. {$endif}
  968. end;
  969. procedure tabstractvarsym.trigger_notifications(what:Tnotification_flag);
  970. var n:Tnotification;
  971. begin
  972. if assigned(notifications) then
  973. begin
  974. n:=Tnotification(notifications.first);
  975. while assigned(n) do
  976. begin
  977. if what in n.flags then
  978. n.callback(what,self);
  979. n:=Tnotification(n.next);
  980. end;
  981. end;
  982. end;
  983. function Tabstractvarsym.register_notification(flags:Tnotification_flags;callback:
  984. Tnotification_callback):cardinal;
  985. var n:Tnotification;
  986. begin
  987. if not assigned(notifications) then
  988. notifications:=Tlinkedlist.create;
  989. n:=Tnotification.create(flags,callback);
  990. register_notification:=n.id;
  991. notifications.concat(n);
  992. end;
  993. procedure Tabstractvarsym.unregister_notification(id:cardinal);
  994. var n:Tnotification;
  995. begin
  996. if not assigned(notifications) then
  997. internalerror(200212311)
  998. else
  999. begin
  1000. n:=Tnotification(notifications.first);
  1001. while assigned(n) do
  1002. begin
  1003. if n.id=id then
  1004. begin
  1005. notifications.remove(n);
  1006. n.destroy;
  1007. exit;
  1008. end;
  1009. n:=Tnotification(n.next);
  1010. end;
  1011. internalerror(200212311)
  1012. end;
  1013. end;
  1014. function tabstractvarsym.jvmmangledbasename: string;
  1015. var
  1016. founderror: tdef;
  1017. begin
  1018. if not jvmtryencodetype(vardef,result,founderror) then
  1019. internalerror(2011011203);
  1020. if (typ=paravarsym) and
  1021. (vo_is_self in tparavarsym(self).varoptions) then
  1022. result:='this ' +result
  1023. else if (typ in [paravarsym,localvarsym]) and
  1024. ([vo_is_funcret,vo_is_result] * tabstractnormalvarsym(self).varoptions <> []) then
  1025. result:='result '+result
  1026. else
  1027. result:=realname+' '+result;
  1028. end;
  1029. procedure tabstractvarsym.setvardef(def:tdef);
  1030. begin
  1031. _vardef := def;
  1032. { can we load the value into a register ? }
  1033. if not assigned(owner) or
  1034. (owner.symtabletype in [localsymtable,parasymtable]) or
  1035. (
  1036. (owner.symtabletype=staticsymtable) and
  1037. not(cs_create_pic in current_settings.moduleswitches)
  1038. ) then
  1039. begin
  1040. if tstoreddef(vardef).is_intregable then
  1041. varregable:=vr_intreg
  1042. else
  1043. { $warning TODO: no fpu regvar in staticsymtable yet, need initialization with 0 }
  1044. if {(
  1045. not assigned(owner) or
  1046. (owner.symtabletype<>staticsymtable)
  1047. ) and }
  1048. tstoreddef(vardef).is_fpuregable then
  1049. begin
  1050. if use_vectorfpu(vardef) then
  1051. varregable:=vr_mmreg
  1052. else
  1053. varregable:=vr_fpureg;
  1054. end;
  1055. end;
  1056. end;
  1057. {****************************************************************************
  1058. TFIELDVARSYM
  1059. ****************************************************************************}
  1060. constructor tfieldvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1061. begin
  1062. inherited create(fieldvarsym,n,vsp,def,vopts);
  1063. fieldoffset:=-1;
  1064. end;
  1065. constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
  1066. begin
  1067. inherited ppuload(fieldvarsym,ppufile);
  1068. fieldoffset:=ppufile.getaint;
  1069. end;
  1070. procedure tfieldvarsym.ppuwrite(ppufile:tcompilerppufile);
  1071. begin
  1072. inherited ppuwrite(ppufile);
  1073. ppufile.putaint(fieldoffset);
  1074. ppufile.writeentry(ibfieldvarsym);
  1075. end;
  1076. function tfieldvarsym.mangledname:string;
  1077. var
  1078. srsym : tsym;
  1079. srsymtable : tsymtable;
  1080. begin
  1081. {$ifdef jvm}
  1082. if is_javaclass(tdef(owner.defowner)) then
  1083. begin
  1084. if assigned(cachedmangledname) then
  1085. result:=cachedmangledname^
  1086. else
  1087. begin
  1088. result:=jvmmangledbasename;
  1089. jvmaddtypeownerprefix(owner,result);
  1090. cachedmangledname:=stringdup(result);
  1091. end;
  1092. end
  1093. else
  1094. {$endif jvm}
  1095. if sp_static in symoptions then
  1096. begin
  1097. if searchsym(lower(owner.name^)+'_'+name,srsym,srsymtable) then
  1098. result:=srsym.mangledname
  1099. { when generating the debug info for the module in which the }
  1100. { symbol is defined, the localsymtable of that module is }
  1101. { already popped from the symtablestack }
  1102. else if searchsym_in_module(current_module,lower(owner.name^)+'_'+name,srsym,srsymtable) then
  1103. result:=srsym.mangledname
  1104. else
  1105. internalerror(2007012501);
  1106. end
  1107. else if is_objcclass(tdef(owner.defowner)) then
  1108. begin
  1109. if assigned(cachedmangledname) then
  1110. result:=cachedmangledname^
  1111. else
  1112. begin
  1113. result:=target_info.cprefix+'OBJC_IVAR_$_'+tobjectdef(owner.defowner).objextname^+'.'+RealName;
  1114. cachedmangledname:=stringdup(result);
  1115. end;
  1116. end
  1117. else
  1118. result:=inherited mangledname;
  1119. end;
  1120. destructor tfieldvarsym.destroy;
  1121. begin
  1122. stringdispose(cachedmangledname);
  1123. inherited destroy;
  1124. end;
  1125. {****************************************************************************
  1126. TABSTRACTNORMALVARSYM
  1127. ****************************************************************************}
  1128. constructor tabstractnormalvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1129. begin
  1130. inherited create(st,n,vsp,def,vopts);
  1131. fillchar(localloc,sizeof(localloc),0);
  1132. fillchar(initialloc,sizeof(initialloc),0);
  1133. defaultconstsym:=nil;
  1134. end;
  1135. constructor tabstractnormalvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  1136. begin
  1137. inherited ppuload(st,ppufile);
  1138. fillchar(localloc,sizeof(localloc),0);
  1139. fillchar(initialloc,sizeof(initialloc),0);
  1140. ppufile.getderef(defaultconstsymderef);
  1141. end;
  1142. procedure tabstractnormalvarsym.buildderef;
  1143. begin
  1144. inherited buildderef;
  1145. defaultconstsymderef.build(defaultconstsym);
  1146. end;
  1147. procedure tabstractnormalvarsym.deref;
  1148. begin
  1149. inherited deref;
  1150. defaultconstsym:=tsym(defaultconstsymderef.resolve);
  1151. end;
  1152. procedure tabstractnormalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1153. begin
  1154. inherited ppuwrite(ppufile);
  1155. ppufile.putderef(defaultconstsymderef);
  1156. end;
  1157. {****************************************************************************
  1158. Tstaticvarsym
  1159. ****************************************************************************}
  1160. constructor tstaticvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1161. begin
  1162. inherited create(staticvarsym,n,vsp,def,vopts);
  1163. _mangledname:=nil;
  1164. end;
  1165. constructor tstaticvarsym.create_dll(const n : string;vsp:tvarspez;def:tdef);
  1166. begin
  1167. tstaticvarsym(self).create(n,vsp,def,[vo_is_dll_var]);
  1168. end;
  1169. constructor tstaticvarsym.create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
  1170. begin
  1171. tstaticvarsym(self).create(n,vsp,def,[]);
  1172. set_mangledname(mangled);
  1173. end;
  1174. constructor tstaticvarsym.ppuload(ppufile:tcompilerppufile);
  1175. begin
  1176. inherited ppuload(staticvarsym,ppufile);
  1177. if vo_has_mangledname in varoptions then
  1178. _mangledname:=stringdup(ppufile.getstring)
  1179. else
  1180. _mangledname:=nil;
  1181. if vo_has_section in varoptions then
  1182. section:=ppufile.getansistring;
  1183. end;
  1184. destructor tstaticvarsym.destroy;
  1185. begin
  1186. if assigned(_mangledname) then
  1187. begin
  1188. {$ifdef MEMDEBUG}
  1189. memmanglednames.start;
  1190. {$endif MEMDEBUG}
  1191. stringdispose(_mangledname);
  1192. {$ifdef MEMDEBUG}
  1193. memmanglednames.stop;
  1194. {$endif MEMDEBUG}
  1195. end;
  1196. inherited destroy;
  1197. end;
  1198. procedure tstaticvarsym.ppuwrite(ppufile:tcompilerppufile);
  1199. begin
  1200. inherited ppuwrite(ppufile);
  1201. if vo_has_mangledname in varoptions then
  1202. ppufile.putstring(_mangledname^);
  1203. if vo_has_section in varoptions then
  1204. ppufile.putansistring(section);
  1205. ppufile.writeentry(ibstaticvarsym);
  1206. end;
  1207. function tstaticvarsym.mangledname:string;
  1208. var
  1209. {$ifdef jvm}
  1210. tmpname: string;
  1211. {$else jvm}
  1212. prefix : string[2];
  1213. {$endif jvm}
  1214. begin
  1215. if not assigned(_mangledname) then
  1216. begin
  1217. {$ifdef jvm}
  1218. tmpname:=jvmmangledbasename;
  1219. jvmaddtypeownerprefix(owner,tmpname);
  1220. _mangledname:=stringdup(tmpname);
  1221. {$else jvm}
  1222. if (vo_is_typed_const in varoptions) then
  1223. prefix:='TC'
  1224. else
  1225. prefix:='U';
  1226. {$ifdef compress}
  1227. _mangledname:=stringdup(minilzw_encode(make_mangledname(prefix,owner,name)));
  1228. {$else compress}
  1229. _mangledname:=stringdup(make_mangledname(prefix,owner,name));
  1230. {$endif compress}
  1231. {$endif jvm}
  1232. end;
  1233. result:=_mangledname^;
  1234. end;
  1235. procedure tstaticvarsym.set_mangledname(const s:string);
  1236. begin
  1237. stringdispose(_mangledname);
  1238. {$if defined(jvm)}
  1239. internalerror(2011011202);
  1240. {$elseif defined(compress)}
  1241. _mangledname:=stringdup(minilzw_encode(s));
  1242. {$else}
  1243. _mangledname:=stringdup(s);
  1244. {$endif}
  1245. include(varoptions,vo_has_mangledname);
  1246. end;
  1247. {****************************************************************************
  1248. TLOCALVARSYM
  1249. ****************************************************************************}
  1250. constructor tlocalvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1251. begin
  1252. inherited create(localvarsym,n,vsp,def,vopts);
  1253. end;
  1254. constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
  1255. begin
  1256. inherited ppuload(localvarsym,ppufile);
  1257. end;
  1258. procedure tlocalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1259. begin
  1260. inherited ppuwrite(ppufile);
  1261. ppufile.writeentry(iblocalvarsym);
  1262. end;
  1263. {****************************************************************************
  1264. TPARAVARSYM
  1265. ****************************************************************************}
  1266. constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1267. begin
  1268. inherited create(paravarsym,n,vsp,def,vopts);
  1269. if (vsp in [vs_var,vs_value,vs_const,vs_constref]) then
  1270. varstate := vs_initialised;
  1271. paranr:=nr;
  1272. paraloc[calleeside].init;
  1273. paraloc[callerside].init;
  1274. end;
  1275. destructor tparavarsym.destroy;
  1276. begin
  1277. paraloc[calleeside].done;
  1278. paraloc[callerside].done;
  1279. inherited destroy;
  1280. end;
  1281. constructor tparavarsym.ppuload(ppufile:tcompilerppufile);
  1282. var
  1283. b : byte;
  1284. begin
  1285. inherited ppuload(paravarsym,ppufile);
  1286. paranr:=ppufile.getword;
  1287. univpara:=boolean(ppufile.getbyte);
  1288. { The var state of parameter symbols is fixed after writing them so
  1289. we write them to the unit file.
  1290. This enables constant folding for inline procedures loaded from units
  1291. }
  1292. varstate:=tvarstate(ppufile.getbyte);
  1293. paraloc[calleeside].init;
  1294. paraloc[callerside].init;
  1295. if vo_has_explicit_paraloc in varoptions then
  1296. begin
  1297. paraloc[callerside].alignment:=ppufile.getbyte;
  1298. b:=ppufile.getbyte;
  1299. if b<>sizeof(paraloc[callerside].location^) then
  1300. internalerror(200411154);
  1301. ppufile.getdata(paraloc[callerside].add_location^,sizeof(paraloc[callerside].location^));
  1302. paraloc[callerside].size:=paraloc[callerside].location^.size;
  1303. paraloc[callerside].intsize:=tcgsize2size[paraloc[callerside].size];
  1304. end;
  1305. end;
  1306. procedure tparavarsym.ppuwrite(ppufile:tcompilerppufile);
  1307. var
  1308. oldintfcrc : boolean;
  1309. begin
  1310. inherited ppuwrite(ppufile);
  1311. ppufile.putword(paranr);
  1312. ppufile.putbyte(byte(univpara));
  1313. { The var state of parameter symbols is fixed after writing them so
  1314. we write them to the unit file.
  1315. This enables constant folding for inline procedures loaded from units
  1316. }
  1317. oldintfcrc:=ppufile.do_crc;
  1318. ppufile.do_crc:=false;
  1319. ppufile.putbyte(ord(varstate));
  1320. ppufile.do_crc:=oldintfcrc;
  1321. if vo_has_explicit_paraloc in varoptions then
  1322. begin
  1323. paraloc[callerside].check_simple_location;
  1324. ppufile.putbyte(sizeof(paraloc[callerside].alignment));
  1325. ppufile.putbyte(sizeof(paraloc[callerside].location^));
  1326. ppufile.putdata(paraloc[callerside].location^,sizeof(paraloc[callerside].location^));
  1327. end;
  1328. ppufile.writeentry(ibparavarsym);
  1329. end;
  1330. {****************************************************************************
  1331. TABSOLUTEVARSYM
  1332. ****************************************************************************}
  1333. constructor tabsolutevarsym.create(const n : string;def:tdef);
  1334. begin
  1335. inherited create(absolutevarsym,n,vs_value,def,[]);
  1336. ref:=nil;
  1337. end;
  1338. constructor tabsolutevarsym.create_ref(const n : string;def:tdef;_ref:tpropaccesslist);
  1339. begin
  1340. inherited create(absolutevarsym,n,vs_value,def,[]);
  1341. ref:=_ref;
  1342. end;
  1343. destructor tabsolutevarsym.destroy;
  1344. begin
  1345. if assigned(ref) then
  1346. ref.free;
  1347. inherited destroy;
  1348. end;
  1349. constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
  1350. begin
  1351. inherited ppuload(absolutevarsym,ppufile);
  1352. ref:=nil;
  1353. asmname:=nil;
  1354. abstyp:=absolutetyp(ppufile.getbyte);
  1355. {$ifdef i386}
  1356. absseg:=false;
  1357. {$endif i386}
  1358. case abstyp of
  1359. tovar :
  1360. ref:=ppufile.getpropaccesslist;
  1361. toasm :
  1362. asmname:=stringdup(ppufile.getstring);
  1363. toaddr :
  1364. begin
  1365. addroffset:=ppufile.getaword;
  1366. {$ifdef i386}
  1367. absseg:=boolean(ppufile.getbyte);
  1368. {$endif i386}
  1369. end;
  1370. end;
  1371. end;
  1372. procedure tabsolutevarsym.ppuwrite(ppufile:tcompilerppufile);
  1373. begin
  1374. inherited ppuwrite(ppufile);
  1375. ppufile.putbyte(byte(abstyp));
  1376. case abstyp of
  1377. tovar :
  1378. ppufile.putpropaccesslist(ref);
  1379. toasm :
  1380. ppufile.putstring(asmname^);
  1381. toaddr :
  1382. begin
  1383. ppufile.putaword(addroffset);
  1384. {$ifdef i386}
  1385. ppufile.putbyte(byte(absseg));
  1386. {$endif i386}
  1387. end;
  1388. end;
  1389. ppufile.writeentry(ibabsolutevarsym);
  1390. end;
  1391. procedure tabsolutevarsym.buildderef;
  1392. begin
  1393. inherited buildderef;
  1394. if (abstyp=tovar) then
  1395. ref.buildderef;
  1396. end;
  1397. procedure tabsolutevarsym.deref;
  1398. begin
  1399. inherited deref;
  1400. { own absolute deref }
  1401. if (abstyp=tovar) then
  1402. ref.resolve;
  1403. end;
  1404. function tabsolutevarsym.mangledname : string;
  1405. begin
  1406. case abstyp of
  1407. toasm :
  1408. mangledname:=asmname^;
  1409. toaddr :
  1410. mangledname:='$'+tostr(addroffset);
  1411. else
  1412. internalerror(200411062);
  1413. end;
  1414. end;
  1415. {****************************************************************************
  1416. TCONSTSYM
  1417. ****************************************************************************}
  1418. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;def:tdef);
  1419. begin
  1420. inherited create(constsym,n);
  1421. fillchar(value, sizeof(value), #0);
  1422. consttyp:=t;
  1423. value.valueord:=v;
  1424. constdef:=def;
  1425. end;
  1426. constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;def:tdef);
  1427. begin
  1428. inherited create(constsym,n);
  1429. fillchar(value, sizeof(value), #0);
  1430. consttyp:=t;
  1431. value.valueordptr:=v;
  1432. constdef:=def;
  1433. end;
  1434. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;def:tdef);
  1435. begin
  1436. inherited create(constsym,n);
  1437. fillchar(value, sizeof(value), #0);
  1438. consttyp:=t;
  1439. value.valueptr:=v;
  1440. constdef:=def;
  1441. end;
  1442. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1443. begin
  1444. inherited create(constsym,n);
  1445. fillchar(value, sizeof(value), #0);
  1446. consttyp:=t;
  1447. value.valueptr:=str;
  1448. constdef:=nil;
  1449. value.len:=l;
  1450. end;
  1451. constructor tconstsym.create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
  1452. begin
  1453. inherited create(constsym,n);
  1454. fillchar(value, sizeof(value), #0);
  1455. consttyp:=t;
  1456. pcompilerwidestring(value.valueptr):=pw;
  1457. constdef:=nil;
  1458. value.len:=getlengthwidestring(pw);
  1459. end;
  1460. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1461. var
  1462. pd : pbestreal;
  1463. ps : pnormalset;
  1464. pc : pchar;
  1465. pw : pcompilerwidestring;
  1466. i : longint;
  1467. begin
  1468. inherited ppuload(constsym,ppufile);
  1469. constdef:=nil;
  1470. consttyp:=tconsttyp(ppufile.getbyte);
  1471. fillchar(value, sizeof(value), #0);
  1472. case consttyp of
  1473. constord :
  1474. begin
  1475. ppufile.getderef(constdefderef);
  1476. value.valueord:=ppufile.getexprint;
  1477. end;
  1478. constpointer :
  1479. begin
  1480. ppufile.getderef(constdefderef);
  1481. value.valueordptr:=ppufile.getptruint;
  1482. end;
  1483. constwstring :
  1484. begin
  1485. initwidestring(pw);
  1486. setlengthwidestring(pw,ppufile.getlongint);
  1487. { don't use getdata, because the compilerwidechars may have to
  1488. be byteswapped
  1489. }
  1490. {$if sizeof(tcompilerwidechar) = 2}
  1491. for i:=0 to pw^.len-1 do
  1492. pw^.data[i]:=ppufile.getword;
  1493. {$elseif sizeof(tcompilerwidechar) = 4}
  1494. for i:=0 to pw^.len-1 do
  1495. pw^.data[i]:=cardinal(ppufile.getlongint);
  1496. {$else}
  1497. {$error Unsupported tcompilerwidechar size}
  1498. {$endif}
  1499. pcompilerwidestring(value.valueptr):=pw;
  1500. end;
  1501. conststring,
  1502. constresourcestring :
  1503. begin
  1504. value.len:=ppufile.getlongint;
  1505. getmem(pc,value.len+1);
  1506. ppufile.getdata(pc^,value.len);
  1507. pc[value.len]:=#0;
  1508. value.valueptr:=pc;
  1509. end;
  1510. constreal :
  1511. begin
  1512. new(pd);
  1513. pd^:=ppufile.getreal;
  1514. value.valueptr:=pd;
  1515. end;
  1516. constset :
  1517. begin
  1518. ppufile.getderef(constdefderef);
  1519. new(ps);
  1520. ppufile.getnormalset(ps^);
  1521. value.valueptr:=ps;
  1522. end;
  1523. constguid :
  1524. begin
  1525. new(pguid(value.valueptr));
  1526. ppufile.getdata(value.valueptr^,sizeof(tguid));
  1527. end;
  1528. constnil : ;
  1529. else
  1530. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1531. end;
  1532. end;
  1533. destructor tconstsym.destroy;
  1534. begin
  1535. case consttyp of
  1536. conststring,
  1537. constresourcestring :
  1538. freemem(pchar(value.valueptr),value.len+1);
  1539. constwstring :
  1540. donewidestring(pcompilerwidestring(value.valueptr));
  1541. constreal :
  1542. dispose(pbestreal(value.valueptr));
  1543. constset :
  1544. dispose(pnormalset(value.valueptr));
  1545. constguid :
  1546. dispose(pguid(value.valueptr));
  1547. end;
  1548. inherited destroy;
  1549. end;
  1550. procedure tconstsym.buildderef;
  1551. begin
  1552. if consttyp in [constord,constpointer,constset] then
  1553. constdefderef.build(constdef);
  1554. end;
  1555. procedure tconstsym.deref;
  1556. begin
  1557. if consttyp in [constord,constpointer,constset] then
  1558. constdef:=tdef(constdefderef.resolve);
  1559. end;
  1560. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1561. begin
  1562. inherited ppuwrite(ppufile);
  1563. ppufile.putbyte(byte(consttyp));
  1564. case consttyp of
  1565. constnil : ;
  1566. constord :
  1567. begin
  1568. ppufile.putderef(constdefderef);
  1569. ppufile.putexprint(value.valueord);
  1570. end;
  1571. constpointer :
  1572. begin
  1573. ppufile.putderef(constdefderef);
  1574. ppufile.putptruint(value.valueordptr);
  1575. end;
  1576. constwstring :
  1577. begin
  1578. ppufile.putlongint(getlengthwidestring(pcompilerwidestring(value.valueptr)));
  1579. ppufile.putdata(pcompilerwidestring(value.valueptr)^.data^,pcompilerwidestring(value.valueptr)^.len*sizeof(tcompilerwidechar));
  1580. end;
  1581. conststring,
  1582. constresourcestring :
  1583. begin
  1584. ppufile.putlongint(value.len);
  1585. ppufile.putdata(pchar(value.valueptr)^,value.len);
  1586. end;
  1587. constreal :
  1588. ppufile.putreal(pbestreal(value.valueptr)^);
  1589. constset :
  1590. begin
  1591. ppufile.putderef(constdefderef);
  1592. ppufile.putnormalset(value.valueptr^);
  1593. end;
  1594. constguid :
  1595. ppufile.putdata(value.valueptr^,sizeof(tguid));
  1596. else
  1597. internalerror(13);
  1598. end;
  1599. ppufile.writeentry(ibconstsym);
  1600. end;
  1601. {****************************************************************************
  1602. TENUMSYM
  1603. ****************************************************************************}
  1604. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1605. begin
  1606. inherited create(enumsym,n);
  1607. definition:=def;
  1608. value:=v;
  1609. end;
  1610. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  1611. begin
  1612. inherited ppuload(enumsym,ppufile);
  1613. ppufile.getderef(definitionderef);
  1614. value:=ppufile.getlongint;
  1615. end;
  1616. procedure tenumsym.buildderef;
  1617. begin
  1618. definitionderef.build(definition);
  1619. end;
  1620. procedure tenumsym.deref;
  1621. begin
  1622. definition:=tenumdef(definitionderef.resolve);
  1623. end;
  1624. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  1625. begin
  1626. inherited ppuwrite(ppufile);
  1627. ppufile.putderef(definitionderef);
  1628. ppufile.putlongint(value);
  1629. ppufile.writeentry(ibenumsym);
  1630. end;
  1631. {****************************************************************************
  1632. TTYPESYM
  1633. ****************************************************************************}
  1634. constructor ttypesym.create(const n : string;def:tdef);
  1635. begin
  1636. inherited create(typesym,n);
  1637. typedef:=def;
  1638. { register the typesym for the definition }
  1639. if assigned(typedef) and
  1640. (typedef.typ<>errordef) and
  1641. not(assigned(typedef.typesym)) then
  1642. typedef.typesym:=self;
  1643. end;
  1644. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  1645. begin
  1646. inherited ppuload(typesym,ppufile);
  1647. ppufile.getderef(typedefderef);
  1648. fprettyname:=ppufile.getansistring;
  1649. end;
  1650. procedure ttypesym.buildderef;
  1651. begin
  1652. typedefderef.build(typedef);
  1653. end;
  1654. procedure ttypesym.deref;
  1655. begin
  1656. typedef:=tdef(typedefderef.resolve);
  1657. end;
  1658. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  1659. begin
  1660. inherited ppuwrite(ppufile);
  1661. ppufile.putderef(typedefderef);
  1662. ppufile.putansistring(fprettyname);
  1663. ppufile.writeentry(ibtypesym);
  1664. end;
  1665. function ttypesym.prettyname : string;
  1666. begin
  1667. if fprettyname<>'' then
  1668. result:=fprettyname
  1669. else
  1670. result:=inherited prettyname;
  1671. end;
  1672. {****************************************************************************
  1673. TSYSSYM
  1674. ****************************************************************************}
  1675. constructor tsyssym.create(const n : string;l : longint);
  1676. begin
  1677. inherited create(syssym,n);
  1678. number:=l;
  1679. end;
  1680. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  1681. begin
  1682. inherited ppuload(syssym,ppufile);
  1683. number:=ppufile.getlongint;
  1684. end;
  1685. destructor tsyssym.destroy;
  1686. begin
  1687. inherited destroy;
  1688. end;
  1689. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  1690. begin
  1691. inherited ppuwrite(ppufile);
  1692. ppufile.putlongint(number);
  1693. ppufile.writeentry(ibsyssym);
  1694. end;
  1695. {*****************************************************************************
  1696. TMacro
  1697. *****************************************************************************}
  1698. constructor tmacro.create(const n : string);
  1699. begin
  1700. inherited create(macrosym,n);
  1701. owner:=nil;
  1702. defined:=false;
  1703. is_used:=false;
  1704. is_compiler_var:=false;
  1705. buftext:=nil;
  1706. buflen:=0;
  1707. end;
  1708. constructor tmacro.ppuload(ppufile:tcompilerppufile);
  1709. begin
  1710. inherited ppuload(macrosym,ppufile);
  1711. defined:=boolean(ppufile.getbyte);
  1712. is_compiler_var:=boolean(ppufile.getbyte);
  1713. is_used:=false;
  1714. buflen:= ppufile.getlongint;
  1715. if buflen > 0 then
  1716. begin
  1717. getmem(buftext, buflen);
  1718. ppufile.getdata(buftext^, buflen)
  1719. end
  1720. else
  1721. buftext:=nil;
  1722. end;
  1723. destructor tmacro.destroy;
  1724. begin
  1725. if assigned(buftext) then
  1726. freemem(buftext);
  1727. inherited destroy;
  1728. end;
  1729. procedure tmacro.ppuwrite(ppufile:tcompilerppufile);
  1730. begin
  1731. inherited ppuwrite(ppufile);
  1732. ppufile.putbyte(byte(defined));
  1733. ppufile.putbyte(byte(is_compiler_var));
  1734. ppufile.putlongint(buflen);
  1735. if buflen > 0 then
  1736. ppufile.putdata(buftext^,buflen);
  1737. ppufile.writeentry(ibmacrosym);
  1738. end;
  1739. function tmacro.GetCopy:tmacro;
  1740. var
  1741. p : tmacro;
  1742. begin
  1743. p:=tmacro.create(realname);
  1744. p.defined:=defined;
  1745. p.is_used:=is_used;
  1746. p.is_compiler_var:=is_compiler_var;
  1747. p.buflen:=buflen;
  1748. if assigned(buftext) then
  1749. begin
  1750. getmem(p.buftext,buflen);
  1751. move(buftext^,p.buftext^,buflen);
  1752. end;
  1753. Result:=p;
  1754. end;
  1755. end.