symsym.pas 78 KB

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