symsym.pas 76 KB

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