symsym.pas 69 KB

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