symsym.pas 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635
  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:=target_info.size_of_pointer;
  1244. vs_value,
  1245. vs_const :
  1246. begin
  1247. if push_addr_param(vartype.def) then
  1248. getpushsize:=target_info.size_of_pointer
  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:=target_info.size_of_pointer
  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. if def.min>v then
  1929. def.setmin(v);
  1930. if def.max<v then
  1931. def.setmax(v);
  1932. order;
  1933. end;
  1934. constructor tenumsym.load(ppufile:tcompilerppufile);
  1935. begin
  1936. inherited loadsym(ppufile);
  1937. typ:=enumsym;
  1938. definition:=tenumdef(ppufile.getderef);
  1939. value:=ppufile.getlongint;
  1940. nextenum := Nil;
  1941. end;
  1942. procedure tenumsym.deref;
  1943. begin
  1944. resolvedef(tdef(definition));
  1945. order;
  1946. end;
  1947. procedure tenumsym.order;
  1948. var
  1949. sym : tenumsym;
  1950. begin
  1951. sym := tenumsym(definition.firstenum);
  1952. if sym = nil then
  1953. begin
  1954. definition.firstenum := self;
  1955. nextenum := nil;
  1956. exit;
  1957. end;
  1958. { reorder the symbols in increasing value }
  1959. if value < sym.value then
  1960. begin
  1961. nextenum := sym;
  1962. definition.firstenum := self;
  1963. end
  1964. else
  1965. begin
  1966. while (sym.value <= value) and assigned(sym.nextenum) do
  1967. sym := sym.nextenum;
  1968. nextenum := sym.nextenum;
  1969. sym.nextenum := self;
  1970. end;
  1971. end;
  1972. procedure tenumsym.write(ppufile:tcompilerppufile);
  1973. begin
  1974. inherited writesym(ppufile);
  1975. ppufile.putderef(definition);
  1976. ppufile.putlongint(value);
  1977. ppufile.writeentry(ibenumsym);
  1978. end;
  1979. {$ifdef GDB}
  1980. procedure tenumsym.concatstabto(asmlist : taasmoutput);
  1981. begin
  1982. {enum elements have no stab !}
  1983. end;
  1984. {$EndIf GDB}
  1985. {****************************************************************************
  1986. TTYPESYM
  1987. ****************************************************************************}
  1988. constructor ttypesym.create(const n : string;const tt : ttype);
  1989. begin
  1990. inherited create(n);
  1991. typ:=typesym;
  1992. restype:=tt;
  1993. {$ifdef GDB}
  1994. isusedinstab := false;
  1995. {$endif GDB}
  1996. { register the typesym for the definition }
  1997. if assigned(restype.def) and
  1998. (restype.def.deftype<>errordef) and
  1999. not(assigned(restype.def.typesym)) then
  2000. restype.def.typesym:=self;
  2001. end;
  2002. constructor ttypesym.load(ppufile:tcompilerppufile);
  2003. begin
  2004. inherited loadsym(ppufile);
  2005. typ:=typesym;
  2006. {$ifdef GDB}
  2007. isusedinstab := false;
  2008. {$endif GDB}
  2009. ppufile.gettype(restype);
  2010. end;
  2011. function ttypesym.gettypedef:tdef;
  2012. begin
  2013. gettypedef:=restype.def;
  2014. end;
  2015. procedure ttypesym.deref;
  2016. begin
  2017. restype.resolve;
  2018. end;
  2019. procedure ttypesym.write(ppufile:tcompilerppufile);
  2020. begin
  2021. inherited writesym(ppufile);
  2022. ppufile.puttype(restype);
  2023. ppufile.writeentry(ibtypesym);
  2024. end;
  2025. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  2026. begin
  2027. inherited load_references(ppufile,locals);
  2028. if (restype.def.deftype=recorddef) then
  2029. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  2030. if (restype.def.deftype=objectdef) then
  2031. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  2032. end;
  2033. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  2034. begin
  2035. if not inherited write_references(ppufile,locals) then
  2036. begin
  2037. { write address of this symbol if record or object
  2038. even if no real refs are there
  2039. because we need it for the symtable }
  2040. if (restype.def.deftype in [recorddef,objectdef]) then
  2041. begin
  2042. ppufile.putderef(self);
  2043. ppufile.writeentry(ibsymref);
  2044. end;
  2045. end;
  2046. write_references:=true;
  2047. if (restype.def.deftype=recorddef) then
  2048. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  2049. if (restype.def.deftype=objectdef) then
  2050. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  2051. end;
  2052. {$ifdef GDB}
  2053. function ttypesym.stabstring : pchar;
  2054. var
  2055. stabchar : string[2];
  2056. short : string;
  2057. begin
  2058. if restype.def.deftype in tagtypes then
  2059. stabchar := 'Tt'
  2060. else
  2061. stabchar := 't';
  2062. short := '"'+name+':'+stabchar+tstoreddef(restype.def).numberstring
  2063. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  2064. stabstring := strpnew(short);
  2065. end;
  2066. procedure ttypesym.concatstabto(asmlist : taasmoutput);
  2067. begin
  2068. {not stabs for forward defs }
  2069. if assigned(restype.def) then
  2070. if (restype.def.typesym = self) then
  2071. tstoreddef(restype.def).concatstabto(asmlist)
  2072. else
  2073. inherited concatstabto(asmlist);
  2074. end;
  2075. {$endif GDB}
  2076. {****************************************************************************
  2077. TSYSSYM
  2078. ****************************************************************************}
  2079. constructor tsyssym.create(const n : string;l : longint);
  2080. begin
  2081. inherited create(n);
  2082. typ:=syssym;
  2083. number:=l;
  2084. end;
  2085. constructor tsyssym.load(ppufile:tcompilerppufile);
  2086. begin
  2087. inherited loadsym(ppufile);
  2088. typ:=syssym;
  2089. number:=ppufile.getlongint;
  2090. end;
  2091. destructor tsyssym.destroy;
  2092. begin
  2093. inherited destroy;
  2094. end;
  2095. procedure tsyssym.write(ppufile:tcompilerppufile);
  2096. begin
  2097. inherited writesym(ppufile);
  2098. ppufile.putlongint(number);
  2099. ppufile.writeentry(ibsyssym);
  2100. end;
  2101. {$ifdef GDB}
  2102. procedure tsyssym.concatstabto(asmlist : taasmoutput);
  2103. begin
  2104. end;
  2105. {$endif GDB}
  2106. {****************************************************************************
  2107. TRTTISYM
  2108. ****************************************************************************}
  2109. constructor trttisym.create(const n:string;rt:trttitype);
  2110. const
  2111. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2112. begin
  2113. inherited create(prefix[rt]+n);
  2114. typ:=rttisym;
  2115. lab:=nil;
  2116. rttityp:=rt;
  2117. end;
  2118. constructor trttisym.load(ppufile:tcompilerppufile);
  2119. begin
  2120. inherited loadsym(ppufile);
  2121. typ:=rttisym;
  2122. lab:=nil;
  2123. rttityp:=trttitype(ppufile.getbyte);
  2124. end;
  2125. procedure trttisym.write(ppufile:tcompilerppufile);
  2126. begin
  2127. inherited writesym(ppufile);
  2128. ppufile.putbyte(byte(rttityp));
  2129. ppufile.writeentry(ibrttisym);
  2130. end;
  2131. function trttisym.mangledname : string;
  2132. const
  2133. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2134. var
  2135. s : string;
  2136. p : tsymtable;
  2137. begin
  2138. s:='';
  2139. p:=owner;
  2140. while assigned(p) and (p.symtabletype=localsymtable) do
  2141. begin
  2142. s:=s+'_'+p.defowner.name;
  2143. p:=p.defowner.owner;
  2144. end;
  2145. if not(p.symtabletype in [globalsymtable,staticsymtable]) then
  2146. internalerror(200108265);
  2147. mangledname:=prefix[rttityp]+p.name^+s+'$_'+Copy(name,5,255);
  2148. end;
  2149. function trttisym.get_label:tasmsymbol;
  2150. begin
  2151. { the label is always a global label }
  2152. if not assigned(lab) then
  2153. lab:=newasmsymboltype(mangledname,AB_GLOBAL,AT_DATA);
  2154. get_label:=lab;
  2155. end;
  2156. { persistent rtti generation }
  2157. procedure generate_rtti(p:tsym);
  2158. var
  2159. rsym : trttisym;
  2160. def : tstoreddef;
  2161. begin
  2162. { rtti can only be generated for classes that are always typesyms }
  2163. if not(p.typ=typesym) then
  2164. internalerror(200108261);
  2165. def:=tstoreddef(ttypesym(p).restype.def);
  2166. { only create rtti once for each definition }
  2167. if not(df_has_rttitable in def.defoptions) then
  2168. begin
  2169. { definition should be in the same symtable as the symbol }
  2170. if p.owner<>def.owner then
  2171. internalerror(200108262);
  2172. { create rttisym }
  2173. rsym:=trttisym.create(p.name,fullrtti);
  2174. p.owner.insert(rsym);
  2175. { register rttisym in definition }
  2176. include(def.defoptions,df_has_rttitable);
  2177. def.rttitablesym:=rsym;
  2178. { write rtti data }
  2179. def.write_child_rtti_data(fullrtti);
  2180. if (cs_create_smart in aktmoduleswitches) then
  2181. rttiList.concat(Tai_cut.Create);
  2182. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2183. def.write_rtti_data(fullrtti);
  2184. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2185. end;
  2186. end;
  2187. { persistent init table generation }
  2188. procedure generate_inittable(p:tsym);
  2189. var
  2190. rsym : trttisym;
  2191. def : tstoreddef;
  2192. begin
  2193. { anonymous types are also allowed for records that can be varsym }
  2194. case p.typ of
  2195. typesym :
  2196. def:=tstoreddef(ttypesym(p).restype.def);
  2197. varsym :
  2198. def:=tstoreddef(tvarsym(p).vartype.def);
  2199. else
  2200. internalerror(200108263);
  2201. end;
  2202. { only create inittable once for each definition }
  2203. if not(df_has_inittable in def.defoptions) then
  2204. begin
  2205. { definition should be in the same symtable as the symbol }
  2206. if p.owner<>def.owner then
  2207. internalerror(200108264);
  2208. { create rttisym }
  2209. rsym:=trttisym.create(p.name,initrtti);
  2210. p.owner.insert(rsym);
  2211. { register rttisym in definition }
  2212. include(def.defoptions,df_has_inittable);
  2213. def.inittablesym:=rsym;
  2214. { write inittable data }
  2215. def.write_child_rtti_data(initrtti);
  2216. if (cs_create_smart in aktmoduleswitches) then
  2217. rttiList.concat(Tai_cut.Create);
  2218. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2219. def.write_rtti_data(initrtti);
  2220. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2221. end;
  2222. end;
  2223. end.
  2224. {
  2225. $Log$
  2226. Revision 1.32 2002-04-07 13:37:29 carl
  2227. + change unit use
  2228. Revision 1.31 2002/02/03 09:30:04 peter
  2229. * more fixes for protected handling
  2230. Revision 1.30 2001/12/31 16:59:43 peter
  2231. * protected/private symbols parsing fixed
  2232. Revision 1.29 2001/12/03 21:48:42 peter
  2233. * freemem change to value parameter
  2234. * torddef low/high range changed to int64
  2235. Revision 1.28 2001/11/30 16:25:35 jonas
  2236. * fixed web bug 1707:
  2237. * tvarsym.getvaluesize doesn't return 0 anymore for dynarrays (found
  2238. by Florian)
  2239. * in genrtti, some more ppointer(data)^ tricks were necessary
  2240. Revision 1.27 2001/11/18 18:43:16 peter
  2241. * overloading supported in child classes
  2242. * fixed parsing of classes with private and virtual and overloaded
  2243. so it is compatible with delphi
  2244. Revision 1.26 2001/11/02 22:58:08 peter
  2245. * procsym definition rewrite
  2246. Revision 1.25 2001/10/25 21:22:40 peter
  2247. * calling convention rewrite
  2248. Revision 1.24 2001/10/23 21:49:43 peter
  2249. * $calling directive and -Cc commandline patch added
  2250. from Pavel Ozerski
  2251. Revision 1.23 2001/10/20 20:30:21 peter
  2252. * read only typed const support, switch $J-
  2253. Revision 1.22 2001/09/19 11:04:42 michael
  2254. * Smartlinking with interfaces fixed
  2255. * Better smartlinking for rtti and init tables
  2256. Revision 1.21 2001/09/02 21:18:29 peter
  2257. * split constsym.value in valueord,valueordptr,valueptr. The valueordptr
  2258. is used for holding target platform pointer values. As those can be
  2259. bigger than the source platform.
  2260. Revision 1.20 2001/08/30 20:13:54 peter
  2261. * rtti/init table updates
  2262. * rttisym for reusable global rtti/init info
  2263. * support published for interfaces
  2264. Revision 1.19 2001/08/26 13:36:50 florian
  2265. * some cg reorganisation
  2266. * some PPC updates
  2267. Revision 1.18 2001/08/19 09:39:28 peter
  2268. * local browser support fixed
  2269. Revision 1.16 2001/08/12 20:00:26 peter
  2270. * don't write fpuregable for varoptions
  2271. Revision 1.15 2001/08/06 21:40:48 peter
  2272. * funcret moved from tprocinfo to tprocdef
  2273. Revision 1.14 2001/07/01 20:16:17 peter
  2274. * alignmentinfo record added
  2275. * -Oa argument supports more alignment settings that can be specified
  2276. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  2277. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  2278. required alignment and the maximum usefull alignment. The final
  2279. alignment will be choosen per variable size dependent on these
  2280. settings
  2281. Revision 1.13 2001/05/08 21:06:32 florian
  2282. * some more support for widechars commited especially
  2283. regarding type casting and constants
  2284. Revision 1.12 2001/05/06 14:49:17 peter
  2285. * ppu object to class rewrite
  2286. * move ppu read and write stuff to fppu
  2287. Revision 1.11 2001/04/18 22:01:59 peter
  2288. * registration of targets and assemblers
  2289. Revision 1.10 2001/04/13 01:22:16 peter
  2290. * symtable change to classes
  2291. * range check generation and errors fixed, make cycle DEBUG=1 works
  2292. * memory leaks fixed
  2293. Revision 1.9 2001/04/02 21:20:35 peter
  2294. * resulttype rewrite
  2295. Revision 1.8 2001/03/11 22:58:51 peter
  2296. * getsym redesign, removed the globals srsym,srsymtable
  2297. Revision 1.7 2000/12/25 00:07:30 peter
  2298. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  2299. tlinkedlist objects)
  2300. Revision 1.6 2000/11/28 00:25:17 pierre
  2301. + use int64tostr function for integer consts
  2302. Revision 1.5 2000/11/13 14:44:35 jonas
  2303. * fixes so no more range errors with improved range checking code
  2304. Revision 1.4 2000/11/08 23:15:17 florian
  2305. * tprocdef.procsym must be set also when a tprocdef is loaded from a PPU
  2306. Revision 1.3 2000/11/06 23:13:53 peter
  2307. * uppercase manglednames
  2308. Revision 1.2 2000/11/01 23:04:38 peter
  2309. * tprocdef.fullprocname added for better casesensitve writing of
  2310. procedures
  2311. Revision 1.1 2000/10/31 22:02:52 peter
  2312. * symtable splitted, no real code changes
  2313. }