symsym.pas 80 KB

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