symsym.pas 79 KB

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