symsym.pas 73 KB

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