symsym.pas 63 KB

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