symsym.pas 62 KB

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