symsym.pas 77 KB

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