symsym.inc 64 KB

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