symsym.pas 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623
  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. cpuinfo,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,
  28. { ppu }
  29. ppu,symppu,
  30. {$ifdef var_notification}
  31. cclasses,symnot,
  32. {$endif}
  33. { aasm }
  34. aasmbase,aasmtai,cpubase,
  35. globals
  36. ;
  37. type
  38. {************************************************
  39. TSym
  40. ************************************************}
  41. { this object is the base for all symbol objects }
  42. tstoredsym = class(tsym)
  43. protected
  44. _mangledname : pstring;
  45. public
  46. {$ifdef GDB}
  47. isstabwritten : boolean;
  48. {$endif GDB}
  49. refs : longint;
  50. lastref,
  51. defref,
  52. lastwritten : tref;
  53. refcount : longint;
  54. constructor create(const n : string);
  55. constructor loadsym(ppufile:tcompilerppufile);
  56. destructor destroy;override;
  57. procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
  58. procedure writesym(ppufile:tcompilerppufile);
  59. procedure deref;override;
  60. {$ifdef GDB}
  61. function stabstring : pchar;virtual;
  62. procedure concatstabto(asmlist : taasmoutput);virtual;
  63. {$endif GDB}
  64. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  65. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  66. function is_visible_for_proc(currprocdef:tprocdef):boolean;
  67. function is_visible_for_object(currobjdef:tobjectdef):boolean;
  68. function mangledname : string;
  69. procedure generate_mangledname;virtual;abstract;
  70. end;
  71. tlabelsym = class(tstoredsym)
  72. lab : tasmlabel;
  73. used,
  74. defined : boolean;
  75. code : pointer; { should be tnode }
  76. constructor create(const n : string; l : tasmlabel);
  77. destructor destroy;override;
  78. constructor ppuload(ppufile:tcompilerppufile);
  79. procedure generate_mangledname;override;
  80. procedure ppuwrite(ppufile:tcompilerppufile);override;
  81. end;
  82. tunitsym = class(tstoredsym)
  83. unitsymtable : tsymtable;
  84. prevsym : tunitsym;
  85. constructor create(const n : string;ref : tsymtable);
  86. constructor ppuload(ppufile:tcompilerppufile);
  87. destructor destroy;override;
  88. procedure ppuwrite(ppufile:tcompilerppufile);override;
  89. procedure restoreunitsym;
  90. {$ifdef GDB}
  91. procedure concatstabto(asmlist : taasmoutput);override;
  92. {$endif GDB}
  93. end;
  94. terrorsym = class(tstoredsym)
  95. constructor create;
  96. end;
  97. Tprocdefcallback = procedure(p:Tprocdef;arg:pointer);
  98. tprocsym = class(tstoredsym)
  99. protected
  100. defs : pprocdeflist; { linked list of overloaded procdefs }
  101. function getprocdef(nr:cardinal):Tprocdef;
  102. public
  103. procdef_count : cardinal;
  104. is_global : boolean;
  105. overloadchecked : boolean;
  106. overloadcount : longint; { amount of overloaded functions in this module }
  107. property procdef[nr:cardinal]:Tprocdef read getprocdef;
  108. constructor create(const n : string);
  109. constructor ppuload(ppufile:tcompilerppufile);
  110. destructor destroy;override;
  111. { writes all declarations except the specified one }
  112. procedure write_parameter_lists(skipdef:tprocdef);
  113. { tests, if all procedures definitions are defined and not }
  114. { only forward }
  115. procedure check_forward;
  116. procedure unchain_overload;
  117. procedure ppuwrite(ppufile:tcompilerppufile);override;
  118. procedure deref;override;
  119. procedure addprocdef(p:tprocdef);
  120. procedure add_para_match_to(Aprocsym:Tprocsym);
  121. procedure concat_procdefs_to(s:Tprocsym);
  122. procedure foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  123. function first_procdef:Tprocdef;
  124. function last_procdef:Tprocdef;
  125. function search_procdef_nopara_boolret:Tprocdef;
  126. function search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  127. function search_procdef_bypara(params:Tparalinkedlist;
  128. allowconvert:boolean):Tprocdef;
  129. function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  130. function search_procdef_by1paradef(firstpara:Tdef):Tprocdef;
  131. function search_procdef_byretdef_by1paradef(retdef,firstpara:Tdef;
  132. matchtype:Tdefmatch):Tprocdef;
  133. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  134. {$ifdef GDB}
  135. function stabstring : pchar;override;
  136. procedure concatstabto(asmlist : taasmoutput);override;
  137. {$endif GDB}
  138. end;
  139. ttypesym = class(tstoredsym)
  140. restype : ttype;
  141. {$ifdef GDB}
  142. isusedinstab : boolean;
  143. {$endif GDB}
  144. constructor create(const n : string;const tt : ttype);
  145. constructor ppuload(ppufile:tcompilerppufile);
  146. procedure ppuwrite(ppufile:tcompilerppufile);override;
  147. procedure deref;override;
  148. function gettypedef:tdef;override;
  149. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  150. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  151. {$ifdef GDB}
  152. function stabstring : pchar;override;
  153. procedure concatstabto(asmlist : taasmoutput);override;
  154. {$endif GDB}
  155. end;
  156. tvarsym = class(tstoredsym)
  157. address : longint;
  158. localvarsym : tvarsym;
  159. vartype : ttype;
  160. varoptions : tvaroptions;
  161. reg : tregister; { if reg<>R_NO, then the variable is an register variable }
  162. varspez : tvarspez; { sets the type of access }
  163. varstate : tvarstate;
  164. {$ifdef var_notification}
  165. notifications : Tlinkedlist;
  166. {$endif}
  167. constructor create(const n : string;const tt : ttype);
  168. constructor create_dll(const n : string;const tt : ttype);
  169. constructor create_C(const n,mangled : string;const tt : ttype);
  170. constructor ppuload(ppufile:tcompilerppufile);
  171. destructor destroy;override;
  172. procedure ppuwrite(ppufile:tcompilerppufile);override;
  173. procedure deref;override;
  174. procedure generate_mangledname;override;
  175. procedure set_mangledname(const s:string);
  176. function getsize : longint;
  177. function getvaluesize : longint;
  178. function getpushsize(is_cdecl:boolean): longint;
  179. {$ifdef var_notification}
  180. function register_notification(flags:Tnotification_flags;
  181. callback:Tnotification_callback):cardinal;
  182. {$endif}
  183. {$ifdef GDB}
  184. function stabstring : pchar;override;
  185. procedure concatstabto(asmlist : taasmoutput);override;
  186. {$endif GDB}
  187. end;
  188. tpropertysym = class(tstoredsym)
  189. propoptions : tpropertyoptions;
  190. propoverriden : tpropertysym;
  191. proptype,
  192. indextype : ttype;
  193. index,
  194. default : longint;
  195. readaccess,
  196. writeaccess,
  197. storedaccess : tsymlist;
  198. constructor create(const n : string);
  199. destructor destroy;override;
  200. constructor ppuload(ppufile:tcompilerppufile);
  201. function getsize : longint;
  202. procedure ppuwrite(ppufile:tcompilerppufile);override;
  203. function gettypedef:tdef;override;
  204. procedure deref;override;
  205. procedure dooverride(overriden:tpropertysym);
  206. {$ifdef GDB}
  207. function stabstring : pchar;override;
  208. procedure concatstabto(asmlist : taasmoutput);override;
  209. {$endif GDB}
  210. end;
  211. tfuncretsym = class(tstoredsym)
  212. returntype : ttype;
  213. address : longint;
  214. funcretstate : tvarstate;
  215. constructor create(const n : string;const tt : ttype);
  216. constructor ppuload(ppufile:tcompilerppufile);
  217. destructor destroy;override;
  218. procedure ppuwrite(ppufile:tcompilerppufile);override;
  219. procedure deref;override;
  220. {$ifdef GDB}
  221. procedure concatstabto(asmlist : taasmoutput);override;
  222. {$endif GDB}
  223. end;
  224. tabsolutesym = class(tvarsym)
  225. abstyp : absolutetyp;
  226. absseg : boolean;
  227. ref : tstoredsym;
  228. asmname : pstring;
  229. constructor create(const n : string;const tt : ttype);
  230. constructor ppuload(ppufile:tcompilerppufile);
  231. procedure deref;override;
  232. function mangledname : string;
  233. procedure ppuwrite(ppufile:tcompilerppufile);override;
  234. {$ifdef GDB}
  235. procedure concatstabto(asmlist : taasmoutput);override;
  236. {$endif GDB}
  237. end;
  238. ttypedconstsym = class(tstoredsym)
  239. typedconsttype : ttype;
  240. is_writable : boolean;
  241. constructor create(const n : string;p : tdef;writable : boolean);
  242. constructor createtype(const n : string;const tt : ttype;writable : boolean);
  243. constructor ppuload(ppufile:tcompilerppufile);
  244. destructor destroy;override;
  245. procedure generate_mangledname;override;
  246. procedure ppuwrite(ppufile:tcompilerppufile);override;
  247. procedure deref;override;
  248. function getsize:longint;
  249. {$ifdef GDB}
  250. function stabstring : pchar;override;
  251. {$endif GDB}
  252. end;
  253. tconstsym = class(tstoredsym)
  254. consttype : ttype;
  255. consttyp : tconsttyp;
  256. resstrindex, { needed for resource strings }
  257. valueord : tconstexprint; { used for ordinal values }
  258. valueordptr : TConstPtrUInt; { used for pointer values }
  259. valueptr : pointer; { used for string, set, real values }
  260. len : longint; { len is needed for string length }
  261. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint);
  262. constructor create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  263. constructor create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  264. constructor create_ptr(const n : string;t : tconsttyp;v : pointer);
  265. constructor create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  266. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  267. constructor ppuload(ppufile:tcompilerppufile);
  268. destructor destroy;override;
  269. function mangledname : string;
  270. procedure deref;override;
  271. procedure ppuwrite(ppufile:tcompilerppufile);override;
  272. {$ifdef GDB}
  273. function stabstring : pchar;override;
  274. procedure concatstabto(asmlist : taasmoutput);override;
  275. {$endif GDB}
  276. end;
  277. tenumsym = class(tstoredsym)
  278. value : longint;
  279. definition : tenumdef;
  280. nextenum : tenumsym;
  281. constructor create(const n : string;def : tenumdef;v : longint);
  282. constructor ppuload(ppufile:tcompilerppufile);
  283. procedure ppuwrite(ppufile:tcompilerppufile);override;
  284. procedure deref;override;
  285. procedure order;
  286. {$ifdef GDB}
  287. procedure concatstabto(asmlist : taasmoutput);override;
  288. {$endif GDB}
  289. end;
  290. tsyssym = class(tstoredsym)
  291. number : longint;
  292. constructor create(const n : string;l : longint);
  293. constructor ppuload(ppufile:tcompilerppufile);
  294. destructor destroy;override;
  295. procedure ppuwrite(ppufile:tcompilerppufile);override;
  296. {$ifdef GDB}
  297. procedure concatstabto(asmlist : taasmoutput);override;
  298. {$endif GDB}
  299. end;
  300. { compiler generated symbol to point to rtti and init/finalize tables }
  301. trttisym = class(tstoredsym)
  302. lab : tasmsymbol;
  303. rttityp : trttitype;
  304. constructor create(const n:string;rt:trttitype);
  305. constructor ppuload(ppufile:tcompilerppufile);
  306. procedure ppuwrite(ppufile:tcompilerppufile);override;
  307. function mangledname:string;
  308. function get_label:tasmsymbol;
  309. end;
  310. { register variables }
  311. pregvarinfo = ^tregvarinfo;
  312. tregvarinfo = record
  313. regvars : array[1..maxvarregs] of tvarsym;
  314. regvars_para : array[1..maxvarregs] of boolean;
  315. regvars_refs : array[1..maxvarregs] of longint;
  316. fpuregvars : array[1..maxfpuvarregs] of tvarsym;
  317. fpuregvars_para : array[1..maxfpuvarregs] of boolean;
  318. fpuregvars_refs : array[1..maxfpuvarregs] of longint;
  319. end;
  320. var
  321. aktprocsym : tprocsym; { pointer to the symbol for the
  322. currently be parsed procedure }
  323. aktprocdef : tprocdef;
  324. aktcallprocdef : tabstractprocdef; { pointer to the definition of the
  325. currently called procedure,
  326. only set/unset in ncal }
  327. aktvarsym : tvarsym; { pointer to the symbol for the
  328. currently read var, only used
  329. for variable directives }
  330. generrorsym : tsym;
  331. otsym : tvarsym;
  332. const
  333. current_object_option : tsymoptions = [sp_public];
  334. { rtti and init/final }
  335. procedure generate_rtti(p:tsym);
  336. procedure generate_inittable(p:tsym);
  337. implementation
  338. uses
  339. {$ifdef Delphi}
  340. sysutils,
  341. {$else Delphi}
  342. strings,
  343. {$endif Delphi}
  344. { global }
  345. globtype,verbose,
  346. { target }
  347. systems,
  348. { symtable }
  349. symtable,defbase,
  350. {$ifdef GDB}
  351. gdb,
  352. {$endif GDB}
  353. { tree }
  354. node,
  355. { aasm }
  356. aasmcpu,
  357. { module }
  358. fmodule,
  359. { codegen }
  360. paramgr,cgbase,cresstr
  361. ;
  362. {****************************************************************************
  363. Helpers
  364. ****************************************************************************}
  365. {****************************************************************************
  366. TSYM (base for all symtypes)
  367. ****************************************************************************}
  368. constructor tstoredsym.create(const n : string);
  369. begin
  370. inherited create(n);
  371. symoptions:=current_object_option;
  372. {$ifdef GDB}
  373. isstabwritten := false;
  374. {$endif GDB}
  375. fileinfo:=akttokenpos;
  376. defref:=nil;
  377. refs:=0;
  378. lastwritten:=nil;
  379. refcount:=0;
  380. if (cs_browser in aktmoduleswitches) and make_ref then
  381. begin
  382. defref:=tref.create(defref,@akttokenpos);
  383. inc(refcount);
  384. end;
  385. lastref:=defref;
  386. _mangledname:=nil;
  387. end;
  388. constructor tstoredsym.loadsym(ppufile:tcompilerppufile);
  389. var
  390. s : string;
  391. nr : word;
  392. begin
  393. nr:=ppufile.getword;
  394. s:=ppufile.getstring;
  395. inherited create(s);
  396. { force the correct indexnr. must be after create! }
  397. indexnr:=nr;
  398. ppufile.getsmallset(symoptions);
  399. ppufile.getposinfo(fileinfo);
  400. lastref:=nil;
  401. defref:=nil;
  402. refs:=0;
  403. lastwritten:=nil;
  404. refcount:=0;
  405. _mangledname:=nil;
  406. {$ifdef GDB}
  407. isstabwritten := false;
  408. {$endif GDB}
  409. end;
  410. procedure tstoredsym.deref;
  411. begin
  412. end;
  413. procedure tstoredsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  414. var
  415. pos : tfileposinfo;
  416. move_last : boolean;
  417. begin
  418. move_last:=lastwritten=lastref;
  419. while (not ppufile.endofentry) do
  420. begin
  421. ppufile.getposinfo(pos);
  422. inc(refcount);
  423. lastref:=tref.create(lastref,@pos);
  424. lastref.is_written:=true;
  425. if refcount=1 then
  426. defref:=lastref;
  427. end;
  428. if move_last then
  429. lastwritten:=lastref;
  430. end;
  431. { big problem here :
  432. wrong refs were written because of
  433. interface parsing of other units PM
  434. moduleindex must be checked !! }
  435. function tstoredsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  436. var
  437. ref : tref;
  438. symref_written,move_last : boolean;
  439. begin
  440. write_references:=false;
  441. if lastwritten=lastref then
  442. exit;
  443. { should we update lastref }
  444. move_last:=true;
  445. symref_written:=false;
  446. { write symbol refs }
  447. if assigned(lastwritten) then
  448. ref:=lastwritten
  449. else
  450. ref:=defref;
  451. while assigned(ref) do
  452. begin
  453. if ref.moduleindex=current_module.unit_index then
  454. begin
  455. { write address to this symbol }
  456. if not symref_written then
  457. begin
  458. ppufile.putderef(self);
  459. symref_written:=true;
  460. end;
  461. ppufile.putposinfo(ref.posinfo);
  462. ref.is_written:=true;
  463. if move_last then
  464. lastwritten:=ref;
  465. end
  466. else if not ref.is_written then
  467. move_last:=false
  468. else if move_last then
  469. lastwritten:=ref;
  470. ref:=ref.nextref;
  471. end;
  472. if symref_written then
  473. ppufile.writeentry(ibsymref);
  474. write_references:=symref_written;
  475. end;
  476. destructor tstoredsym.destroy;
  477. begin
  478. if assigned(_mangledname) then
  479. stringdispose(_mangledname);
  480. if assigned(defref) then
  481. begin
  482. defref.freechain;
  483. defref.free;
  484. end;
  485. inherited destroy;
  486. end;
  487. procedure tstoredsym.writesym(ppufile:tcompilerppufile);
  488. begin
  489. ppufile.putword(indexnr);
  490. ppufile.putstring(_realname^);
  491. ppufile.putsmallset(symoptions);
  492. ppufile.putposinfo(fileinfo);
  493. end;
  494. {$ifdef GDB}
  495. function tstoredsym.stabstring : pchar;
  496. begin
  497. stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+
  498. tostr(fileinfo.line)+',0');
  499. end;
  500. procedure tstoredsym.concatstabto(asmlist : taasmoutput);
  501. var
  502. stab_str : pchar;
  503. begin
  504. if not isstabwritten then
  505. begin
  506. stab_str := stabstring;
  507. { count_dbx(stab_str); moved to GDB.PAS }
  508. asmList.concat(Tai_stabs.Create(stab_str));
  509. isstabwritten:=true;
  510. end;
  511. end;
  512. {$endif GDB}
  513. function tstoredsym.is_visible_for_proc(currprocdef:tprocdef):boolean;
  514. begin
  515. is_visible_for_proc:=false;
  516. { private symbols are allowed when we are in the same
  517. module as they are defined }
  518. if (sp_private in symoptions) and
  519. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  520. (owner.defowner.owner.unitid<>0) then
  521. exit;
  522. { protected symbols are vissible in the module that defines them and
  523. also visible to related objects }
  524. if (sp_protected in symoptions) and
  525. (
  526. (
  527. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  528. (owner.defowner.owner.unitid<>0)
  529. ) and
  530. not(
  531. assigned(currprocdef) and
  532. assigned(currprocdef._class) and
  533. currprocdef._class.is_related(tobjectdef(owner.defowner))
  534. )
  535. ) then
  536. exit;
  537. is_visible_for_proc:=true;
  538. end;
  539. function tstoredsym.is_visible_for_object(currobjdef:tobjectdef):boolean;
  540. begin
  541. is_visible_for_object:=false;
  542. { private symbols are allowed when we are in the same
  543. module as they are defined }
  544. if (sp_private in symoptions) and
  545. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  546. (owner.defowner.owner.unitid<>0) then
  547. exit;
  548. { protected symbols are vissible in the module that defines them and
  549. also visible to related objects }
  550. if (sp_protected in symoptions) and
  551. (
  552. (
  553. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  554. (owner.defowner.owner.unitid<>0)
  555. ) and
  556. not(
  557. assigned(currobjdef) and
  558. currobjdef.is_related(tobjectdef(owner.defowner))
  559. )
  560. ) then
  561. exit;
  562. is_visible_for_object:=true;
  563. end;
  564. function tstoredsym.mangledname : string;
  565. begin
  566. if not assigned(_mangledname) then
  567. begin
  568. generate_mangledname;
  569. if not assigned(_mangledname) then
  570. internalerror(200204171);
  571. end;
  572. mangledname:=_mangledname^
  573. end;
  574. {****************************************************************************
  575. TLABELSYM
  576. ****************************************************************************}
  577. constructor tlabelsym.create(const n : string; l : tasmlabel);
  578. begin
  579. inherited create(n);
  580. typ:=labelsym;
  581. lab:=l;
  582. used:=false;
  583. defined:=false;
  584. code:=nil;
  585. end;
  586. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  587. begin
  588. inherited loadsym(ppufile);
  589. typ:=labelsym;
  590. { this is all dummy
  591. it is only used for local browsing }
  592. lab:=nil;
  593. code:=nil;
  594. used:=false;
  595. defined:=true;
  596. end;
  597. destructor tlabelsym.destroy;
  598. begin
  599. inherited destroy;
  600. end;
  601. procedure tlabelsym.generate_mangledname;
  602. begin
  603. _mangledname:=stringdup(lab.name);
  604. end;
  605. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  606. begin
  607. if owner.symtabletype=globalsymtable then
  608. Message(sym_e_ill_label_decl)
  609. else
  610. begin
  611. inherited writesym(ppufile);
  612. ppufile.writeentry(iblabelsym);
  613. end;
  614. end;
  615. {****************************************************************************
  616. TUNITSYM
  617. ****************************************************************************}
  618. constructor tunitsym.create(const n : string;ref : tsymtable);
  619. var
  620. old_make_ref : boolean;
  621. begin
  622. old_make_ref:=make_ref;
  623. make_ref:=false;
  624. inherited create(n);
  625. make_ref:=old_make_ref;
  626. typ:=unitsym;
  627. unitsymtable:=ref;
  628. if assigned(ref) and
  629. (ref.symtabletype=globalsymtable) then
  630. begin
  631. prevsym:=tglobalsymtable(ref).unitsym;
  632. tglobalsymtable(ref).unitsym:=self;
  633. end;
  634. end;
  635. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  636. begin
  637. inherited loadsym(ppufile);
  638. typ:=unitsym;
  639. unitsymtable:=nil;
  640. prevsym:=nil;
  641. refs:=0;
  642. end;
  643. { we need to remove it from the prevsym chain ! }
  644. procedure tunitsym.restoreunitsym;
  645. var pus,ppus : tunitsym;
  646. begin
  647. if assigned(unitsymtable) and
  648. (unitsymtable.symtabletype=globalsymtable) then
  649. begin
  650. ppus:=nil;
  651. pus:=tglobalsymtable(unitsymtable).unitsym;
  652. if pus=self then
  653. tglobalsymtable(unitsymtable).unitsym:=prevsym
  654. else while assigned(pus) do
  655. begin
  656. if pus=self then
  657. begin
  658. ppus.prevsym:=prevsym;
  659. break;
  660. end
  661. else
  662. begin
  663. ppus:=pus;
  664. pus:=ppus.prevsym;
  665. end;
  666. end;
  667. end;
  668. unitsymtable:=nil;
  669. prevsym:=nil;
  670. end;
  671. destructor tunitsym.destroy;
  672. begin
  673. restoreunitsym;
  674. inherited destroy;
  675. end;
  676. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  677. begin
  678. inherited writesym(ppufile);
  679. ppufile.writeentry(ibunitsym);
  680. end;
  681. {$ifdef GDB}
  682. procedure tunitsym.concatstabto(asmlist : taasmoutput);
  683. begin
  684. {Nothing to write to stabs !}
  685. end;
  686. {$endif GDB}
  687. {****************************************************************************
  688. TPROCSYM
  689. ****************************************************************************}
  690. constructor tprocsym.create(const n : string);
  691. begin
  692. inherited create(n);
  693. typ:=procsym;
  694. defs:=nil;
  695. owner:=nil;
  696. is_global:=false;
  697. overloadchecked:=false;
  698. overloadcount:=0;
  699. procdef_count:=0;
  700. end;
  701. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  702. var
  703. pd : tprocdef;
  704. begin
  705. inherited loadsym(ppufile);
  706. typ:=procsym;
  707. defs:=nil;
  708. procdef_count:=0;
  709. repeat
  710. pd:=tprocdef(ppufile.getderef);
  711. if pd=nil then
  712. break;
  713. addprocdef(pd);
  714. until false;
  715. is_global:=false;
  716. overloadchecked:=false;
  717. overloadcount:=-1; { invalid, not used anymore }
  718. end;
  719. destructor tprocsym.destroy;
  720. var
  721. hp,p : pprocdeflist;
  722. begin
  723. p:=defs;
  724. while assigned(p) do
  725. begin
  726. hp:=p^.next;
  727. dispose(p);
  728. p:=hp;
  729. end;
  730. inherited destroy;
  731. end;
  732. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  733. var
  734. p : pprocdeflist;
  735. begin
  736. p:=defs;
  737. while assigned(p) do
  738. begin
  739. if p^.def<>skipdef then
  740. MessagePos1(p^.def.fileinfo,sym_b_param_list,p^.def.fullprocname);
  741. p:=p^.next;
  742. end;
  743. end;
  744. procedure tprocsym.check_forward;
  745. var
  746. p : pprocdeflist;
  747. begin
  748. p:=defs;
  749. while assigned(p) do
  750. begin
  751. if (p^.def.procsym=self) and
  752. (p^.def.forwarddef) then
  753. begin
  754. MessagePos1(fileinfo,sym_e_forward_not_resolved,p^.def.fullprocname);
  755. { Turn futher error messages off }
  756. p^.def.forwarddef:=false;
  757. end;
  758. p:=p^.next;
  759. end;
  760. end;
  761. procedure tprocsym.deref;
  762. var
  763. p : pprocdeflist;
  764. begin
  765. p:=defs;
  766. while assigned(p) do
  767. begin
  768. resolvedef(pointer(p^.def));
  769. p:=p^.next;
  770. end;
  771. end;
  772. procedure tprocsym.addprocdef(p:tprocdef);
  773. var
  774. pd : pprocdeflist;
  775. begin
  776. new(pd);
  777. pd^.def:=p;
  778. pd^.next:=defs;
  779. defs:=pd;
  780. inc(procdef_count);
  781. end;
  782. function Tprocsym.getprocdef(nr:cardinal):Tprocdef;
  783. var i:cardinal;
  784. pd:Pprocdeflist;
  785. begin
  786. pd:=defs;
  787. for i:=2 to nr do
  788. pd:=pd^.next;
  789. getprocdef:=pd^.def;
  790. end;
  791. procedure Tprocsym.add_para_match_to(Aprocsym:Tprocsym);
  792. var pd:Pprocdeflist;
  793. begin
  794. pd:=defs;
  795. while assigned(pd) do
  796. begin
  797. if Aprocsym.search_procdef_bypara(pd^.def.para,false)=nil then
  798. Aprocsym.addprocdef(pd^.def);
  799. pd:=pd^.next;
  800. end;
  801. end;
  802. procedure Tprocsym.concat_procdefs_to(s:Tprocsym);
  803. var pd:Pprocdeflist;
  804. begin
  805. pd:=defs;
  806. while assigned(pd) do
  807. begin
  808. s.addprocdef(pd^.def);
  809. pd:=pd^.next;
  810. end;
  811. end;
  812. function Tprocsym.first_procdef:Tprocdef;
  813. begin
  814. first_procdef:=defs^.def;
  815. end;
  816. function Tprocsym.last_procdef:Tprocdef;
  817. var pd:Pprocdeflist;
  818. begin
  819. pd:=defs;
  820. while assigned(pd) do
  821. begin
  822. last_procdef:=pd^.def;
  823. pd:=pd^.next;
  824. end;
  825. end;
  826. procedure Tprocsym.foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  827. var p:Pprocdeflist;
  828. begin
  829. p:=defs;
  830. while assigned(p) do
  831. begin
  832. proc2call(p^.def,arg);
  833. p:=p^.next;
  834. end;
  835. end;
  836. function Tprocsym.search_procdef_nopara_boolret:Tprocdef;
  837. var p:Pprocdeflist;
  838. begin
  839. search_procdef_nopara_boolret:=nil;
  840. p:=defs;
  841. while p<>nil do
  842. begin
  843. if p^.def.para.empty and is_boolean(p^.def.rettype.def) then
  844. begin
  845. search_procdef_nopara_boolret:=p^.def;
  846. break;
  847. end;
  848. p:=p^.next;
  849. end;
  850. end;
  851. function Tprocsym.search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  852. var p:Pprocdeflist;
  853. begin
  854. search_procdef_bytype:=nil;
  855. p:=defs;
  856. while p<>nil do
  857. begin
  858. if p^.def.proctypeoption=pt then
  859. begin
  860. search_procdef_bytype:=p^.def;
  861. break;
  862. end;
  863. p:=p^.next;
  864. end;
  865. end;
  866. function Tprocsym.search_procdef_bypara(params:Tparalinkedlist;
  867. allowconvert:boolean):Tprocdef;
  868. var pd:Pprocdeflist;
  869. begin
  870. search_procdef_bypara:=nil;
  871. pd:=defs;
  872. while assigned(pd) do
  873. begin
  874. if equal_paras(pd^.def.para,params,cp_value_equal_const) or
  875. (allowconvert and convertable_paras(pd^.def.para,params,
  876. cp_value_equal_const)) then
  877. begin
  878. search_procdef_bypara:=pd^.def;
  879. break;
  880. end;
  881. pd:=pd^.next;
  882. end;
  883. end;
  884. function Tprocsym.search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  885. var pd:Pprocdeflist;
  886. begin
  887. {This function will return the pprocdef of pprocsym that
  888. is the best match for procvardef. When there are multiple
  889. matches it returns nil.}
  890. {Try to find an exact match first.}
  891. search_procdef_byprocvardef:=nil;
  892. pd:=defs;
  893. while assigned(pd) do
  894. begin
  895. if proc_to_procvar_equal(pd^.def,d,true) then
  896. begin
  897. { already found a match ? Then stop and return nil }
  898. if assigned(search_procdef_byprocvardef) then
  899. begin
  900. search_procdef_byprocvardef:=nil;
  901. break;
  902. end;
  903. search_procdef_byprocvardef:=pd^.def;
  904. end;
  905. pd:=pd^.next;
  906. end;
  907. {Try a convertable match, if no exact match was found.}
  908. if not assigned(search_procdef_byprocvardef) and not assigned(pd) then
  909. begin
  910. pd:=defs;
  911. while assigned(pd) do
  912. begin
  913. if proc_to_procvar_equal(pd^.def,d,false) then
  914. begin
  915. { already found a match ? Then stop and return nil }
  916. if assigned(search_procdef_byprocvardef) then
  917. begin
  918. search_procdef_byprocvardef:=nil;
  919. break;
  920. end;
  921. search_procdef_byprocvardef:=pd^.def;
  922. end;
  923. pd:=pd^.next;
  924. end;
  925. end;
  926. end;
  927. function Tprocsym.search_procdef_by1paradef(firstpara:Tdef):Tprocdef;
  928. var pd:Pprocdeflist;
  929. begin
  930. search_procdef_by1paradef:=nil;
  931. pd:=defs;
  932. while assigned(pd) do
  933. begin
  934. if is_equal(Tparaitem(pd^.def.para.first).paratype.def,firstpara) and
  935. (Tparaitem(pd^.def.para.first).next=nil) then
  936. begin
  937. search_procdef_by1paradef:=pd^.def;
  938. break;
  939. end;
  940. pd:=pd^.next;
  941. end;
  942. end;
  943. function Tprocsym.search_procdef_byretdef_by1paradef(retdef,firstpara:Tdef;
  944. matchtype:Tdefmatch):Tprocdef;
  945. var pd:Pprocdeflist;
  946. convtyp:Tconverttype;
  947. a,b:boolean;
  948. begin
  949. search_procdef_byretdef_by1paradef:=nil;
  950. pd:=defs;
  951. while assigned(pd) do
  952. begin
  953. a:=is_equal(retdef,pd^.def.rettype.def);
  954. {Alert alert alert alert alert alert alert!!!
  955. Make sure you never call isconvertable when a=false. You get
  956. endless recursion then. Originally a and b were placed in a
  957. single if statement. There was only one reason that it worked:
  958. short circuit boolean eval.}
  959. if a then
  960. case matchtype of
  961. dm_exact:
  962. b:=TParaItem(pd^.def.para.first).paratype.def=firstpara;
  963. dm_equal:
  964. b:=is_equal(Tparaitem(pd^.def.para.first).paratype.def,firstpara);
  965. dm_convertl1:
  966. b:=isconvertable(firstpara,Tparaitem(pd^.def.para.first).paratype.def,
  967. convtyp,ordconstn,false)=1;
  968. end;
  969. if a and b then
  970. begin
  971. search_procdef_byretdef_by1paradef:=pd^.def;
  972. break;
  973. end;
  974. pd:=pd^.next;
  975. end;
  976. end;
  977. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  978. var
  979. p : pprocdeflist;
  980. begin
  981. inherited writesym(ppufile);
  982. p:=defs;
  983. while assigned(p) do
  984. begin
  985. { only write the proc definitions that belong
  986. to this procsym }
  987. if (p^.def.procsym=self) then
  988. ppufile.putderef(p^.def);
  989. p:=p^.next;
  990. end;
  991. ppufile.putderef(nil);
  992. ppufile.writeentry(ibprocsym);
  993. end;
  994. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  995. var
  996. p : pprocdeflist;
  997. begin
  998. write_references:=false;
  999. if not inherited write_references(ppufile,locals) then
  1000. exit;
  1001. write_references:=true;
  1002. p:=defs;
  1003. while assigned(p) do
  1004. begin
  1005. if (p^.def.procsym=self) then
  1006. p^.def.write_references(ppufile,locals);
  1007. p:=p^.next;
  1008. end;
  1009. end;
  1010. procedure tprocsym.unchain_overload;
  1011. var
  1012. p,hp,
  1013. first,
  1014. last : pprocdeflist;
  1015. begin
  1016. { remove all overloaded procdefs from the
  1017. procdeflist that are not in the current symtable }
  1018. first:=nil;
  1019. last:=nil;
  1020. p:=defs;
  1021. while assigned(p) do
  1022. begin
  1023. hp:=p^.next;
  1024. if (p^.def.procsym=self) then
  1025. begin
  1026. { keep in list }
  1027. if not assigned(first) then
  1028. begin
  1029. first:=p;
  1030. last:=p;
  1031. end
  1032. else
  1033. last^.next:=p;
  1034. last:=p;
  1035. p^.next:=nil;
  1036. end
  1037. else
  1038. begin
  1039. { remove }
  1040. dispose(p);
  1041. dec(procdef_count);
  1042. end;
  1043. p:=hp;
  1044. end;
  1045. defs:=first;
  1046. end;
  1047. {$ifdef GDB}
  1048. function tprocsym.stabstring : pchar;
  1049. begin
  1050. internalerror(200111171);
  1051. stabstring:=nil;
  1052. end;
  1053. procedure tprocsym.concatstabto(asmlist : taasmoutput);
  1054. begin
  1055. internalerror(200111172);
  1056. end;
  1057. {$endif GDB}
  1058. {****************************************************************************
  1059. TERRORSYM
  1060. ****************************************************************************}
  1061. constructor terrorsym.create;
  1062. begin
  1063. inherited create('');
  1064. typ:=errorsym;
  1065. end;
  1066. {****************************************************************************
  1067. TPROPERTYSYM
  1068. ****************************************************************************}
  1069. constructor tpropertysym.create(const n : string);
  1070. begin
  1071. inherited create(n);
  1072. typ:=propertysym;
  1073. propoptions:=[];
  1074. index:=0;
  1075. default:=0;
  1076. proptype.reset;
  1077. indextype.reset;
  1078. readaccess:=tsymlist.create;
  1079. writeaccess:=tsymlist.create;
  1080. storedaccess:=tsymlist.create;
  1081. end;
  1082. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  1083. begin
  1084. inherited loadsym(ppufile);
  1085. typ:=propertysym;
  1086. ppufile.getsmallset(propoptions);
  1087. if (ppo_is_override in propoptions) then
  1088. begin
  1089. propoverriden:=tpropertysym(ppufile.getderef);
  1090. { we need to have these objects initialized }
  1091. readaccess:=tsymlist.create;
  1092. writeaccess:=tsymlist.create;
  1093. storedaccess:=tsymlist.create;
  1094. end
  1095. else
  1096. begin
  1097. ppufile.gettype(proptype);
  1098. index:=ppufile.getlongint;
  1099. default:=ppufile.getlongint;
  1100. ppufile.gettype(indextype);
  1101. readaccess:=ppufile.getsymlist;
  1102. writeaccess:=ppufile.getsymlist;
  1103. storedaccess:=ppufile.getsymlist;
  1104. end;
  1105. end;
  1106. destructor tpropertysym.destroy;
  1107. begin
  1108. readaccess.free;
  1109. writeaccess.free;
  1110. storedaccess.free;
  1111. inherited destroy;
  1112. end;
  1113. function tpropertysym.gettypedef:tdef;
  1114. begin
  1115. gettypedef:=proptype.def;
  1116. end;
  1117. procedure tpropertysym.deref;
  1118. begin
  1119. if (ppo_is_override in propoptions) then
  1120. begin
  1121. resolvesym(pointer(propoverriden));
  1122. dooverride(propoverriden);
  1123. end
  1124. else
  1125. begin
  1126. proptype.resolve;
  1127. indextype.resolve;
  1128. readaccess.resolve;
  1129. writeaccess.resolve;
  1130. storedaccess.resolve;
  1131. end;
  1132. end;
  1133. function tpropertysym.getsize : longint;
  1134. begin
  1135. getsize:=0;
  1136. end;
  1137. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  1138. begin
  1139. inherited writesym(ppufile);
  1140. ppufile.putsmallset(propoptions);
  1141. if (ppo_is_override in propoptions) then
  1142. ppufile.putderef(propoverriden)
  1143. else
  1144. begin
  1145. ppufile.puttype(proptype);
  1146. ppufile.putlongint(index);
  1147. ppufile.putlongint(default);
  1148. ppufile.puttype(indextype);
  1149. ppufile.putsymlist(readaccess);
  1150. ppufile.putsymlist(writeaccess);
  1151. ppufile.putsymlist(storedaccess);
  1152. end;
  1153. ppufile.writeentry(ibpropertysym);
  1154. end;
  1155. procedure tpropertysym.dooverride(overriden:tpropertysym);
  1156. begin
  1157. propoverriden:=overriden;
  1158. proptype:=overriden.proptype;
  1159. propoptions:=overriden.propoptions+[ppo_is_override];
  1160. index:=overriden.index;
  1161. default:=overriden.default;
  1162. indextype:=overriden.indextype;
  1163. readaccess.free;
  1164. readaccess:=overriden.readaccess.getcopy;
  1165. writeaccess.free;
  1166. writeaccess:=overriden.writeaccess.getcopy;
  1167. storedaccess.free;
  1168. storedaccess:=overriden.storedaccess.getcopy;
  1169. end;
  1170. {$ifdef GDB}
  1171. function tpropertysym.stabstring : pchar;
  1172. begin
  1173. { !!!! don't know how to handle }
  1174. stabstring:=strpnew('');
  1175. end;
  1176. procedure tpropertysym.concatstabto(asmlist : taasmoutput);
  1177. begin
  1178. { !!!! don't know how to handle }
  1179. end;
  1180. {$endif GDB}
  1181. {****************************************************************************
  1182. TFUNCRETSYM
  1183. ****************************************************************************}
  1184. constructor tfuncretsym.create(const n : string;const tt:ttype);
  1185. begin
  1186. inherited create(n);
  1187. typ:=funcretsym;
  1188. returntype:=tt;
  1189. funcretstate:=vs_declared;
  1190. { address valid for ret in param only }
  1191. { otherwise set by insert }
  1192. address:=procinfo.return_offset;
  1193. end;
  1194. constructor tfuncretsym.ppuload(ppufile:tcompilerppufile);
  1195. begin
  1196. inherited loadsym(ppufile);
  1197. ppufile.gettype(returntype);
  1198. address:=ppufile.getlongint;
  1199. typ:=funcretsym;
  1200. end;
  1201. destructor tfuncretsym.destroy;
  1202. begin
  1203. inherited destroy;
  1204. end;
  1205. procedure tfuncretsym.ppuwrite(ppufile:tcompilerppufile);
  1206. begin
  1207. inherited writesym(ppufile);
  1208. ppufile.puttype(returntype);
  1209. ppufile.putlongint(address);
  1210. ppufile.writeentry(ibfuncretsym);
  1211. funcretstate:=vs_used;
  1212. end;
  1213. procedure tfuncretsym.deref;
  1214. begin
  1215. returntype.resolve;
  1216. end;
  1217. {$ifdef GDB}
  1218. procedure tfuncretsym.concatstabto(asmlist : taasmoutput);
  1219. begin
  1220. { Nothing to do here, it is done in genexitcode }
  1221. end;
  1222. {$endif GDB}
  1223. {****************************************************************************
  1224. TABSOLUTESYM
  1225. ****************************************************************************}
  1226. constructor tabsolutesym.create(const n : string;const tt : ttype);
  1227. begin
  1228. inherited create(n,tt);
  1229. typ:=absolutesym;
  1230. end;
  1231. constructor tabsolutesym.ppuload(ppufile:tcompilerppufile);
  1232. begin
  1233. { Note: This needs to load everything of tvarsym.write }
  1234. inherited ppuload(ppufile);
  1235. { load absolute }
  1236. typ:=absolutesym;
  1237. ref:=nil;
  1238. address:=0;
  1239. asmname:=nil;
  1240. abstyp:=absolutetyp(ppufile.getbyte);
  1241. absseg:=false;
  1242. case abstyp of
  1243. tovar :
  1244. asmname:=stringdup(ppufile.getstring);
  1245. toasm :
  1246. asmname:=stringdup(ppufile.getstring);
  1247. toaddr :
  1248. begin
  1249. address:=ppufile.getlongint;
  1250. absseg:=boolean(ppufile.getbyte);
  1251. end;
  1252. end;
  1253. end;
  1254. procedure tabsolutesym.ppuwrite(ppufile:tcompilerppufile);
  1255. var
  1256. hvo : tvaroptions;
  1257. begin
  1258. { Note: This needs to write everything of tvarsym.write }
  1259. inherited writesym(ppufile);
  1260. ppufile.putbyte(byte(varspez));
  1261. ppufile.putlongint(address);
  1262. { write only definition or definitionsym }
  1263. ppufile.puttype(vartype);
  1264. hvo:=varoptions-[vo_regable];
  1265. ppufile.putsmallset(hvo);
  1266. ppufile.putbyte(byte(abstyp));
  1267. case abstyp of
  1268. tovar :
  1269. ppufile.putstring(ref.name);
  1270. toasm :
  1271. ppufile.putstring(asmname^);
  1272. toaddr :
  1273. begin
  1274. ppufile.putlongint(address);
  1275. ppufile.putbyte(byte(absseg));
  1276. end;
  1277. end;
  1278. ppufile.writeentry(ibabsolutesym);
  1279. end;
  1280. procedure tabsolutesym.deref;
  1281. var
  1282. srsym : tsym;
  1283. srsymtable : tsymtable;
  1284. begin
  1285. { inheritance of varsym.deref ! }
  1286. vartype.resolve;
  1287. { own absolute deref }
  1288. if (abstyp=tovar) and (asmname<>nil) then
  1289. begin
  1290. { search previous loaded symtables }
  1291. searchsym(asmname^,srsym,srsymtable);
  1292. if not assigned(srsym) then
  1293. srsym:=searchsymonlyin(owner,asmname^);
  1294. if not assigned(srsym) then
  1295. srsym:=generrorsym;
  1296. ref:=tstoredsym(srsym);
  1297. stringdispose(asmname);
  1298. end;
  1299. end;
  1300. function tabsolutesym.mangledname : string;
  1301. begin
  1302. case abstyp of
  1303. tovar :
  1304. begin
  1305. case ref.typ of
  1306. varsym :
  1307. mangledname:=tvarsym(ref).mangledname;
  1308. else
  1309. internalerror(200111011);
  1310. end;
  1311. end;
  1312. toasm :
  1313. mangledname:=asmname^;
  1314. toaddr :
  1315. mangledname:='$'+tostr(address);
  1316. else
  1317. internalerror(10002);
  1318. end;
  1319. end;
  1320. {$ifdef GDB}
  1321. procedure tabsolutesym.concatstabto(asmlist : taasmoutput);
  1322. begin
  1323. { I don't know how to handle this !! }
  1324. end;
  1325. {$endif GDB}
  1326. {****************************************************************************
  1327. TVARSYM
  1328. ****************************************************************************}
  1329. constructor tvarsym.create(const n : string;const tt : ttype);
  1330. begin
  1331. inherited create(n);
  1332. typ:=varsym;
  1333. vartype:=tt;
  1334. _mangledname:=nil;
  1335. varspez:=vs_value;
  1336. address:=0;
  1337. localvarsym:=nil;
  1338. refs:=0;
  1339. varstate:=vs_used;
  1340. varoptions:=[];
  1341. { can we load the value into a register ? }
  1342. if tstoreddef(tt.def).is_intregable then
  1343. include(varoptions,vo_regable)
  1344. else
  1345. exclude(varoptions,vo_regable);
  1346. if tstoreddef(tt.def).is_fpuregable then
  1347. include(varoptions,vo_fpuregable)
  1348. else
  1349. exclude(varoptions,vo_fpuregable);
  1350. reg:=R_NO;
  1351. end;
  1352. constructor tvarsym.create_dll(const n : string;const tt : ttype);
  1353. begin
  1354. tvarsym(self).create(n,tt);
  1355. include(varoptions,vo_is_dll_var);
  1356. end;
  1357. constructor tvarsym.create_C(const n,mangled : string;const tt : ttype);
  1358. begin
  1359. tvarsym(self).create(n,tt);
  1360. include(varoptions,vo_is_C_var);
  1361. stringdispose(_mangledname);
  1362. _mangledname:=stringdup(mangled);
  1363. end;
  1364. constructor tvarsym.ppuload(ppufile:tcompilerppufile);
  1365. begin
  1366. inherited loadsym(ppufile);
  1367. typ:=varsym;
  1368. reg:=R_NO;
  1369. refs := 0;
  1370. varstate:=vs_used;
  1371. varspez:=tvarspez(ppufile.getbyte);
  1372. address:=ppufile.getlongint;
  1373. localvarsym:=nil;
  1374. ppufile.gettype(vartype);
  1375. ppufile.getsmallset(varoptions);
  1376. if (vo_is_C_var in varoptions) then
  1377. _mangledname:=stringdup(ppufile.getstring);
  1378. end;
  1379. destructor tvarsym.destroy;
  1380. begin
  1381. {$ifdef var_notification}
  1382. if assigned(notifications) then
  1383. notifications.destroy;
  1384. {$endif}
  1385. inherited destroy;
  1386. end;
  1387. procedure tvarsym.deref;
  1388. begin
  1389. vartype.resolve;
  1390. end;
  1391. procedure tvarsym.ppuwrite(ppufile:tcompilerppufile);
  1392. var
  1393. hvo : tvaroptions;
  1394. begin
  1395. inherited writesym(ppufile);
  1396. ppufile.putbyte(byte(varspez));
  1397. ppufile.putlongint(address);
  1398. ppufile.puttype(vartype);
  1399. { symbols which are load are never candidates for a register,
  1400. turn off the regable }
  1401. hvo:=varoptions-[vo_regable,vo_fpuregable];
  1402. ppufile.putsmallset(hvo);
  1403. if (vo_is_C_var in varoptions) then
  1404. ppufile.putstring(mangledname);
  1405. ppufile.writeentry(ibvarsym);
  1406. end;
  1407. procedure tvarsym.generate_mangledname;
  1408. begin
  1409. _mangledname:=stringdup(mangledname_prefix('U',owner)+name);
  1410. end;
  1411. procedure tvarsym.set_mangledname(const s:string);
  1412. begin
  1413. stringdispose(_mangledname);
  1414. _mangledname:=stringdup(s);
  1415. end;
  1416. function tvarsym.getsize : longint;
  1417. begin
  1418. if assigned(vartype.def) then
  1419. getsize:=vartype.def.size
  1420. else
  1421. getsize:=0;
  1422. end;
  1423. function tvarsym.getvaluesize : longint;
  1424. begin
  1425. if assigned(vartype.def) and
  1426. (varspez=vs_value) and
  1427. ((vartype.def.deftype<>arraydef) or
  1428. tarraydef(vartype.def).isDynamicArray or
  1429. (tarraydef(vartype.def).highrange>=tarraydef(vartype.def).lowrange)) then
  1430. getvaluesize:=vartype.def.size
  1431. else
  1432. getvaluesize:=0;
  1433. end;
  1434. function tvarsym.getpushsize(is_cdecl:boolean) : longint;
  1435. begin
  1436. getpushsize:=-1;
  1437. if assigned(vartype.def) then
  1438. begin
  1439. case varspez of
  1440. vs_out,
  1441. vs_var :
  1442. getpushsize:=pointer_size;
  1443. vs_value,
  1444. vs_const :
  1445. begin
  1446. if paramanager.push_addr_param(vartype.def,is_cdecl) then
  1447. getpushsize:=pointer_size
  1448. else
  1449. getpushsize:=vartype.def.size;
  1450. end;
  1451. end;
  1452. end;
  1453. end;
  1454. {$ifdef var_notification}
  1455. function Tvarsym.register_notification(flags:Tnotification_flags;callback:
  1456. Tnotification_callback):cardinal;
  1457. var n:Tnotification;
  1458. begin
  1459. if not assigned(notifications) then
  1460. notifications:=Tlinkedlist.create;
  1461. n:=Tnotification.create(flags,callback);
  1462. register_notification:=n.id;
  1463. notifications.concat(n);
  1464. end;
  1465. {$endif}
  1466. {$ifdef GDB}
  1467. function tvarsym.stabstring : pchar;
  1468. var
  1469. st : string;
  1470. is_cdecl : boolean;
  1471. begin
  1472. st:=tstoreddef(vartype.def).numberstring;
  1473. if (owner.symtabletype = objectsymtable) and
  1474. (sp_static in symoptions) then
  1475. begin
  1476. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1477. stabstring := strpnew('"'+upper(owner.name^)+'__'+name+':'+st+
  1478. '",'+
  1479. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1480. end
  1481. else if (owner.symtabletype = globalsymtable) then
  1482. begin
  1483. { Here we used S instead of
  1484. because with G GDB doesn't look at the address field
  1485. but searches the same name or with a leading underscore
  1486. but these names don't exist in pascal !}
  1487. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1488. stabstring := strpnew('"'+name+':'+st+'",'+
  1489. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1490. end
  1491. else if owner.symtabletype = staticsymtable then
  1492. begin
  1493. stabstring := strpnew('"'+name+':S'+st+'",'+
  1494. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1495. end
  1496. else if (owner.symtabletype in [parasymtable,inlineparasymtable]) then
  1497. begin
  1498. is_cdecl:=(tprocdef(owner.defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]);
  1499. case varspez of
  1500. vs_out,
  1501. vs_var : st := 'v'+st;
  1502. vs_value,
  1503. vs_const : if paramanager.push_addr_param(vartype.def,is_cdecl) then
  1504. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1505. else
  1506. st := 'p'+st;
  1507. end;
  1508. stabstring := strpnew('"'+name+':'+st+'",'+
  1509. tostr(N_tsym)+',0,'+tostr(fileinfo.line)+','+
  1510. tostr(address+owner.address_fixup));
  1511. {offset to ebp => will not work if the framepointer is esp
  1512. so some optimizing will make things harder to debug }
  1513. end
  1514. else if (owner.symtabletype in [localsymtable,inlinelocalsymtable]) then
  1515. if reg<>R_NO then
  1516. begin
  1517. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1518. { this is the register order for GDB}
  1519. stabstring:=strpnew('"'+name+':r'+st+'",'+
  1520. tostr(N_RSYM)+',0,'+
  1521. tostr(fileinfo.line)+','+tostr(stab_regindex[reg]));
  1522. end
  1523. else
  1524. { I don't know if this will work (PM) }
  1525. if (vo_is_C_var in varoptions) then
  1526. stabstring := strpnew('"'+name+':S'+st+'",'+
  1527. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname)
  1528. else
  1529. stabstring := strpnew('"'+name+':'+st+'",'+
  1530. tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',-'+tostr(address-owner.address_fixup))
  1531. else
  1532. stabstring := inherited stabstring;
  1533. end;
  1534. procedure tvarsym.concatstabto(asmlist : taasmoutput);
  1535. var stab_str : pchar;
  1536. begin
  1537. inherited concatstabto(asmlist);
  1538. if (owner.symtabletype=parasymtable) and
  1539. (reg<>R_NO) then
  1540. begin
  1541. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1542. { this is the register order for GDB}
  1543. stab_str:=strpnew('"'+name+':r'
  1544. +tstoreddef(vartype.def).numberstring+'",'+
  1545. tostr(N_RSYM)+',0,'+
  1546. tostr(fileinfo.line)+','+tostr(stab_regindex[reg]));
  1547. asmList.concat(Tai_stabs.Create(stab_str));
  1548. end;
  1549. end;
  1550. {$endif GDB}
  1551. {****************************************************************************
  1552. TTYPEDCONSTSYM
  1553. *****************************************************************************}
  1554. constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
  1555. begin
  1556. inherited create(n);
  1557. typ:=typedconstsym;
  1558. typedconsttype.setdef(p);
  1559. is_writable:=writable;
  1560. end;
  1561. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
  1562. begin
  1563. inherited create(n);
  1564. typ:=typedconstsym;
  1565. typedconsttype:=tt;
  1566. is_writable:=writable;
  1567. end;
  1568. constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
  1569. begin
  1570. inherited loadsym(ppufile);
  1571. typ:=typedconstsym;
  1572. ppufile.gettype(typedconsttype);
  1573. is_writable:=boolean(ppufile.getbyte);
  1574. end;
  1575. destructor ttypedconstsym.destroy;
  1576. begin
  1577. inherited destroy;
  1578. end;
  1579. procedure ttypedconstsym.generate_mangledname;
  1580. begin
  1581. _mangledname:=stringdup(mangledname_prefix('TC',owner)+name);
  1582. end;
  1583. function ttypedconstsym.getsize : longint;
  1584. begin
  1585. if assigned(typedconsttype.def) then
  1586. getsize:=typedconsttype.def.size
  1587. else
  1588. getsize:=0;
  1589. end;
  1590. procedure ttypedconstsym.deref;
  1591. begin
  1592. typedconsttype.resolve;
  1593. end;
  1594. procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
  1595. begin
  1596. inherited writesym(ppufile);
  1597. ppufile.puttype(typedconsttype);
  1598. ppufile.putbyte(byte(is_writable));
  1599. ppufile.writeentry(ibtypedconstsym);
  1600. end;
  1601. {$ifdef GDB}
  1602. function ttypedconstsym.stabstring : pchar;
  1603. var
  1604. st : char;
  1605. begin
  1606. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1607. st := 'G'
  1608. else
  1609. st := 'S';
  1610. stabstring := strpnew('"'+name+':'+st+
  1611. tstoreddef(typedconsttype.def).numberstring+'",'+tostr(n_STSYM)+',0,'+
  1612. tostr(fileinfo.line)+','+mangledname);
  1613. end;
  1614. {$endif GDB}
  1615. {****************************************************************************
  1616. TCONSTSYM
  1617. ****************************************************************************}
  1618. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : TConstExprInt);
  1619. begin
  1620. inherited create(n);
  1621. typ:=constsym;
  1622. consttyp:=t;
  1623. valueord:=v;
  1624. valueordptr:=0;
  1625. valueptr:=nil;
  1626. ResStrIndex:=0;
  1627. consttype.reset;
  1628. len:=0;
  1629. end;
  1630. constructor tconstsym.create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1631. begin
  1632. inherited create(n);
  1633. typ:=constsym;
  1634. consttyp:=t;
  1635. valueord:=v;
  1636. valueordptr:=0;
  1637. valueptr:=nil;
  1638. ResStrIndex:=0;
  1639. consttype:=tt;
  1640. len:=0;
  1641. end;
  1642. constructor tconstsym.create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1643. begin
  1644. inherited create(n);
  1645. typ:=constsym;
  1646. consttyp:=t;
  1647. valueord:=0;
  1648. valueordptr:=v;
  1649. valueptr:=nil;
  1650. ResStrIndex:=0;
  1651. consttype:=tt;
  1652. len:=0;
  1653. end;
  1654. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer);
  1655. begin
  1656. inherited create(n);
  1657. typ:=constsym;
  1658. consttyp:=t;
  1659. valueord:=0;
  1660. valueordptr:=0;
  1661. valueptr:=v;
  1662. ResStrIndex:=0;
  1663. consttype.reset;
  1664. len:=0;
  1665. end;
  1666. constructor tconstsym.create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1667. begin
  1668. inherited create(n);
  1669. typ:=constsym;
  1670. consttyp:=t;
  1671. valueord:=0;
  1672. valueordptr:=0;
  1673. valueptr:=v;
  1674. ResStrIndex:=0;
  1675. consttype:=tt;
  1676. len:=0;
  1677. end;
  1678. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1679. begin
  1680. inherited create(n);
  1681. typ:=constsym;
  1682. consttyp:=t;
  1683. valueord:=0;
  1684. valueordptr:=0;
  1685. valueptr:=str;
  1686. consttype.reset;
  1687. len:=l;
  1688. if t=constresourcestring then
  1689. ResStrIndex:=ResourceStrings.Register(name,pchar(valueptr),len);
  1690. end;
  1691. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1692. var
  1693. pd : pbestreal;
  1694. ps : pnormalset;
  1695. pc : pchar;
  1696. begin
  1697. inherited loadsym(ppufile);
  1698. typ:=constsym;
  1699. consttype.reset;
  1700. consttyp:=tconsttyp(ppufile.getbyte);
  1701. valueord:=0;
  1702. valueordptr:=0;
  1703. valueptr:=nil;
  1704. case consttyp of
  1705. constint:
  1706. valueord:=ppufile.getexprint;
  1707. constwchar,
  1708. constbool,
  1709. constchar :
  1710. valueord:=ppufile.getlongint;
  1711. constord :
  1712. begin
  1713. ppufile.gettype(consttype);
  1714. valueord:=ppufile.getexprint;
  1715. end;
  1716. constpointer :
  1717. begin
  1718. ppufile.gettype(consttype);
  1719. valueordptr:=ppufile.getptruint;
  1720. end;
  1721. conststring,
  1722. constresourcestring :
  1723. begin
  1724. len:=ppufile.getlongint;
  1725. getmem(pc,len+1);
  1726. ppufile.getdata(pc^,len);
  1727. if consttyp=constresourcestring then
  1728. ResStrIndex:=ppufile.getlongint;
  1729. valueptr:=pc;
  1730. end;
  1731. constreal :
  1732. begin
  1733. new(pd);
  1734. pd^:=ppufile.getreal;
  1735. valueptr:=pd;
  1736. end;
  1737. constset :
  1738. begin
  1739. ppufile.gettype(consttype);
  1740. new(ps);
  1741. ppufile.getnormalset(ps^);
  1742. valueptr:=ps;
  1743. end;
  1744. constnil : ;
  1745. else
  1746. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1747. end;
  1748. end;
  1749. destructor tconstsym.destroy;
  1750. begin
  1751. case consttyp of
  1752. conststring,
  1753. constresourcestring :
  1754. freemem(pchar(valueptr),len+1);
  1755. constreal :
  1756. dispose(pbestreal(valueptr));
  1757. constset :
  1758. dispose(pnormalset(valueptr));
  1759. end;
  1760. inherited destroy;
  1761. end;
  1762. function tconstsym.mangledname : string;
  1763. begin
  1764. mangledname:=name;
  1765. end;
  1766. procedure tconstsym.deref;
  1767. begin
  1768. if consttyp in [constord,constpointer,constset] then
  1769. consttype.resolve;
  1770. end;
  1771. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1772. begin
  1773. inherited writesym(ppufile);
  1774. ppufile.putbyte(byte(consttyp));
  1775. case consttyp of
  1776. constnil : ;
  1777. constint:
  1778. ppufile.putexprint(valueord);
  1779. constbool,
  1780. constchar :
  1781. ppufile.putlongint(valueord);
  1782. constord :
  1783. begin
  1784. ppufile.puttype(consttype);
  1785. ppufile.putexprint(valueord);
  1786. end;
  1787. constpointer :
  1788. begin
  1789. ppufile.puttype(consttype);
  1790. ppufile.putptruint(valueordptr);
  1791. end;
  1792. conststring,
  1793. constresourcestring :
  1794. begin
  1795. ppufile.putlongint(len);
  1796. ppufile.putdata(pchar(valueptr)^,len);
  1797. if consttyp=constresourcestring then
  1798. ppufile.putlongint(ResStrIndex);
  1799. end;
  1800. constreal :
  1801. ppufile.putreal(pbestreal(valueptr)^);
  1802. constset :
  1803. begin
  1804. ppufile.puttype(consttype);
  1805. ppufile.putnormalset(valueptr^);
  1806. end;
  1807. else
  1808. internalerror(13);
  1809. end;
  1810. ppufile.writeentry(ibconstsym);
  1811. end;
  1812. {$ifdef GDB}
  1813. function tconstsym.stabstring : pchar;
  1814. var st : string;
  1815. begin
  1816. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1817. case consttyp of
  1818. conststring : begin
  1819. st := 's'''+strpas(pchar(valueptr))+'''';
  1820. end;
  1821. constbool,
  1822. constint,
  1823. constord,
  1824. constchar : st := 'i'+int64tostr(valueord);
  1825. constpointer :
  1826. st := 'i'+int64tostr(valueordptr);
  1827. constreal : begin
  1828. system.str(pbestreal(valueptr)^,st);
  1829. st := 'r'+st;
  1830. end;
  1831. { if we don't know just put zero !! }
  1832. else st:='i0';
  1833. {***SETCONST}
  1834. {constset:;} {*** I don't know what to do with a set.}
  1835. { sets are not recognized by GDB}
  1836. {***}
  1837. end;
  1838. stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
  1839. tostr(fileinfo.line)+',0');
  1840. end;
  1841. procedure tconstsym.concatstabto(asmlist : taasmoutput);
  1842. begin
  1843. if consttyp <> conststring then
  1844. inherited concatstabto(asmlist);
  1845. end;
  1846. {$endif GDB}
  1847. {****************************************************************************
  1848. TENUMSYM
  1849. ****************************************************************************}
  1850. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1851. begin
  1852. inherited create(n);
  1853. typ:=enumsym;
  1854. definition:=def;
  1855. value:=v;
  1856. { check for jumps }
  1857. if v>def.max+1 then
  1858. def.has_jumps:=true;
  1859. { update low and high }
  1860. if def.min>v then
  1861. def.setmin(v);
  1862. if def.max<v then
  1863. def.setmax(v);
  1864. order;
  1865. end;
  1866. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  1867. begin
  1868. inherited loadsym(ppufile);
  1869. typ:=enumsym;
  1870. definition:=tenumdef(ppufile.getderef);
  1871. value:=ppufile.getlongint;
  1872. nextenum := Nil;
  1873. end;
  1874. procedure tenumsym.deref;
  1875. begin
  1876. resolvedef(pointer(definition));
  1877. order;
  1878. end;
  1879. procedure tenumsym.order;
  1880. var
  1881. sym : tenumsym;
  1882. begin
  1883. sym := tenumsym(definition.firstenum);
  1884. if sym = nil then
  1885. begin
  1886. definition.firstenum := self;
  1887. nextenum := nil;
  1888. exit;
  1889. end;
  1890. { reorder the symbols in increasing value }
  1891. if value < sym.value then
  1892. begin
  1893. nextenum := sym;
  1894. definition.firstenum := self;
  1895. end
  1896. else
  1897. begin
  1898. while (sym.value <= value) and assigned(sym.nextenum) do
  1899. sym := sym.nextenum;
  1900. nextenum := sym.nextenum;
  1901. sym.nextenum := self;
  1902. end;
  1903. end;
  1904. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  1905. begin
  1906. inherited writesym(ppufile);
  1907. ppufile.putderef(definition);
  1908. ppufile.putlongint(value);
  1909. ppufile.writeentry(ibenumsym);
  1910. end;
  1911. {$ifdef GDB}
  1912. procedure tenumsym.concatstabto(asmlist : taasmoutput);
  1913. begin
  1914. {enum elements have no stab !}
  1915. end;
  1916. {$EndIf GDB}
  1917. {****************************************************************************
  1918. TTYPESYM
  1919. ****************************************************************************}
  1920. constructor ttypesym.create(const n : string;const tt : ttype);
  1921. begin
  1922. inherited create(n);
  1923. typ:=typesym;
  1924. restype:=tt;
  1925. {$ifdef GDB}
  1926. isusedinstab := false;
  1927. {$endif GDB}
  1928. { register the typesym for the definition }
  1929. if assigned(restype.def) and
  1930. (restype.def.deftype<>errordef) and
  1931. not(assigned(restype.def.typesym)) then
  1932. restype.def.typesym:=self;
  1933. end;
  1934. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  1935. begin
  1936. inherited loadsym(ppufile);
  1937. typ:=typesym;
  1938. {$ifdef GDB}
  1939. isusedinstab := false;
  1940. {$endif GDB}
  1941. ppufile.gettype(restype);
  1942. end;
  1943. function ttypesym.gettypedef:tdef;
  1944. begin
  1945. gettypedef:=restype.def;
  1946. end;
  1947. procedure ttypesym.deref;
  1948. begin
  1949. restype.resolve;
  1950. end;
  1951. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  1952. begin
  1953. inherited writesym(ppufile);
  1954. ppufile.puttype(restype);
  1955. ppufile.writeentry(ibtypesym);
  1956. end;
  1957. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  1958. begin
  1959. inherited load_references(ppufile,locals);
  1960. if (restype.def.deftype=recorddef) then
  1961. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  1962. if (restype.def.deftype=objectdef) then
  1963. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  1964. end;
  1965. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  1966. begin
  1967. if not inherited write_references(ppufile,locals) then
  1968. begin
  1969. { write address of this symbol if record or object
  1970. even if no real refs are there
  1971. because we need it for the symtable }
  1972. if (restype.def.deftype in [recorddef,objectdef]) then
  1973. begin
  1974. ppufile.putderef(self);
  1975. ppufile.writeentry(ibsymref);
  1976. end;
  1977. end;
  1978. write_references:=true;
  1979. if (restype.def.deftype=recorddef) then
  1980. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  1981. if (restype.def.deftype=objectdef) then
  1982. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  1983. end;
  1984. {$ifdef GDB}
  1985. function ttypesym.stabstring : pchar;
  1986. var
  1987. stabchar : string[2];
  1988. short : string;
  1989. begin
  1990. if restype.def.deftype in tagtypes then
  1991. stabchar := 'Tt'
  1992. else
  1993. stabchar := 't';
  1994. short := '"'+name+':'+stabchar+tstoreddef(restype.def).numberstring
  1995. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  1996. stabstring := strpnew(short);
  1997. end;
  1998. procedure ttypesym.concatstabto(asmlist : taasmoutput);
  1999. begin
  2000. {not stabs for forward defs }
  2001. if assigned(restype.def) then
  2002. if (restype.def.typesym = self) then
  2003. tstoreddef(restype.def).concatstabto(asmlist)
  2004. else
  2005. inherited concatstabto(asmlist);
  2006. end;
  2007. {$endif GDB}
  2008. {****************************************************************************
  2009. TSYSSYM
  2010. ****************************************************************************}
  2011. constructor tsyssym.create(const n : string;l : longint);
  2012. begin
  2013. inherited create(n);
  2014. typ:=syssym;
  2015. number:=l;
  2016. end;
  2017. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  2018. begin
  2019. inherited loadsym(ppufile);
  2020. typ:=syssym;
  2021. number:=ppufile.getlongint;
  2022. end;
  2023. destructor tsyssym.destroy;
  2024. begin
  2025. inherited destroy;
  2026. end;
  2027. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  2028. begin
  2029. inherited writesym(ppufile);
  2030. ppufile.putlongint(number);
  2031. ppufile.writeentry(ibsyssym);
  2032. end;
  2033. {$ifdef GDB}
  2034. procedure tsyssym.concatstabto(asmlist : taasmoutput);
  2035. begin
  2036. end;
  2037. {$endif GDB}
  2038. {****************************************************************************
  2039. TRTTISYM
  2040. ****************************************************************************}
  2041. constructor trttisym.create(const n:string;rt:trttitype);
  2042. const
  2043. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2044. begin
  2045. inherited create(prefix[rt]+n);
  2046. typ:=rttisym;
  2047. lab:=nil;
  2048. rttityp:=rt;
  2049. end;
  2050. constructor trttisym.ppuload(ppufile:tcompilerppufile);
  2051. begin
  2052. inherited loadsym(ppufile);
  2053. typ:=rttisym;
  2054. lab:=nil;
  2055. rttityp:=trttitype(ppufile.getbyte);
  2056. end;
  2057. procedure trttisym.ppuwrite(ppufile:tcompilerppufile);
  2058. begin
  2059. inherited writesym(ppufile);
  2060. ppufile.putbyte(byte(rttityp));
  2061. ppufile.writeentry(ibrttisym);
  2062. end;
  2063. function trttisym.mangledname : string;
  2064. const
  2065. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2066. var
  2067. s : string;
  2068. p : tsymtable;
  2069. begin
  2070. s:='';
  2071. p:=owner;
  2072. while assigned(p) and (p.symtabletype=localsymtable) do
  2073. begin
  2074. s:=s+'_'+p.defowner.name;
  2075. p:=p.defowner.owner;
  2076. end;
  2077. if not(p.symtabletype in [globalsymtable,staticsymtable]) then
  2078. internalerror(200108265);
  2079. mangledname:=prefix[rttityp]+p.name^+s+'$_'+Copy(name,5,255);
  2080. end;
  2081. function trttisym.get_label:tasmsymbol;
  2082. begin
  2083. { the label is always a global label }
  2084. if not assigned(lab) then
  2085. lab:=objectlibrary.newasmsymboltype(mangledname,AB_GLOBAL,AT_DATA);
  2086. get_label:=lab;
  2087. end;
  2088. { persistent rtti generation }
  2089. procedure generate_rtti(p:tsym);
  2090. var
  2091. rsym : trttisym;
  2092. def : tstoreddef;
  2093. begin
  2094. { rtti can only be generated for classes that are always typesyms }
  2095. if not(p.typ=typesym) then
  2096. internalerror(200108261);
  2097. def:=tstoreddef(ttypesym(p).restype.def);
  2098. { only create rtti once for each definition }
  2099. if not(df_has_rttitable in def.defoptions) then
  2100. begin
  2101. { definition should be in the same symtable as the symbol }
  2102. if p.owner<>def.owner then
  2103. internalerror(200108262);
  2104. { create rttisym }
  2105. rsym:=trttisym.create(p.name,fullrtti);
  2106. p.owner.insert(rsym);
  2107. { register rttisym in definition }
  2108. include(def.defoptions,df_has_rttitable);
  2109. def.rttitablesym:=rsym;
  2110. { write rtti data }
  2111. def.write_child_rtti_data(fullrtti);
  2112. if (cs_create_smart in aktmoduleswitches) then
  2113. rttiList.concat(Tai_cut.Create);
  2114. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2115. def.write_rtti_data(fullrtti);
  2116. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2117. end;
  2118. end;
  2119. { persistent init table generation }
  2120. procedure generate_inittable(p:tsym);
  2121. var
  2122. rsym : trttisym;
  2123. def : tstoreddef;
  2124. begin
  2125. { anonymous types are also allowed for records that can be varsym }
  2126. case p.typ of
  2127. typesym :
  2128. def:=tstoreddef(ttypesym(p).restype.def);
  2129. varsym :
  2130. def:=tstoreddef(tvarsym(p).vartype.def);
  2131. else
  2132. internalerror(200108263);
  2133. end;
  2134. { only create inittable once for each definition }
  2135. if not(df_has_inittable in def.defoptions) then
  2136. begin
  2137. { definition should be in the same symtable as the symbol }
  2138. if p.owner<>def.owner then
  2139. internalerror(200108264);
  2140. { create rttisym }
  2141. rsym:=trttisym.create(p.name,initrtti);
  2142. p.owner.insert(rsym);
  2143. { register rttisym in definition }
  2144. include(def.defoptions,df_has_inittable);
  2145. def.inittablesym:=rsym;
  2146. { write inittable data }
  2147. def.write_child_rtti_data(initrtti);
  2148. if (cs_create_smart in aktmoduleswitches) then
  2149. rttiList.concat(Tai_cut.Create);
  2150. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2151. def.write_rtti_data(initrtti);
  2152. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2153. end;
  2154. end;
  2155. end.
  2156. {
  2157. $Log$
  2158. Revision 1.59 2002-09-03 16:26:27 daniel
  2159. * Make Tprocdef.defs protected
  2160. Revision 1.58 2002/09/01 08:01:16 daniel
  2161. * Removed sets from Tcallnode.det_resulttype
  2162. + Added read/write notifications of variables. These will be usefull
  2163. for providing information for several optimizations. For example
  2164. the value of the loop variable of a for loop does matter is the
  2165. variable is read after the for loop, but if it's no longer used
  2166. or written, it doesn't matter and this can be used to optimize
  2167. the loop code generation.
  2168. Revision 1.57 2002/08/25 19:25:21 peter
  2169. * sym.insert_in_data removed
  2170. * symtable.insertvardata/insertconstdata added
  2171. * removed insert_in_data call from symtable.insert, it needs to be
  2172. called separatly. This allows to deref the address calculation
  2173. * procedures now calculate the parast addresses after the procedure
  2174. directives are parsed. This fixes the cdecl parast problem
  2175. * push_addr_param has an extra argument that specifies if cdecl is used
  2176. or not
  2177. Revision 1.56 2002/08/25 09:06:21 peter
  2178. * fixed loop in concat_procdefs
  2179. Revision 1.55 2002/08/20 16:54:40 peter
  2180. * write address of varsym always
  2181. Revision 1.54 2002/08/20 10:31:26 daniel
  2182. * Tcallnode.det_resulttype rewritten
  2183. Revision 1.53 2002/08/18 20:06:27 peter
  2184. * inlining is now also allowed in interface
  2185. * renamed write/load to ppuwrite/ppuload
  2186. * tnode storing in ppu
  2187. * nld,ncon,nbas are already updated for storing in ppu
  2188. Revision 1.52 2002/08/17 09:23:42 florian
  2189. * first part of procinfo rewrite
  2190. Revision 1.51 2002/08/16 14:24:59 carl
  2191. * issameref() to test if two references are the same (then emit no opcodes)
  2192. + ret_in_reg to replace ret_in_acc
  2193. (fix some register allocation bugs at the same time)
  2194. + save_std_register now has an extra parameter which is the
  2195. usedinproc registers
  2196. Revision 1.50 2002/08/13 21:40:57 florian
  2197. * more fixes for ppc calling conventions
  2198. Revision 1.49 2002/08/12 15:08:40 carl
  2199. + stab register indexes for powerpc (moved from gdb to cpubase)
  2200. + tprocessor enumeration moved to cpuinfo
  2201. + linker in target_info is now a class
  2202. * many many updates for m68k (will soon start to compile)
  2203. - removed some ifdef or correct them for correct cpu
  2204. Revision 1.48 2002/08/11 14:32:28 peter
  2205. * renamed current_library to objectlibrary
  2206. Revision 1.47 2002/08/11 13:24:14 peter
  2207. * saving of asmsymbols in ppu supported
  2208. * asmsymbollist global is removed and moved into a new class
  2209. tasmlibrarydata that will hold the info of a .a file which
  2210. corresponds with a single module. Added librarydata to tmodule
  2211. to keep the library info stored for the module. In the future the
  2212. objectfiles will also be stored to the tasmlibrarydata class
  2213. * all getlabel/newasmsymbol and friends are moved to the new class
  2214. Revision 1.46 2002/07/23 10:13:23 daniel
  2215. * Added important comment
  2216. Revision 1.45 2002/07/23 09:51:26 daniel
  2217. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2218. are worth comitting.
  2219. Revision 1.44 2002/07/20 17:45:29 daniel
  2220. * Register variables are now possible for global variables too. This is
  2221. important for small programs without procedures.
  2222. Revision 1.43 2002/07/20 11:57:58 florian
  2223. * types.pas renamed to defbase.pas because D6 contains a types
  2224. unit so this would conflicts if D6 programms are compiled
  2225. + Willamette/SSE2 instructions to assembler added
  2226. Revision 1.42 2002/07/11 14:41:31 florian
  2227. * start of the new generic parameter handling
  2228. Revision 1.41 2002/07/10 07:24:40 jonas
  2229. * memory leak fixes from Sergey Korshunoff
  2230. Revision 1.40 2002/07/01 18:46:27 peter
  2231. * internal linker
  2232. * reorganized aasm layer
  2233. Revision 1.39 2002/05/18 13:34:18 peter
  2234. * readded missing revisions
  2235. Revision 1.38 2002/05/16 19:46:45 carl
  2236. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2237. + try to fix temp allocation (still in ifdef)
  2238. + generic constructor calls
  2239. + start of tassembler / tmodulebase class cleanup
  2240. Revision 1.36 2002/05/12 16:53:15 peter
  2241. * moved entry and exitcode to ncgutil and cgobj
  2242. * foreach gets extra argument for passing local data to the
  2243. iterator function
  2244. * -CR checks also class typecasts at runtime by changing them
  2245. into as
  2246. * fixed compiler to cycle with the -CR option
  2247. * fixed stabs with elf writer, finally the global variables can
  2248. be watched
  2249. * removed a lot of routines from cga unit and replaced them by
  2250. calls to cgobj
  2251. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2252. u32bit then the other is typecasted also to u32bit without giving
  2253. a rangecheck warning/error.
  2254. * fixed pascal calling method with reversing also the high tree in
  2255. the parast, detected by tcalcst3 test
  2256. Revision 1.35 2002/04/19 15:46:03 peter
  2257. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  2258. in most cases and not written to the ppu
  2259. * add mangeledname_prefix() routine to generate the prefix of
  2260. manglednames depending on the current procedure, object and module
  2261. * removed static procprefix since the mangledname is now build only
  2262. on demand from tprocdef.mangledname
  2263. Revision 1.34 2002/04/16 16:12:47 peter
  2264. * give error when using enums with jumps as array index
  2265. * allow char as enum value
  2266. Revision 1.33 2002/04/15 19:08:22 carl
  2267. + target_info.size_of_pointer -> pointer_size
  2268. + some cleanup of unused types/variables
  2269. Revision 1.32 2002/04/07 13:37:29 carl
  2270. + change unit use
  2271. Revision 1.31 2002/02/03 09:30:04 peter
  2272. * more fixes for protected handling
  2273. }