2
0

symsym.pas 71 KB

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