symsym.pas 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356
  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,
  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 : boolean;
  46. { points to the matching node, only valid resultdef pass is run and
  47. the goto<->label relation in the node tree is created, should
  48. be a tnode }
  49. code : pointer;
  50. { when the label is defined in an asm block, this points to the
  51. generated asmlabel }
  52. asmblocklabel : tasmlabel;
  53. constructor create(const n : string);
  54. constructor ppuload(ppufile:tcompilerppufile);
  55. procedure ppuwrite(ppufile:tcompilerppufile);override;
  56. function mangledname:string;override;
  57. end;
  58. tunitsym = class(Tstoredsym)
  59. module : tobject; { tmodule }
  60. constructor create(const n : string;amodule : tobject);
  61. constructor ppuload(ppufile:tcompilerppufile);
  62. destructor destroy;override;
  63. procedure ppuwrite(ppufile:tcompilerppufile);override;
  64. end;
  65. terrorsym = class(Tsym)
  66. constructor create;
  67. end;
  68. Tprocdefcallback = procedure(p:Tprocdef;arg:pointer);
  69. tprocsym = class(tstoredsym)
  70. protected
  71. pdlistfirst,
  72. pdlistlast : pprocdeflist; { linked list of overloaded procdefs }
  73. function getprocdef(nr:cardinal):Tprocdef;
  74. public
  75. procdef_count : byte;
  76. overloadchecked : boolean;
  77. property procdef[nr:cardinal]:Tprocdef read getprocdef;
  78. constructor create(const n : string);
  79. constructor ppuload(ppufile:tcompilerppufile);
  80. destructor destroy;override;
  81. { writes all declarations except the specified one }
  82. procedure write_parameter_lists(skipdef:tprocdef);
  83. { tests, if all procedures definitions are defined and not }
  84. { only forward }
  85. procedure check_forward;
  86. procedure unchain_overload;
  87. procedure ppuwrite(ppufile:tcompilerppufile);override;
  88. procedure buildderef;override;
  89. procedure deref;override;
  90. procedure addprocdef(p:tprocdef);
  91. procedure addprocdef_deref(const d:tderef);
  92. procedure add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  93. procedure concat_procdefs_to(s:Tprocsym);
  94. procedure foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  95. function first_procdef:Tprocdef;
  96. function last_procdef:Tprocdef;
  97. function search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  98. function search_procdef_bypara(para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  99. function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  100. function search_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  101. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  102. { currobjdef is the object def to assume, this is necessary for protected and
  103. private,
  104. context is the object def we're really in, this is for the strict stuff
  105. }
  106. function is_visible_for_object(currobjdef:tdef;context:tdef):boolean;override;
  107. end;
  108. ttypesym = class(Tstoredsym)
  109. typedef : tdef;
  110. typedefderef : tderef;
  111. constructor create(const n : string;def:tdef);
  112. constructor ppuload(ppufile:tcompilerppufile);
  113. procedure ppuwrite(ppufile:tcompilerppufile);override;
  114. procedure buildderef;override;
  115. procedure deref;override;
  116. function getderefdef:tdef;override;
  117. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  118. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  119. end;
  120. tabstractvarsym = class(tstoredsym)
  121. varoptions : tvaroptions;
  122. varspez : tvarspez; { sets the type of access }
  123. varregable : tvarregable;
  124. varstate : tvarstate;
  125. notifications : Tlinkedlist;
  126. constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  127. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  128. destructor destroy;override;
  129. procedure ppuwrite(ppufile:tcompilerppufile);override;
  130. procedure buildderef;override;
  131. procedure deref;override;
  132. function getsize : longint;
  133. function getpackedbitsize : longint;
  134. function is_regvar(refpara: boolean):boolean;
  135. procedure trigger_notifications(what:Tnotification_flag);
  136. function register_notification(flags:Tnotification_flags;
  137. callback:Tnotification_callback):cardinal;
  138. procedure unregister_notification(id:cardinal);
  139. private
  140. procedure setvardef(def:tdef);
  141. _vardef : tdef;
  142. vardefderef : tderef;
  143. public
  144. property vardef: tdef read _vardef write setvardef;
  145. end;
  146. tfieldvarsym = class(tabstractvarsym)
  147. fieldoffset : aint; { offset in record/object }
  148. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  149. constructor ppuload(ppufile:tcompilerppufile);
  150. procedure ppuwrite(ppufile:tcompilerppufile);override;
  151. function mangledname:string;override;
  152. end;
  153. tabstractnormalvarsym = class(tabstractvarsym)
  154. defaultconstsym : tsym;
  155. defaultconstsymderef : tderef;
  156. localloc : TLocation; { register/reference for local var }
  157. initialloc : TLocation; { initial location so it can still be initialized later after the location was changed by SSA }
  158. constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  159. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  160. procedure ppuwrite(ppufile:tcompilerppufile);override;
  161. procedure buildderef;override;
  162. procedure deref;override;
  163. end;
  164. tlocalvarsym = class(tabstractnormalvarsym)
  165. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  166. constructor ppuload(ppufile:tcompilerppufile);
  167. procedure ppuwrite(ppufile:tcompilerppufile);override;
  168. end;
  169. tparavarsym = class(tabstractnormalvarsym)
  170. paraloc : array[tcallercallee] of TCGPara;
  171. paranr : word; { position of this parameter }
  172. {$ifdef EXTDEBUG}
  173. eqval : tequaltype;
  174. {$endif EXTDEBUG}
  175. constructor create(const n : string;nr:word;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  176. constructor ppuload(ppufile:tcompilerppufile);
  177. destructor destroy;override;
  178. procedure ppuwrite(ppufile:tcompilerppufile);override;
  179. end;
  180. tglobalvarsym = class(tabstractnormalvarsym)
  181. private
  182. _mangledname : pshortstring;
  183. public
  184. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  185. constructor create_dll(const n : string;vsp:tvarspez;def:tdef);
  186. constructor create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
  187. constructor ppuload(ppufile:tcompilerppufile);
  188. destructor destroy;override;
  189. procedure ppuwrite(ppufile:tcompilerppufile);override;
  190. function mangledname:string;override;
  191. procedure set_mangledname(const s:string);
  192. end;
  193. tabsolutevarsym = class(tabstractvarsym)
  194. public
  195. abstyp : absolutetyp;
  196. {$ifdef i386}
  197. absseg : boolean;
  198. {$endif i386}
  199. asmname : pshortstring;
  200. addroffset : aint;
  201. ref : tpropaccesslist;
  202. constructor create(const n : string;def:tdef);
  203. constructor create_ref(const n : string;def:tdef;_ref:tpropaccesslist);
  204. destructor destroy;override;
  205. constructor ppuload(ppufile:tcompilerppufile);
  206. procedure buildderef;override;
  207. procedure deref;override;
  208. function mangledname : string;override;
  209. procedure ppuwrite(ppufile:tcompilerppufile);override;
  210. end;
  211. tpropaccesslisttypes=(palt_none,palt_read,palt_write,palt_stored);
  212. tpropertysym = class(Tstoredsym)
  213. propoptions : tpropertyoptions;
  214. overridenpropsym : tpropertysym;
  215. overridenpropsymderef : tderef;
  216. propdef : tdef;
  217. propdefderef : tderef;
  218. indexdef : tdef;
  219. indexdefderef : tderef;
  220. index,
  221. default : longint;
  222. propaccesslist : array[tpropaccesslisttypes] of tpropaccesslist;
  223. constructor create(const n : string);
  224. destructor destroy;override;
  225. constructor ppuload(ppufile:tcompilerppufile);
  226. function getsize : longint;
  227. procedure ppuwrite(ppufile:tcompilerppufile);override;
  228. function getderefdef:tdef;override;
  229. procedure buildderef;override;
  230. procedure deref;override;
  231. end;
  232. ttypedconstsym = class(tstoredsym)
  233. private
  234. _mangledname : pshortstring;
  235. public
  236. typedconstdef : tdef;
  237. typedconstdefderef : tderef;
  238. is_writable : boolean;
  239. constructor create(const n : string;def : tdef;writable : boolean);
  240. constructor ppuload(ppufile:tcompilerppufile);
  241. destructor destroy;override;
  242. function mangledname : string;override;
  243. procedure ppuwrite(ppufile:tcompilerppufile);override;
  244. procedure buildderef;override;
  245. procedure deref;override;
  246. function getsize:longint;
  247. procedure set_mangledname(const s:string);
  248. end;
  249. tconstvalue = record
  250. case integer of
  251. 0: (valueord : tconstexprint);
  252. 1: (valueordptr : tconstptruint);
  253. 2: (valueptr : pointer; len : longint);
  254. end;
  255. tconstsym = class(tstoredsym)
  256. constdef : tdef;
  257. constdefderef : tderef;
  258. consttyp : tconsttyp;
  259. value : tconstvalue;
  260. resstrindex : longint; { needed for resource strings }
  261. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint;def:tdef);
  262. constructor create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;def:tdef);
  263. constructor create_ptr(const n : string;t : tconsttyp;v : pointer;def:tdef);
  264. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  265. constructor create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
  266. constructor ppuload(ppufile:tcompilerppufile);
  267. destructor destroy;override;
  268. procedure buildderef;override;
  269. procedure deref;override;
  270. procedure ppuwrite(ppufile:tcompilerppufile);override;
  271. end;
  272. tenumsym = class(Tstoredsym)
  273. value : longint;
  274. definition : tenumdef;
  275. definitionderef : tderef;
  276. nextenum : tenumsym;
  277. constructor create(const n : string;def : tenumdef;v : longint);
  278. constructor ppuload(ppufile:tcompilerppufile);
  279. procedure ppuwrite(ppufile:tcompilerppufile);override;
  280. procedure buildderef;override;
  281. procedure deref;override;
  282. procedure order;
  283. end;
  284. tsyssym = class(Tstoredsym)
  285. number : longint;
  286. constructor create(const n : string;l : longint);
  287. constructor ppuload(ppufile:tcompilerppufile);
  288. destructor destroy;override;
  289. procedure ppuwrite(ppufile:tcompilerppufile);override;
  290. end;
  291. const
  292. maxmacrolen=16*1024;
  293. type
  294. pmacrobuffer = ^tmacrobuffer;
  295. tmacrobuffer = array[0..maxmacrolen-1] of char;
  296. tmacro = class(tstoredsym)
  297. {Normally true, but false when a previously defined macro is undef-ed}
  298. defined : boolean;
  299. {True if this is a mac style compiler variable, in which case no macro
  300. substitutions shall be done.}
  301. is_compiler_var : boolean;
  302. {Whether the macro was used. NOTE: A use of a macro which was never defined}
  303. {e. g. an IFDEF which returns false, will not be registered as used,}
  304. {since there is no place to register its use. }
  305. is_used : boolean;
  306. buftext : pchar;
  307. buflen : longint;
  308. constructor create(const n : string);
  309. constructor ppuload(ppufile:tcompilerppufile);
  310. procedure ppuwrite(ppufile:tcompilerppufile);override;
  311. destructor destroy;override;
  312. function GetCopy:tmacro;
  313. end;
  314. { compiler generated symbol to point to rtti and init/finalize tables }
  315. trttisym = class(tstoredsym)
  316. private
  317. _mangledname : pshortstring;
  318. public
  319. lab : tasmsymbol;
  320. rttityp : trttitype;
  321. constructor create(const n:string;rt:trttitype);
  322. constructor ppuload(ppufile:tcompilerppufile);
  323. destructor destroy;override;
  324. procedure ppuwrite(ppufile:tcompilerppufile);override;
  325. function mangledname:string;override;
  326. function get_label:tasmsymbol;
  327. end;
  328. var
  329. generrorsym : tsym;
  330. implementation
  331. uses
  332. { global }
  333. verbose,
  334. { target }
  335. systems,
  336. { symtable }
  337. defutil,symtable,
  338. fmodule,
  339. { tree }
  340. node,
  341. { aasm }
  342. aasmtai,aasmdata,
  343. { codegen }
  344. paramgr,
  345. procinfo
  346. ;
  347. {****************************************************************************
  348. Helpers
  349. ****************************************************************************}
  350. {****************************************************************************
  351. TSYM (base for all symtypes)
  352. ****************************************************************************}
  353. constructor tstoredsym.create(st:tsymtyp;const n : string);
  354. begin
  355. inherited create(st,n);
  356. { Register in current_module }
  357. if assigned(current_module) then
  358. begin
  359. current_module.symlist.Add(self);
  360. SymId:=current_module.symlist.Count-1;
  361. end;
  362. end;
  363. constructor tstoredsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  364. var
  365. nr : word;
  366. s : string;
  367. begin
  368. SymId:=ppufile.getlongint;
  369. current_module.symlist[SymId]:=self;
  370. nr:=ppufile.getword;
  371. s:=ppufile.getstring;
  372. if s[1]='$' then
  373. inherited createname(copy(s,2,255))
  374. else
  375. inherited createname(upper(s));
  376. _realname:=stringdup(s);
  377. typ:=st;
  378. { force the correct indexnr. must be after create! }
  379. indexnr:=nr;
  380. ppufile.getposinfo(fileinfo);
  381. ppufile.getsmallset(symoptions);
  382. lastref:=nil;
  383. defref:=nil;
  384. refs:=0;
  385. lastwritten:=nil;
  386. refcount:=0;
  387. isdbgwritten := false;
  388. end;
  389. procedure tstoredsym.ppuwrite(ppufile:tcompilerppufile);
  390. begin
  391. ppufile.putlongint(SymId);
  392. ppufile.putword(indexnr);
  393. ppufile.putstring(_realname^);
  394. ppufile.putposinfo(fileinfo);
  395. ppufile.putsmallset(symoptions);
  396. end;
  397. destructor tstoredsym.destroy;
  398. begin
  399. if assigned(defref) then
  400. begin
  401. {$ifdef MEMDEBUG}
  402. membrowser.start;
  403. {$endif MEMDEBUG}
  404. defref.freechain;
  405. defref.free;
  406. {$ifdef MEMDEBUG}
  407. membrowser.stop;
  408. {$endif MEMDEBUG}
  409. end;
  410. inherited destroy;
  411. end;
  412. {****************************************************************************
  413. TLABELSYM
  414. ****************************************************************************}
  415. constructor tlabelsym.create(const n : string);
  416. begin
  417. inherited create(labelsym,n);
  418. used:=false;
  419. defined:=false;
  420. code:=nil;
  421. end;
  422. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  423. begin
  424. inherited ppuload(labelsym,ppufile);
  425. code:=nil;
  426. used:=false;
  427. defined:=true;
  428. end;
  429. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  430. begin
  431. if owner.symtabletype=globalsymtable then
  432. Message(sym_e_ill_label_decl)
  433. else
  434. begin
  435. inherited ppuwrite(ppufile);
  436. ppufile.writeentry(iblabelsym);
  437. end;
  438. end;
  439. function tlabelsym.mangledname:string;
  440. begin
  441. if not(defined) then
  442. begin
  443. defined:=true;
  444. current_asmdata.getjumplabel(asmblocklabel);
  445. end;
  446. result:=asmblocklabel.getname;
  447. end;
  448. {****************************************************************************
  449. TUNITSYM
  450. ****************************************************************************}
  451. constructor tunitsym.create(const n : string;amodule : tobject);
  452. var
  453. old_make_ref : boolean;
  454. begin
  455. old_make_ref:=make_ref;
  456. make_ref:=false;
  457. inherited create(unitsym,n);
  458. make_ref:=old_make_ref;
  459. module:=amodule;
  460. end;
  461. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  462. begin
  463. inherited ppuload(unitsym,ppufile);
  464. module:=nil;
  465. end;
  466. destructor tunitsym.destroy;
  467. begin
  468. inherited destroy;
  469. end;
  470. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  471. begin
  472. inherited ppuwrite(ppufile);
  473. ppufile.writeentry(ibunitsym);
  474. end;
  475. {****************************************************************************
  476. TPROCSYM
  477. ****************************************************************************}
  478. constructor tprocsym.create(const n : string);
  479. begin
  480. inherited create(procsym,n);
  481. pdlistfirst:=nil;
  482. pdlistlast:=nil;
  483. { the tprocdef have their own symoptions, make the procsym
  484. always visible }
  485. symoptions:=[sp_public];
  486. overloadchecked:=false;
  487. procdef_count:=0;
  488. end;
  489. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  490. var
  491. pdderef : tderef;
  492. i,n : longint;
  493. begin
  494. inherited ppuload(procsym,ppufile);
  495. pdlistfirst:=nil;
  496. pdlistlast:=nil;
  497. procdef_count:=0;
  498. n:=ppufile.getword;
  499. for i:=1to n do
  500. begin
  501. ppufile.getderef(pdderef);
  502. addprocdef_deref(pdderef);
  503. end;
  504. overloadchecked:=false;
  505. end;
  506. destructor tprocsym.destroy;
  507. var
  508. hp,p : pprocdeflist;
  509. begin
  510. p:=pdlistfirst;
  511. while assigned(p) do
  512. begin
  513. hp:=p^.next;
  514. dispose(p);
  515. p:=hp;
  516. end;
  517. inherited destroy;
  518. end;
  519. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  520. var
  521. p : pprocdeflist;
  522. n : word;
  523. begin
  524. inherited ppuwrite(ppufile);
  525. { count procdefs }
  526. n:=0;
  527. p:=pdlistfirst;
  528. while assigned(p) do
  529. begin
  530. { only write the proc definitions that belong
  531. to this procsym and are in the global symtable }
  532. if p^.def.owner=owner then
  533. inc(n);
  534. p:=p^.next;
  535. end;
  536. ppufile.putword(n);
  537. { write procdefs }
  538. p:=pdlistfirst;
  539. while assigned(p) do
  540. begin
  541. { only write the proc definitions that belong
  542. to this procsym and are in the global symtable }
  543. if p^.def.owner=owner then
  544. ppufile.putderef(p^.defderef);
  545. p:=p^.next;
  546. end;
  547. ppufile.writeentry(ibprocsym);
  548. end;
  549. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  550. var
  551. p : pprocdeflist;
  552. begin
  553. p:=pdlistfirst;
  554. while assigned(p) do
  555. begin
  556. if p^.def<>skipdef then
  557. MessagePos1(p^.def.fileinfo,sym_h_param_list,p^.def.fullprocname(false));
  558. p:=p^.next;
  559. end;
  560. end;
  561. {Makes implicit externals (procedures declared in the interface
  562. section which do not have a counterpart in the implementation)
  563. to be an imported procedure. For mode macpas.}
  564. procedure import_implict_external(pd:tabstractprocdef);
  565. begin
  566. tprocdef(pd).forwarddef:=false;
  567. tprocdef(pd).setmangledname(target_info.CPrefix+tprocdef(pd).procsym.realname);
  568. end;
  569. procedure tprocsym.check_forward;
  570. var
  571. p : pprocdeflist;
  572. begin
  573. p:=pdlistfirst;
  574. while assigned(p) do
  575. begin
  576. if (p^.def.owner=owner) and (p^.def.forwarddef) then
  577. begin
  578. if (m_mac in current_settings.modeswitches) and (p^.def.interfacedef) then
  579. import_implict_external(p^.def)
  580. else
  581. begin
  582. MessagePos1(p^.def.fileinfo,sym_e_forward_not_resolved,p^.def.fullprocname(false));
  583. { Turn further error messages off }
  584. p^.def.forwarddef:=false;
  585. end
  586. end;
  587. p:=p^.next;
  588. end;
  589. end;
  590. procedure tprocsym.buildderef;
  591. var
  592. p : pprocdeflist;
  593. begin
  594. p:=pdlistfirst;
  595. while assigned(p) do
  596. begin
  597. if p^.def.owner=owner then
  598. p^.defderef.build(p^.def);
  599. p:=p^.next;
  600. end;
  601. end;
  602. procedure tprocsym.deref;
  603. var
  604. p : pprocdeflist;
  605. begin
  606. { We have removed the overloaded entries, because they
  607. are not valid anymore and we can't deref them because
  608. the unit were they come from is not necessary in
  609. our uses clause (PFV) }
  610. unchain_overload;
  611. { Deref our own procdefs }
  612. p:=pdlistfirst;
  613. while assigned(p) do
  614. begin
  615. if not(
  616. (p^.def=nil) or
  617. (p^.def.owner=owner)
  618. ) then
  619. internalerror(200310291);
  620. p^.def:=tprocdef(p^.defderef.resolve);
  621. p:=p^.next;
  622. end;
  623. end;
  624. procedure tprocsym.addprocdef(p:tprocdef);
  625. var
  626. pd : pprocdeflist;
  627. begin
  628. new(pd);
  629. pd^.def:=p;
  630. pd^.defderef.reset;
  631. pd^.next:=nil;
  632. { Add at end of list to keep always
  633. a correct order, also after loading from ppu }
  634. if assigned(pdlistlast) then
  635. begin
  636. pdlistlast^.next:=pd;
  637. pdlistlast:=pd;
  638. end
  639. else
  640. begin
  641. pdlistfirst:=pd;
  642. pdlistlast:=pd;
  643. end;
  644. inc(procdef_count);
  645. end;
  646. procedure tprocsym.addprocdef_deref(const d:tderef);
  647. var
  648. pd : pprocdeflist;
  649. begin
  650. new(pd);
  651. pd^.def:=nil;
  652. pd^.defderef:=d;
  653. pd^.next:=nil;
  654. { Add at end of list to keep always
  655. a correct order, also after loading from ppu }
  656. if assigned(pdlistlast) then
  657. begin
  658. pdlistlast^.next:=pd;
  659. pdlistlast:=pd;
  660. end
  661. else
  662. begin
  663. pdlistfirst:=pd;
  664. pdlistlast:=pd;
  665. end;
  666. inc(procdef_count);
  667. end;
  668. function Tprocsym.getprocdef(nr:cardinal):Tprocdef;
  669. var
  670. i : cardinal;
  671. pd : pprocdeflist;
  672. begin
  673. pd:=pdlistfirst;
  674. for i:=2 to nr do
  675. begin
  676. if not assigned(pd) then
  677. internalerror(200209051);
  678. pd:=pd^.next;
  679. end;
  680. getprocdef:=pd^.def;
  681. end;
  682. procedure Tprocsym.add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  683. var
  684. pd:pprocdeflist;
  685. begin
  686. pd:=pdlistfirst;
  687. while assigned(pd) do
  688. begin
  689. if Aprocsym.search_procdef_bypara(pd^.def.paras,nil,cpoptions)=nil then
  690. Aprocsym.addprocdef(pd^.def);
  691. pd:=pd^.next;
  692. end;
  693. end;
  694. procedure Tprocsym.concat_procdefs_to(s:Tprocsym);
  695. var
  696. pd : pprocdeflist;
  697. begin
  698. pd:=pdlistfirst;
  699. while assigned(pd) do
  700. begin
  701. s.addprocdef(pd^.def);
  702. pd:=pd^.next;
  703. end;
  704. end;
  705. function Tprocsym.first_procdef:Tprocdef;
  706. begin
  707. if assigned(pdlistfirst) then
  708. first_procdef:=pdlistfirst^.def
  709. else
  710. first_procdef:=nil;
  711. end;
  712. function Tprocsym.last_procdef:Tprocdef;
  713. begin
  714. if assigned(pdlistlast) then
  715. last_procdef:=pdlistlast^.def
  716. else
  717. last_procdef:=nil;
  718. end;
  719. procedure Tprocsym.foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  720. var
  721. p : pprocdeflist;
  722. begin
  723. p:=pdlistfirst;
  724. while assigned(p) do
  725. begin
  726. proc2call(p^.def,arg);
  727. p:=p^.next;
  728. end;
  729. end;
  730. function Tprocsym.search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  731. var
  732. p : pprocdeflist;
  733. begin
  734. search_procdef_bytype:=nil;
  735. p:=pdlistfirst;
  736. while p<>nil do
  737. begin
  738. if p^.def.proctypeoption=pt then
  739. begin
  740. search_procdef_bytype:=p^.def;
  741. break;
  742. end;
  743. p:=p^.next;
  744. end;
  745. end;
  746. function Tprocsym.search_procdef_bypara(para:TFPObjectList;retdef:tdef;
  747. cpoptions:tcompare_paras_options):Tprocdef;
  748. var
  749. pd : pprocdeflist;
  750. eq : tequaltype;
  751. begin
  752. search_procdef_bypara:=nil;
  753. pd:=pdlistfirst;
  754. while assigned(pd) do
  755. begin
  756. if assigned(retdef) then
  757. eq:=compare_defs(retdef,pd^.def.returndef,nothingn)
  758. else
  759. eq:=te_equal;
  760. if (eq>=te_equal) or
  761. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  762. begin
  763. eq:=compare_paras(para,pd^.def.paras,cp_value_equal_const,cpoptions);
  764. if (eq>=te_equal) or
  765. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  766. begin
  767. search_procdef_bypara:=pd^.def;
  768. break;
  769. end;
  770. end;
  771. pd:=pd^.next;
  772. end;
  773. end;
  774. function Tprocsym.search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  775. var
  776. pd : pprocdeflist;
  777. eq,besteq : tequaltype;
  778. bestpd : tprocdef;
  779. begin
  780. { This function will return the pprocdef of pprocsym that
  781. is the best match for procvardef. When there are multiple
  782. matches it returns nil.}
  783. search_procdef_byprocvardef:=nil;
  784. bestpd:=nil;
  785. besteq:=te_incompatible;
  786. pd:=pdlistfirst;
  787. while assigned(pd) do
  788. begin
  789. eq:=proc_to_procvar_equal(pd^.def,d);
  790. if eq>=te_equal then
  791. begin
  792. { multiple procvars with the same equal level }
  793. if assigned(bestpd) and
  794. (besteq=eq) then
  795. exit;
  796. if eq>besteq then
  797. begin
  798. besteq:=eq;
  799. bestpd:=pd^.def;
  800. end;
  801. end;
  802. pd:=pd^.next;
  803. end;
  804. search_procdef_byprocvardef:=bestpd;
  805. end;
  806. function Tprocsym.search_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  807. var
  808. convtyp : tconverttype;
  809. pd : pprocdeflist;
  810. bestpd : tprocdef;
  811. eq : tequaltype;
  812. hpd : tprocdef;
  813. i : byte;
  814. begin
  815. result:=nil;
  816. bestpd:=nil;
  817. besteq:=te_incompatible;
  818. pd:=pdlistfirst;
  819. while assigned(pd) do
  820. begin
  821. if equal_defs(todef,pd^.def.returndef) and
  822. { the result type must be always really equal and not an alias,
  823. if you mess with this code, check tw4093 }
  824. ((todef=pd^.def.returndef) or
  825. (
  826. not(df_unique in todef.defoptions) and
  827. not(df_unique in pd^.def.returndef.defoptions)
  828. )
  829. ) then
  830. begin
  831. i:=0;
  832. { ignore vs_hidden parameters }
  833. while (i<pd^.def.paras.count) and
  834. assigned(pd^.def.paras[i]) and
  835. (vo_is_hidden_para in tparavarsym(pd^.def.paras[i]).varoptions) do
  836. inc(i);
  837. if (i<pd^.def.paras.count) and
  838. assigned(pd^.def.paras[i]) then
  839. begin
  840. eq:=compare_defs_ext(fromdef,tparavarsym(pd^.def.paras[i]).vardef,nothingn,convtyp,hpd,[]);
  841. { alias? if yes, only l1 choice,
  842. if you mess with this code, check tw4093 }
  843. if (eq=te_exact) and
  844. (fromdef<>tparavarsym(pd^.def.paras[i]).vardef) and
  845. ((df_unique in fromdef.defoptions) or
  846. (df_unique in tparavarsym(pd^.def.paras[i]).vardef.defoptions)) then
  847. eq:=te_convert_l1;
  848. if eq=te_exact then
  849. begin
  850. besteq:=eq;
  851. result:=pd^.def;
  852. exit;
  853. end;
  854. if eq>besteq then
  855. begin
  856. bestpd:=pd^.def;
  857. besteq:=eq;
  858. end;
  859. end;
  860. end;
  861. pd:=pd^.next;
  862. end;
  863. result:=bestpd;
  864. end;
  865. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  866. var
  867. p : pprocdeflist;
  868. begin
  869. write_references:=false;
  870. if not inherited write_references(ppufile,locals) then
  871. exit;
  872. write_references:=true;
  873. p:=pdlistfirst;
  874. while assigned(p) do
  875. begin
  876. if p^.def.owner=owner then
  877. p^.def.write_references(ppufile,locals);
  878. p:=p^.next;
  879. end;
  880. end;
  881. procedure tprocsym.unchain_overload;
  882. var
  883. p,hp : pprocdeflist;
  884. begin
  885. { remove all overloaded procdefs from the
  886. procdeflist that are not in the current symtable }
  887. overloadchecked:=false;
  888. p:=pdlistfirst;
  889. { reset new lists }
  890. pdlistfirst:=nil;
  891. pdlistlast:=nil;
  892. while assigned(p) do
  893. begin
  894. hp:=p^.next;
  895. { only keep the proc definitions:
  896. - are not deref'd (def=nil)
  897. - are in the same symtable as the procsym (for example both
  898. are in the staticsymtable) }
  899. if (p^.def=nil) or
  900. (p^.def.owner=owner) then
  901. begin
  902. { keep, add to list }
  903. if assigned(pdlistlast) then
  904. begin
  905. pdlistlast^.next:=p;
  906. pdlistlast:=p;
  907. end
  908. else
  909. begin
  910. pdlistfirst:=p;
  911. pdlistlast:=p;
  912. end;
  913. p^.next:=nil;
  914. end
  915. else
  916. begin
  917. { remove }
  918. dispose(p);
  919. dec(procdef_count);
  920. end;
  921. p:=hp;
  922. end;
  923. end;
  924. function tprocsym.is_visible_for_object(currobjdef:tdef;context:tdef):boolean;
  925. var
  926. p : pprocdeflist;
  927. begin
  928. { This procsym is visible, when there is at least
  929. one of the procdefs visible }
  930. result:=false;
  931. p:=pdlistfirst;
  932. while assigned(p) do
  933. begin
  934. if (p^.def.owner=owner) and
  935. p^.def.is_visible_for_object(tobjectdef(currobjdef),tobjectdef(context)) then
  936. begin
  937. result:=true;
  938. exit;
  939. end;
  940. p:=p^.next;
  941. end;
  942. end;
  943. {****************************************************************************
  944. TERRORSYM
  945. ****************************************************************************}
  946. constructor terrorsym.create;
  947. begin
  948. inherited create(errorsym,'');
  949. end;
  950. {****************************************************************************
  951. TPROPERTYSYM
  952. ****************************************************************************}
  953. constructor tpropertysym.create(const n : string);
  954. var
  955. pap : tpropaccesslisttypes;
  956. begin
  957. inherited create(propertysym,n);
  958. propoptions:=[];
  959. index:=0;
  960. default:=0;
  961. propdef:=nil;
  962. indexdef:=nil;
  963. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  964. propaccesslist[pap]:=tpropaccesslist.create;
  965. end;
  966. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  967. var
  968. pap : tpropaccesslisttypes;
  969. begin
  970. inherited ppuload(propertysym,ppufile);
  971. ppufile.getsmallset(propoptions);
  972. ppufile.getderef(overridenpropsymderef);
  973. ppufile.getderef(propdefderef);
  974. index:=ppufile.getlongint;
  975. default:=ppufile.getlongint;
  976. ppufile.getderef(indexdefderef);
  977. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  978. propaccesslist[pap]:=ppufile.getpropaccesslist;
  979. end;
  980. destructor tpropertysym.destroy;
  981. var
  982. pap : tpropaccesslisttypes;
  983. begin
  984. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  985. propaccesslist[pap].free;
  986. inherited destroy;
  987. end;
  988. function tpropertysym.getderefdef:tdef;
  989. begin
  990. result:=propdef;
  991. end;
  992. procedure tpropertysym.buildderef;
  993. var
  994. pap : tpropaccesslisttypes;
  995. begin
  996. overridenpropsymderef.build(overridenpropsym);
  997. propdefderef.build(propdef);
  998. indexdefderef.build(indexdef);
  999. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  1000. propaccesslist[pap].buildderef;
  1001. end;
  1002. procedure tpropertysym.deref;
  1003. var
  1004. pap : tpropaccesslisttypes;
  1005. begin
  1006. overridenpropsym:=tpropertysym(overridenpropsymderef.resolve);
  1007. indexdef:=tdef(indexdefderef.resolve);
  1008. propdef:=tdef(propdefderef.resolve);
  1009. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  1010. propaccesslist[pap].resolve;
  1011. end;
  1012. function tpropertysym.getsize : longint;
  1013. begin
  1014. getsize:=0;
  1015. end;
  1016. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  1017. var
  1018. pap : tpropaccesslisttypes;
  1019. begin
  1020. inherited ppuwrite(ppufile);
  1021. ppufile.putsmallset(propoptions);
  1022. ppufile.putderef(overridenpropsymderef);
  1023. ppufile.putderef(propdefderef);
  1024. ppufile.putlongint(index);
  1025. ppufile.putlongint(default);
  1026. ppufile.putderef(indexdefderef);
  1027. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  1028. ppufile.putpropaccesslist(propaccesslist[pap]);
  1029. ppufile.writeentry(ibpropertysym);
  1030. end;
  1031. {****************************************************************************
  1032. TABSTRACTVARSYM
  1033. ****************************************************************************}
  1034. constructor tabstractvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1035. begin
  1036. inherited create(st,n);
  1037. vardef:=def;
  1038. varspez:=vsp;
  1039. varstate:=vs_declared;
  1040. varoptions:=vopts;
  1041. end;
  1042. constructor tabstractvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  1043. begin
  1044. inherited ppuload(st,ppufile);
  1045. varstate:=vs_readwritten;
  1046. varspez:=tvarspez(ppufile.getbyte);
  1047. varregable:=tvarregable(ppufile.getbyte);
  1048. ppufile.getderef(vardefderef);
  1049. ppufile.getsmallset(varoptions);
  1050. end;
  1051. destructor tabstractvarsym.destroy;
  1052. begin
  1053. if assigned(notifications) then
  1054. notifications.destroy;
  1055. inherited destroy;
  1056. end;
  1057. procedure tabstractvarsym.buildderef;
  1058. begin
  1059. vardefderef.build(vardef);
  1060. end;
  1061. procedure tabstractvarsym.deref;
  1062. begin
  1063. vardef:=tdef(vardefderef.resolve);
  1064. end;
  1065. procedure tabstractvarsym.ppuwrite(ppufile:tcompilerppufile);
  1066. var
  1067. oldintfcrc : boolean;
  1068. begin
  1069. inherited ppuwrite(ppufile);
  1070. ppufile.putbyte(byte(varspez));
  1071. oldintfcrc:=ppufile.do_crc;
  1072. ppufile.do_crc:=false;
  1073. ppufile.putbyte(byte(varregable));
  1074. ppufile.do_crc:=oldintfcrc;
  1075. ppufile.putderef(vardefderef);
  1076. ppufile.putsmallset(varoptions);
  1077. end;
  1078. function tabstractvarsym.getsize : longint;
  1079. begin
  1080. if assigned(vardef) and
  1081. ((vardef.deftype<>arraydef) or
  1082. is_dynamic_array(vardef) or
  1083. (tarraydef(vardef).highrange>=tarraydef(vardef).lowrange)) then
  1084. result:=vardef.size
  1085. else
  1086. result:=0;
  1087. end;
  1088. function tabstractvarsym.getpackedbitsize : longint;
  1089. begin
  1090. { bitpacking is only done for ordinals }
  1091. if not is_ordinal(vardef) then
  1092. internalerror(2006082010);
  1093. result:=vardef.packedbitsize;
  1094. end;
  1095. function tabstractvarsym.is_regvar(refpara: boolean):boolean;
  1096. begin
  1097. { Register variables are not allowed in the following cases:
  1098. - regvars are disabled
  1099. - exceptions are used (after an exception is raised the contents of the
  1100. registers is not valid anymore)
  1101. - it has a local copy
  1102. - the value needs to be in memory (i.e. reference counted) }
  1103. result:=(cs_opt_regvar in current_settings.optimizerswitches) and
  1104. not(pi_has_assembler_block in current_procinfo.flags) and
  1105. not(pi_uses_exceptions in current_procinfo.flags) and
  1106. not(vo_has_local_copy in varoptions) and
  1107. ((refpara and
  1108. (varregable <> vr_none)) or
  1109. (not refpara and
  1110. not(varregable in [vr_none,vr_addr])))
  1111. {$if not defined(powerpc) and not defined(powerpc64)}
  1112. and ((vardef.deftype <> recorddef) or
  1113. (varregable = vr_addr) or
  1114. not(varstate in [vs_written,vs_readwritten]));
  1115. {$endif}
  1116. end;
  1117. procedure tabstractvarsym.trigger_notifications(what:Tnotification_flag);
  1118. var n:Tnotification;
  1119. begin
  1120. if assigned(notifications) then
  1121. begin
  1122. n:=Tnotification(notifications.first);
  1123. while assigned(n) do
  1124. begin
  1125. if what in n.flags then
  1126. n.callback(what,self);
  1127. n:=Tnotification(n.next);
  1128. end;
  1129. end;
  1130. end;
  1131. function Tabstractvarsym.register_notification(flags:Tnotification_flags;callback:
  1132. Tnotification_callback):cardinal;
  1133. var n:Tnotification;
  1134. begin
  1135. if not assigned(notifications) then
  1136. notifications:=Tlinkedlist.create;
  1137. n:=Tnotification.create(flags,callback);
  1138. register_notification:=n.id;
  1139. notifications.concat(n);
  1140. end;
  1141. procedure Tabstractvarsym.unregister_notification(id:cardinal);
  1142. var n:Tnotification;
  1143. begin
  1144. if not assigned(notifications) then
  1145. internalerror(200212311)
  1146. else
  1147. begin
  1148. n:=Tnotification(notifications.first);
  1149. while assigned(n) do
  1150. begin
  1151. if n.id=id then
  1152. begin
  1153. notifications.remove(n);
  1154. n.destroy;
  1155. exit;
  1156. end;
  1157. n:=Tnotification(n.next);
  1158. end;
  1159. internalerror(200212311)
  1160. end;
  1161. end;
  1162. procedure tabstractvarsym.setvardef(def:tdef);
  1163. begin
  1164. _vardef := def;
  1165. { can we load the value into a register ? }
  1166. if not assigned(owner) or
  1167. (owner.symtabletype in [localsymtable,parasymtable]) or
  1168. (
  1169. (owner.symtabletype=staticsymtable) and
  1170. not(cs_create_pic in current_settings.moduleswitches)
  1171. ) then
  1172. begin
  1173. if tstoreddef(vardef).is_intregable then
  1174. varregable:=vr_intreg
  1175. else
  1176. { $warning TODO: no fpu regvar in staticsymtable yet, need initialization with 0 }
  1177. if {(
  1178. not assigned(owner) or
  1179. (owner.symtabletype<>staticsymtable)
  1180. ) and }
  1181. tstoreddef(vardef).is_fpuregable then
  1182. begin
  1183. {$ifdef x86}
  1184. if use_sse(vardef) then
  1185. varregable:=vr_mmreg
  1186. else
  1187. {$else x86}
  1188. varregable:=vr_fpureg;
  1189. {$endif x86}
  1190. end;
  1191. end;
  1192. end;
  1193. {****************************************************************************
  1194. TFIELDVARSYM
  1195. ****************************************************************************}
  1196. constructor tfieldvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1197. begin
  1198. inherited create(fieldvarsym,n,vsp,def,vopts);
  1199. fieldoffset:=-1;
  1200. end;
  1201. constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
  1202. begin
  1203. inherited ppuload(fieldvarsym,ppufile);
  1204. fieldoffset:=ppufile.getaint;
  1205. end;
  1206. procedure tfieldvarsym.ppuwrite(ppufile:tcompilerppufile);
  1207. begin
  1208. inherited ppuwrite(ppufile);
  1209. ppufile.putaint(fieldoffset);
  1210. ppufile.writeentry(ibfieldvarsym);
  1211. end;
  1212. function tfieldvarsym.mangledname:string;
  1213. var
  1214. srsym : tsym;
  1215. srsymtable : tsymtable;
  1216. begin
  1217. if sp_static in symoptions then
  1218. begin
  1219. searchsym(lower(owner.name^)+'_'+name,srsym,srsymtable);
  1220. if assigned(srsym) then
  1221. result:=srsym.mangledname;
  1222. end
  1223. else
  1224. result:=inherited mangledname;
  1225. end;
  1226. {****************************************************************************
  1227. TABSTRACTNORMALVARSYM
  1228. ****************************************************************************}
  1229. constructor tabstractnormalvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1230. begin
  1231. inherited create(st,n,vsp,def,vopts);
  1232. fillchar(localloc,sizeof(localloc),0);
  1233. fillchar(initialloc,sizeof(initialloc),0);
  1234. defaultconstsym:=nil;
  1235. end;
  1236. constructor tabstractnormalvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  1237. begin
  1238. inherited ppuload(st,ppufile);
  1239. fillchar(localloc,sizeof(localloc),0);
  1240. fillchar(initialloc,sizeof(initialloc),0);
  1241. ppufile.getderef(defaultconstsymderef);
  1242. end;
  1243. procedure tabstractnormalvarsym.buildderef;
  1244. begin
  1245. inherited buildderef;
  1246. defaultconstsymderef.build(defaultconstsym);
  1247. end;
  1248. procedure tabstractnormalvarsym.deref;
  1249. begin
  1250. inherited deref;
  1251. defaultconstsym:=tsym(defaultconstsymderef.resolve);
  1252. end;
  1253. procedure tabstractnormalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1254. begin
  1255. inherited ppuwrite(ppufile);
  1256. ppufile.putderef(defaultconstsymderef);
  1257. end;
  1258. {****************************************************************************
  1259. TGLOBALVARSYM
  1260. ****************************************************************************}
  1261. constructor tglobalvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1262. begin
  1263. inherited create(globalvarsym,n,vsp,def,vopts);
  1264. _mangledname:=nil;
  1265. end;
  1266. constructor tglobalvarsym.create_dll(const n : string;vsp:tvarspez;def:tdef);
  1267. begin
  1268. tglobalvarsym(self).create(n,vsp,def,[vo_is_dll_var]);
  1269. end;
  1270. constructor tglobalvarsym.create_C(const n,mangled : string;vsp:tvarspez;def:tdef);
  1271. begin
  1272. tglobalvarsym(self).create(n,vsp,def,[]);
  1273. set_mangledname(mangled);
  1274. end;
  1275. constructor tglobalvarsym.ppuload(ppufile:tcompilerppufile);
  1276. begin
  1277. inherited ppuload(globalvarsym,ppufile);
  1278. if vo_has_mangledname in varoptions then
  1279. _mangledname:=stringdup(ppufile.getstring)
  1280. else
  1281. _mangledname:=nil;
  1282. end;
  1283. destructor tglobalvarsym.destroy;
  1284. begin
  1285. if assigned(_mangledname) then
  1286. begin
  1287. {$ifdef MEMDEBUG}
  1288. memmanglednames.start;
  1289. {$endif MEMDEBUG}
  1290. stringdispose(_mangledname);
  1291. {$ifdef MEMDEBUG}
  1292. memmanglednames.stop;
  1293. {$endif MEMDEBUG}
  1294. end;
  1295. inherited destroy;
  1296. end;
  1297. procedure tglobalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1298. begin
  1299. inherited ppuwrite(ppufile);
  1300. if vo_has_mangledname in varoptions then
  1301. ppufile.putstring(_mangledname^);
  1302. ppufile.writeentry(ibglobalvarsym);
  1303. end;
  1304. function tglobalvarsym.mangledname:string;
  1305. begin
  1306. if not assigned(_mangledname) then
  1307. begin
  1308. {$ifdef compress}
  1309. _mangledname:=stringdup(minilzw_encode(make_mangledname('U',owner,name)));
  1310. {$else}
  1311. _mangledname:=stringdup(make_mangledname('U',owner,name));
  1312. {$endif}
  1313. end;
  1314. result:=_mangledname^;
  1315. end;
  1316. procedure tglobalvarsym.set_mangledname(const s:string);
  1317. begin
  1318. stringdispose(_mangledname);
  1319. {$ifdef compress}
  1320. _mangledname:=stringdup(minilzw_encode(s));
  1321. {$else}
  1322. _mangledname:=stringdup(s);
  1323. {$endif}
  1324. include(varoptions,vo_has_mangledname);
  1325. end;
  1326. {****************************************************************************
  1327. TLOCALVARSYM
  1328. ****************************************************************************}
  1329. constructor tlocalvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1330. begin
  1331. inherited create(localvarsym,n,vsp,def,vopts);
  1332. end;
  1333. constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
  1334. begin
  1335. inherited ppuload(localvarsym,ppufile);
  1336. end;
  1337. procedure tlocalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1338. begin
  1339. inherited ppuwrite(ppufile);
  1340. ppufile.writeentry(iblocalvarsym);
  1341. end;
  1342. {****************************************************************************
  1343. TPARAVARSYM
  1344. ****************************************************************************}
  1345. constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1346. begin
  1347. inherited create(paravarsym,n,vsp,def,vopts);
  1348. if (vsp in [vs_var,vs_value,vs_const]) then
  1349. varstate := vs_initialised;
  1350. paranr:=nr;
  1351. paraloc[calleeside].init;
  1352. paraloc[callerside].init;
  1353. end;
  1354. destructor tparavarsym.destroy;
  1355. begin
  1356. paraloc[calleeside].done;
  1357. paraloc[callerside].done;
  1358. inherited destroy;
  1359. end;
  1360. constructor tparavarsym.ppuload(ppufile:tcompilerppufile);
  1361. var
  1362. b : byte;
  1363. begin
  1364. inherited ppuload(paravarsym,ppufile);
  1365. paranr:=ppufile.getword;
  1366. { The var state of parameter symbols is fixed after writing them so
  1367. we write them to the unit file.
  1368. This enables constant folding for inline procedures loaded from units
  1369. }
  1370. varstate:=tvarstate(ppufile.getbyte);
  1371. paraloc[calleeside].init;
  1372. paraloc[callerside].init;
  1373. if vo_has_explicit_paraloc in varoptions then
  1374. begin
  1375. b:=ppufile.getbyte;
  1376. if b<>sizeof(paraloc[callerside].location^) then
  1377. internalerror(200411154);
  1378. ppufile.getdata(paraloc[callerside].add_location^,sizeof(paraloc[callerside].location^));
  1379. paraloc[callerside].size:=paraloc[callerside].location^.size;
  1380. paraloc[callerside].intsize:=tcgsize2size[paraloc[callerside].size];
  1381. end;
  1382. end;
  1383. procedure tparavarsym.ppuwrite(ppufile:tcompilerppufile);
  1384. var
  1385. oldintfcrc : boolean;
  1386. begin
  1387. inherited ppuwrite(ppufile);
  1388. ppufile.putword(paranr);
  1389. { The var state of parameter symbols is fixed after writing them so
  1390. we write them to the unit file.
  1391. This enables constant folding for inline procedures loaded from units
  1392. }
  1393. oldintfcrc:=ppufile.do_crc;
  1394. ppufile.do_crc:=false;
  1395. ppufile.putbyte(ord(varstate));
  1396. ppufile.do_crc:=oldintfcrc;
  1397. if vo_has_explicit_paraloc in varoptions then
  1398. begin
  1399. paraloc[callerside].check_simple_location;
  1400. ppufile.putbyte(sizeof(paraloc[callerside].location^));
  1401. ppufile.putdata(paraloc[callerside].location^,sizeof(paraloc[callerside].location^));
  1402. end;
  1403. ppufile.writeentry(ibparavarsym);
  1404. end;
  1405. {****************************************************************************
  1406. TABSOLUTEVARSYM
  1407. ****************************************************************************}
  1408. constructor tabsolutevarsym.create(const n : string;def:tdef);
  1409. begin
  1410. inherited create(absolutevarsym,n,vs_value,def,[]);
  1411. ref:=nil;
  1412. end;
  1413. constructor tabsolutevarsym.create_ref(const n : string;def:tdef;_ref:tpropaccesslist);
  1414. begin
  1415. inherited create(absolutevarsym,n,vs_value,def,[]);
  1416. ref:=_ref;
  1417. end;
  1418. destructor tabsolutevarsym.destroy;
  1419. begin
  1420. if assigned(ref) then
  1421. ref.free;
  1422. inherited destroy;
  1423. end;
  1424. constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
  1425. begin
  1426. inherited ppuload(absolutevarsym,ppufile);
  1427. ref:=nil;
  1428. asmname:=nil;
  1429. abstyp:=absolutetyp(ppufile.getbyte);
  1430. {$ifdef i386}
  1431. absseg:=false;
  1432. {$endif i386}
  1433. case abstyp of
  1434. tovar :
  1435. ref:=ppufile.getpropaccesslist;
  1436. toasm :
  1437. asmname:=stringdup(ppufile.getstring);
  1438. toaddr :
  1439. begin
  1440. addroffset:=ppufile.getaint;
  1441. {$ifdef i386}
  1442. absseg:=boolean(ppufile.getbyte);
  1443. {$endif i386}
  1444. end;
  1445. end;
  1446. end;
  1447. procedure tabsolutevarsym.ppuwrite(ppufile:tcompilerppufile);
  1448. begin
  1449. inherited ppuwrite(ppufile);
  1450. ppufile.putbyte(byte(abstyp));
  1451. case abstyp of
  1452. tovar :
  1453. ppufile.putpropaccesslist(ref);
  1454. toasm :
  1455. ppufile.putstring(asmname^);
  1456. toaddr :
  1457. begin
  1458. ppufile.putaint(addroffset);
  1459. {$ifdef i386}
  1460. ppufile.putbyte(byte(absseg));
  1461. {$endif i386}
  1462. end;
  1463. end;
  1464. ppufile.writeentry(ibabsolutevarsym);
  1465. end;
  1466. procedure tabsolutevarsym.buildderef;
  1467. begin
  1468. inherited buildderef;
  1469. if (abstyp=tovar) then
  1470. ref.buildderef;
  1471. end;
  1472. procedure tabsolutevarsym.deref;
  1473. begin
  1474. inherited deref;
  1475. { own absolute deref }
  1476. if (abstyp=tovar) then
  1477. ref.resolve;
  1478. end;
  1479. function tabsolutevarsym.mangledname : string;
  1480. begin
  1481. case abstyp of
  1482. toasm :
  1483. mangledname:=asmname^;
  1484. toaddr :
  1485. mangledname:='$'+tostr(addroffset);
  1486. else
  1487. internalerror(200411062);
  1488. end;
  1489. end;
  1490. {****************************************************************************
  1491. TTYPEDCONSTSYM
  1492. *****************************************************************************}
  1493. constructor ttypedconstsym.create(const n : string;def : tdef;writable : boolean);
  1494. begin
  1495. inherited create(typedconstsym,n);
  1496. typedconstdef:=def;
  1497. is_writable:=writable;
  1498. end;
  1499. constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
  1500. begin
  1501. inherited ppuload(typedconstsym,ppufile);
  1502. ppufile.getderef(typedconstdefderef);
  1503. is_writable:=boolean(ppufile.getbyte);
  1504. end;
  1505. destructor ttypedconstsym.destroy;
  1506. begin
  1507. if assigned(_mangledname) then
  1508. begin
  1509. {$ifdef MEMDEBUG}
  1510. memmanglednames.start;
  1511. {$endif MEMDEBUG}
  1512. stringdispose(_mangledname);
  1513. {$ifdef MEMDEBUG}
  1514. memmanglednames.stop;
  1515. {$endif MEMDEBUG}
  1516. end;
  1517. inherited destroy;
  1518. end;
  1519. function ttypedconstsym.mangledname:string;
  1520. begin
  1521. if not assigned(_mangledname) then
  1522. begin
  1523. {$ifdef compress}
  1524. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1525. {$else}
  1526. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1527. {$endif}
  1528. end;
  1529. result:=_mangledname^;
  1530. end;
  1531. procedure ttypedconstsym.set_mangledname(const s:string);
  1532. begin
  1533. stringdispose(_mangledname);
  1534. {$ifdef compress}
  1535. _mangledname:=stringdup(minilzw_encode(s));
  1536. {$else}
  1537. _mangledname:=stringdup(s);
  1538. {$endif}
  1539. end;
  1540. function ttypedconstsym.getsize : longint;
  1541. begin
  1542. if assigned(typedconstdef) then
  1543. getsize:=typedconstdef.size
  1544. else
  1545. getsize:=0;
  1546. end;
  1547. procedure ttypedconstsym.buildderef;
  1548. begin
  1549. typedconstdefderef.build(typedconstdef);
  1550. end;
  1551. procedure ttypedconstsym.deref;
  1552. begin
  1553. typedconstdef:=tdef(typedconstdefderef.resolve);
  1554. end;
  1555. procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
  1556. begin
  1557. inherited ppuwrite(ppufile);
  1558. ppufile.putderef(typedconstdefderef);
  1559. ppufile.putbyte(byte(is_writable));
  1560. ppufile.writeentry(ibtypedconstsym);
  1561. end;
  1562. {****************************************************************************
  1563. TCONSTSYM
  1564. ****************************************************************************}
  1565. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;def:tdef);
  1566. begin
  1567. inherited create(constsym,n);
  1568. fillchar(value, sizeof(value), #0);
  1569. consttyp:=t;
  1570. value.valueord:=v;
  1571. ResStrIndex:=0;
  1572. constdef:=def;
  1573. end;
  1574. constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;def:tdef);
  1575. begin
  1576. inherited create(constsym,n);
  1577. fillchar(value, sizeof(value), #0);
  1578. consttyp:=t;
  1579. value.valueordptr:=v;
  1580. ResStrIndex:=0;
  1581. constdef:=def;
  1582. end;
  1583. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;def:tdef);
  1584. begin
  1585. inherited create(constsym,n);
  1586. fillchar(value, sizeof(value), #0);
  1587. consttyp:=t;
  1588. value.valueptr:=v;
  1589. ResStrIndex:=0;
  1590. constdef:=def;
  1591. end;
  1592. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1593. begin
  1594. inherited create(constsym,n);
  1595. fillchar(value, sizeof(value), #0);
  1596. consttyp:=t;
  1597. value.valueptr:=str;
  1598. constdef:=nil;
  1599. value.len:=l;
  1600. end;
  1601. constructor tconstsym.create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
  1602. begin
  1603. inherited create(constsym,n);
  1604. fillchar(value, sizeof(value), #0);
  1605. consttyp:=t;
  1606. pcompilerwidestring(value.valueptr):=pw;
  1607. constdef:=nil;
  1608. value.len:=getlengthwidestring(pw);
  1609. end;
  1610. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1611. var
  1612. pd : pbestreal;
  1613. ps : pnormalset;
  1614. pc : pchar;
  1615. pw : pcompilerwidestring;
  1616. begin
  1617. inherited ppuload(constsym,ppufile);
  1618. constdef:=nil;
  1619. consttyp:=tconsttyp(ppufile.getbyte);
  1620. fillchar(value, sizeof(value), #0);
  1621. case consttyp of
  1622. constord :
  1623. begin
  1624. ppufile.getderef(constdefderef);
  1625. value.valueord:=ppufile.getexprint;
  1626. end;
  1627. constpointer :
  1628. begin
  1629. ppufile.getderef(constdefderef);
  1630. value.valueordptr:=ppufile.getptruint;
  1631. end;
  1632. constwstring :
  1633. begin
  1634. initwidestring(pw);
  1635. setlengthwidestring(pw,ppufile.getlongint);
  1636. ppufile.getdata(pw^.data,pw^.len*sizeof(tcompilerwidechar));
  1637. pcompilerwidestring(value.valueptr):=pw;
  1638. end;
  1639. conststring,
  1640. constresourcestring :
  1641. begin
  1642. value.len:=ppufile.getlongint;
  1643. getmem(pc,value.len+1);
  1644. ppufile.getdata(pc^,value.len);
  1645. if consttyp=constresourcestring then
  1646. ResStrIndex:=ppufile.getlongint;
  1647. value.valueptr:=pc;
  1648. end;
  1649. constreal :
  1650. begin
  1651. new(pd);
  1652. pd^:=ppufile.getreal;
  1653. value.valueptr:=pd;
  1654. end;
  1655. constset :
  1656. begin
  1657. ppufile.getderef(constdefderef);
  1658. new(ps);
  1659. ppufile.getnormalset(ps^);
  1660. value.valueptr:=ps;
  1661. end;
  1662. constguid :
  1663. begin
  1664. new(pguid(value.valueptr));
  1665. ppufile.getdata(value.valueptr^,sizeof(tguid));
  1666. end;
  1667. constnil : ;
  1668. else
  1669. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1670. end;
  1671. end;
  1672. destructor tconstsym.destroy;
  1673. begin
  1674. case consttyp of
  1675. conststring,
  1676. constresourcestring :
  1677. freemem(pchar(value.valueptr),value.len+1);
  1678. constwstring :
  1679. donewidestring(pcompilerwidestring(value.valueptr));
  1680. constreal :
  1681. dispose(pbestreal(value.valueptr));
  1682. constset :
  1683. dispose(pnormalset(value.valueptr));
  1684. constguid :
  1685. dispose(pguid(value.valueptr));
  1686. end;
  1687. inherited destroy;
  1688. end;
  1689. procedure tconstsym.buildderef;
  1690. begin
  1691. if consttyp in [constord,constpointer,constset] then
  1692. constdefderef.build(constdef);
  1693. end;
  1694. procedure tconstsym.deref;
  1695. begin
  1696. if consttyp in [constord,constpointer,constset] then
  1697. constdef:=tdef(constdefderef.resolve);
  1698. end;
  1699. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1700. begin
  1701. inherited ppuwrite(ppufile);
  1702. ppufile.putbyte(byte(consttyp));
  1703. case consttyp of
  1704. constnil : ;
  1705. constord :
  1706. begin
  1707. ppufile.putderef(constdefderef);
  1708. ppufile.putexprint(value.valueord);
  1709. end;
  1710. constpointer :
  1711. begin
  1712. ppufile.putderef(constdefderef);
  1713. ppufile.putptruint(value.valueordptr);
  1714. end;
  1715. constwstring :
  1716. begin
  1717. ppufile.putlongint(getlengthwidestring(pcompilerwidestring(value.valueptr)));
  1718. ppufile.putdata(pcompilerwidestring(value.valueptr)^.data,pcompilerwidestring(value.valueptr)^.len*sizeof(tcompilerwidechar));
  1719. end;
  1720. conststring,
  1721. constresourcestring :
  1722. begin
  1723. ppufile.putlongint(value.len);
  1724. ppufile.putdata(pchar(value.valueptr)^,value.len);
  1725. if consttyp=constresourcestring then
  1726. ppufile.putlongint(ResStrIndex);
  1727. end;
  1728. constreal :
  1729. ppufile.putreal(pbestreal(value.valueptr)^);
  1730. constset :
  1731. begin
  1732. ppufile.putderef(constdefderef);
  1733. ppufile.putnormalset(value.valueptr^);
  1734. end;
  1735. constguid :
  1736. ppufile.putdata(value.valueptr^,sizeof(tguid));
  1737. else
  1738. internalerror(13);
  1739. end;
  1740. ppufile.writeentry(ibconstsym);
  1741. end;
  1742. {****************************************************************************
  1743. TENUMSYM
  1744. ****************************************************************************}
  1745. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1746. begin
  1747. inherited create(enumsym,n);
  1748. definition:=def;
  1749. value:=v;
  1750. { First entry? Then we need to set the minval }
  1751. if def.firstenum=nil then
  1752. begin
  1753. if v>0 then
  1754. def.has_jumps:=true;
  1755. def.setmin(v);
  1756. def.setmax(v);
  1757. end
  1758. else
  1759. begin
  1760. { check for jumps }
  1761. if v>def.max+1 then
  1762. def.has_jumps:=true;
  1763. { update low and high }
  1764. if def.min>v then
  1765. def.setmin(v);
  1766. if def.max<v then
  1767. def.setmax(v);
  1768. end;
  1769. order;
  1770. end;
  1771. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  1772. begin
  1773. inherited ppuload(enumsym,ppufile);
  1774. ppufile.getderef(definitionderef);
  1775. value:=ppufile.getlongint;
  1776. nextenum := Nil;
  1777. end;
  1778. procedure tenumsym.buildderef;
  1779. begin
  1780. definitionderef.build(definition);
  1781. end;
  1782. procedure tenumsym.deref;
  1783. begin
  1784. definition:=tenumdef(definitionderef.resolve);
  1785. order;
  1786. end;
  1787. procedure tenumsym.order;
  1788. var
  1789. sym : tenumsym;
  1790. begin
  1791. sym := tenumsym(definition.firstenum);
  1792. if sym = nil then
  1793. begin
  1794. definition.firstenum := self;
  1795. nextenum := nil;
  1796. exit;
  1797. end;
  1798. { reorder the symbols in increasing value }
  1799. if value < sym.value then
  1800. begin
  1801. nextenum := sym;
  1802. definition.firstenum := self;
  1803. end
  1804. else
  1805. begin
  1806. while (sym.value <= value) and assigned(sym.nextenum) do
  1807. sym := sym.nextenum;
  1808. nextenum := sym.nextenum;
  1809. sym.nextenum := self;
  1810. end;
  1811. end;
  1812. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  1813. begin
  1814. inherited ppuwrite(ppufile);
  1815. ppufile.putderef(definitionderef);
  1816. ppufile.putlongint(value);
  1817. ppufile.writeentry(ibenumsym);
  1818. end;
  1819. {****************************************************************************
  1820. TTYPESYM
  1821. ****************************************************************************}
  1822. constructor ttypesym.create(const n : string;def:tdef);
  1823. begin
  1824. inherited create(typesym,n);
  1825. typedef:=def;
  1826. { register the typesym for the definition }
  1827. if assigned(typedef) and
  1828. (typedef.deftype<>errordef) and
  1829. not(assigned(typedef.typesym)) then
  1830. typedef.typesym:=self;
  1831. end;
  1832. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  1833. begin
  1834. inherited ppuload(typesym,ppufile);
  1835. ppufile.getderef(typedefderef);
  1836. end;
  1837. function ttypesym.getderefdef:tdef;
  1838. begin
  1839. result:=typedef;
  1840. end;
  1841. procedure ttypesym.buildderef;
  1842. begin
  1843. typedefderef.build(typedef);
  1844. end;
  1845. procedure ttypesym.deref;
  1846. begin
  1847. typedef:=tdef(typedefderef.resolve);
  1848. end;
  1849. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  1850. begin
  1851. inherited ppuwrite(ppufile);
  1852. ppufile.putderef(typedefderef);
  1853. ppufile.writeentry(ibtypesym);
  1854. end;
  1855. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  1856. begin
  1857. inherited load_references(ppufile,locals);
  1858. if (typedef.deftype=recorddef) then
  1859. tstoredsymtable(trecorddef(typedef).symtable).load_references(ppufile,locals);
  1860. if (typedef.deftype=objectdef) then
  1861. tstoredsymtable(tobjectdef(typedef).symtable).load_references(ppufile,locals);
  1862. end;
  1863. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  1864. var
  1865. d : tderef;
  1866. begin
  1867. d.reset;
  1868. if not inherited write_references(ppufile,locals) then
  1869. begin
  1870. { write address of this symbol if record or object
  1871. even if no real refs are there
  1872. because we need it for the symtable }
  1873. if (typedef.deftype in [recorddef,objectdef]) then
  1874. begin
  1875. d.build(self);
  1876. ppufile.putderef(d);
  1877. ppufile.writeentry(ibsymref);
  1878. end;
  1879. end;
  1880. write_references:=true;
  1881. if (typedef.deftype=recorddef) then
  1882. tstoredsymtable(trecorddef(typedef).symtable).write_references(ppufile,locals);
  1883. if (typedef.deftype=objectdef) then
  1884. tstoredsymtable(tobjectdef(typedef).symtable).write_references(ppufile,locals);
  1885. end;
  1886. {****************************************************************************
  1887. TSYSSYM
  1888. ****************************************************************************}
  1889. constructor tsyssym.create(const n : string;l : longint);
  1890. begin
  1891. inherited create(syssym,n);
  1892. number:=l;
  1893. end;
  1894. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  1895. begin
  1896. inherited ppuload(syssym,ppufile);
  1897. number:=ppufile.getlongint;
  1898. end;
  1899. destructor tsyssym.destroy;
  1900. begin
  1901. inherited destroy;
  1902. end;
  1903. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  1904. begin
  1905. inherited ppuwrite(ppufile);
  1906. ppufile.putlongint(number);
  1907. ppufile.writeentry(ibsyssym);
  1908. end;
  1909. {*****************************************************************************
  1910. TMacro
  1911. *****************************************************************************}
  1912. constructor tmacro.create(const n : string);
  1913. begin
  1914. inherited create(macrosym,n);
  1915. owner:=nil;
  1916. defined:=false;
  1917. is_used:=false;
  1918. is_compiler_var:=false;
  1919. buftext:=nil;
  1920. buflen:=0;
  1921. end;
  1922. constructor tmacro.ppuload(ppufile:tcompilerppufile);
  1923. begin
  1924. inherited ppuload(macrosym,ppufile);
  1925. name:=ppufile.getstring;
  1926. defined:=boolean(ppufile.getbyte);
  1927. is_compiler_var:=boolean(ppufile.getbyte);
  1928. is_used:=false;
  1929. buflen:= ppufile.getlongint;
  1930. if buflen > 0 then
  1931. begin
  1932. getmem(buftext, buflen);
  1933. ppufile.getdata(buftext^, buflen)
  1934. end
  1935. else
  1936. buftext:=nil;
  1937. end;
  1938. destructor tmacro.destroy;
  1939. begin
  1940. if assigned(buftext) then
  1941. freemem(buftext);
  1942. inherited destroy;
  1943. end;
  1944. procedure tmacro.ppuwrite(ppufile:tcompilerppufile);
  1945. begin
  1946. inherited ppuwrite(ppufile);
  1947. ppufile.putstring(name);
  1948. ppufile.putbyte(byte(defined));
  1949. ppufile.putbyte(byte(is_compiler_var));
  1950. ppufile.putlongint(buflen);
  1951. if buflen > 0 then
  1952. ppufile.putdata(buftext^,buflen);
  1953. ppufile.writeentry(ibmacrosym);
  1954. end;
  1955. function tmacro.GetCopy:tmacro;
  1956. var
  1957. p : tmacro;
  1958. begin
  1959. p:=tmacro.create(realname);
  1960. p.defined:=defined;
  1961. p.is_used:=is_used;
  1962. p.is_compiler_var:=is_compiler_var;
  1963. p.buflen:=buflen;
  1964. if assigned(buftext) then
  1965. begin
  1966. getmem(p.buftext,buflen);
  1967. move(buftext^,p.buftext^,buflen);
  1968. end;
  1969. Result:=p;
  1970. end;
  1971. {****************************************************************************
  1972. TRTTISYM
  1973. ****************************************************************************}
  1974. constructor trttisym.create(const n:string;rt:trttitype);
  1975. const
  1976. prefix : array[trttitype] of string[5]=('$rtti','$init');
  1977. begin
  1978. inherited create(rttisym,prefix[rt]+n);
  1979. include(symoptions,sp_internal);
  1980. lab:=nil;
  1981. rttityp:=rt;
  1982. end;
  1983. destructor trttisym.destroy;
  1984. begin
  1985. if assigned(_mangledname) then
  1986. begin
  1987. {$ifdef MEMDEBUG}
  1988. memmanglednames.start;
  1989. {$endif MEMDEBUG}
  1990. stringdispose(_mangledname);
  1991. {$ifdef MEMDEBUG}
  1992. memmanglednames.stop;
  1993. {$endif MEMDEBUG}
  1994. end;
  1995. inherited destroy;
  1996. end;
  1997. constructor trttisym.ppuload(ppufile:tcompilerppufile);
  1998. begin
  1999. inherited ppuload(rttisym,ppufile);
  2000. lab:=nil;
  2001. rttityp:=trttitype(ppufile.getbyte);
  2002. end;
  2003. procedure trttisym.ppuwrite(ppufile:tcompilerppufile);
  2004. begin
  2005. inherited ppuwrite(ppufile);
  2006. ppufile.putbyte(byte(rttityp));
  2007. ppufile.writeentry(ibrttisym);
  2008. end;
  2009. function trttisym.mangledname : string;
  2010. const
  2011. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2012. begin
  2013. if not assigned(_mangledname) then
  2014. _mangledname:=stringdup(make_mangledname(prefix[rttityp],owner,Copy(name,5,255)));
  2015. result:=_mangledname^;
  2016. end;
  2017. function trttisym.get_label:tasmsymbol;
  2018. begin
  2019. { the label is always a global label }
  2020. if not assigned(lab) then
  2021. lab:=current_asmdata.RefAsmSymbol(mangledname);
  2022. get_label:=lab;
  2023. end;
  2024. end.