symsym.inc 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191
  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. left:=nil;
  24. right:=nil;
  25. {$ifdef nextfield}
  26. nextsym:=nil;
  27. {$endif nextfield}
  28. setname(n);
  29. typ:=abstractsym;
  30. properties:=current_object_option;
  31. {$ifdef GDB}
  32. isstabwritten := false;
  33. {$endif GDB}
  34. fileinfo:=tokenpos;
  35. defref:=nil;
  36. lastwritten:=nil;
  37. refcount:=0;
  38. if (cs_browser in aktmoduleswitches) and make_ref then
  39. begin
  40. defref:=new(pref,init(defref,@tokenpos));
  41. inc(refcount);
  42. end;
  43. lastref:=defref;
  44. end;
  45. constructor tsym.load;
  46. begin
  47. left:=nil;
  48. right:=nil;
  49. setname(readstring);
  50. typ:=abstractsym;
  51. fillchar(fileinfo,sizeof(fileinfo),0);
  52. if object_options then
  53. properties:=symprop(readbyte)
  54. else
  55. properties:=sp_public;
  56. lastref:=nil;
  57. defref:=nil;
  58. lastwritten:=nil;
  59. refcount:=0;
  60. {$ifdef GDB}
  61. isstabwritten := false;
  62. {$endif GDB}
  63. end;
  64. procedure tsym.load_references;
  65. var
  66. pos : tfileposinfo;
  67. move_last : boolean;
  68. begin
  69. move_last:=lastwritten=lastref;
  70. while (not current_ppu^.endofentry) do
  71. begin
  72. readposinfo(pos);
  73. inc(refcount);
  74. lastref:=new(pref,init(lastref,@pos));
  75. lastref^.is_written:=true;
  76. if refcount=1 then
  77. defref:=lastref;
  78. end;
  79. if move_last then
  80. lastwritten:=lastref;
  81. end;
  82. { big problem here :
  83. wrong refs were written because of
  84. interface parsing of other units PM
  85. moduleindex must be checked !! }
  86. function tsym.write_references : boolean;
  87. var
  88. ref : pref;
  89. symref_written,move_last : boolean;
  90. begin
  91. write_references:=false;
  92. if lastwritten=lastref then
  93. exit;
  94. { should we update lastref }
  95. move_last:=true;
  96. symref_written:=false;
  97. { write symbol refs }
  98. if assigned(lastwritten) then
  99. ref:=lastwritten
  100. else
  101. ref:=defref;
  102. while assigned(ref) do
  103. begin
  104. if ref^.moduleindex=current_module^.unit_index then
  105. begin
  106. { write address to this symbol }
  107. if not symref_written then
  108. begin
  109. writesymref(@self);
  110. symref_written:=true;
  111. end;
  112. writeposinfo(ref^.posinfo);
  113. ref^.is_written:=true;
  114. if move_last then
  115. lastwritten:=ref;
  116. end
  117. else if not ref^.is_written then
  118. move_last:=false
  119. else if move_last then
  120. lastwritten:=ref;
  121. ref:=ref^.nextref;
  122. end;
  123. if symref_written then
  124. current_ppu^.writeentry(ibsymref);
  125. write_references:=symref_written;
  126. end;
  127. {$ifdef BrowserLog}
  128. procedure tsym.add_to_browserlog;
  129. begin
  130. if assigned(defref) then
  131. begin
  132. browserlog.AddLog('***'+name+'***');
  133. browserlog.AddLogRefs(defref);
  134. end;
  135. end;
  136. {$endif BrowserLog}
  137. destructor tsym.done;
  138. begin
  139. {$ifdef tp}
  140. if not(use_big) then
  141. {$endif tp}
  142. strdispose(_name);
  143. if assigned(defref) then
  144. dispose(defref,done);
  145. if assigned(left) then
  146. dispose(left,done);
  147. if assigned(right) then
  148. dispose(right,done);
  149. end;
  150. procedure tsym.write;
  151. begin
  152. writestring(name);
  153. if object_options then
  154. writebyte(byte(properties));
  155. end;
  156. procedure tsym.deref;
  157. begin
  158. end;
  159. function tsym.name : string;
  160. {$ifdef tp}
  161. var
  162. s : string;
  163. b : byte;
  164. {$endif}
  165. begin
  166. {$ifdef tp}
  167. if use_big then
  168. begin
  169. symbolstream.seek(longint(_name));
  170. symbolstream.read(b,1);
  171. symbolstream.read(s[1],b);
  172. s[0]:=chr(b);
  173. name:=s;
  174. end
  175. else
  176. {$endif}
  177. if assigned(_name) then
  178. name:=strpas(_name)
  179. else
  180. name:='';
  181. end;
  182. function tsym.mangledname : string;
  183. begin
  184. mangledname:=name;
  185. end;
  186. procedure tsym.setname(const s : string);
  187. begin
  188. setstring(_name,s);
  189. end;
  190. { for most symbol types there is nothing to do at all }
  191. procedure tsym.insert_in_data;
  192. begin
  193. end;
  194. {$ifdef GDB}
  195. function tsym.stabstring : pchar;
  196. begin
  197. stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+
  198. tostr(fileinfo.line)+',0');
  199. end;
  200. procedure tsym.concatstabto(asmlist : paasmoutput);
  201. var stab_str : pchar;
  202. begin
  203. if not isstabwritten then
  204. begin
  205. stab_str := stabstring;
  206. if asmlist = debuglist then do_count_dbx := true;
  207. { count_dbx(stab_str); moved to GDB.PAS }
  208. asmlist^.concat(new(pai_stabs,init(stab_str)));
  209. isstabwritten:=true;
  210. end;
  211. end;
  212. {$endif GDB}
  213. {****************************************************************************
  214. TLABELSYM
  215. ****************************************************************************}
  216. constructor tlabelsym.init(const n : string; l : plabel);
  217. begin
  218. inherited init(n);
  219. typ:=labelsym;
  220. number:=l;
  221. number^.is_used:=false;
  222. number^.is_set:=true;
  223. number^.refcount:=0;
  224. defined:=false;
  225. end;
  226. constructor tlabelsym.load;
  227. begin
  228. tsym.load;
  229. typ:=labelsym;
  230. { this is all dummy
  231. it is only used for local browsing }
  232. number:=nil;
  233. defined:=true;
  234. end;
  235. destructor tlabelsym.done;
  236. begin
  237. inherited done;
  238. end;
  239. function tlabelsym.mangledname : string;
  240. begin
  241. { this also sets the is_used field }
  242. mangledname:=lab2str(number);
  243. end;
  244. procedure tlabelsym.write;
  245. begin
  246. if owner^.symtabletype in [unitsymtable,globalsymtable] then
  247. Message(sym_e_ill_label_decl)
  248. else
  249. begin
  250. tsym.write;
  251. current_ppu^.writeentry(iblabelsym);
  252. end;
  253. end;
  254. {****************************************************************************
  255. TUNITSYM
  256. ****************************************************************************}
  257. constructor tunitsym.init(const n : string;ref : punitsymtable);
  258. var
  259. old_make_ref : boolean;
  260. begin
  261. old_make_ref:=make_ref;
  262. make_ref:=false;
  263. inherited init(n);
  264. make_ref:=old_make_ref;
  265. typ:=unitsym;
  266. unitsymtable:=ref;
  267. prevsym:=ref^.unitsym;
  268. ref^.unitsym:=@self;
  269. refs:=0;
  270. end;
  271. constructor tunitsym.load;
  272. begin
  273. tsym.load;
  274. typ:=unitsym;
  275. unitsymtable:=punitsymtable(current_module^.globalsymtable);
  276. prevsym:=nil;
  277. end;
  278. destructor tunitsym.done;
  279. begin
  280. if assigned(unitsymtable) and (unitsymtable^.unitsym=@self) then
  281. unitsymtable^.unitsym:=prevsym;
  282. inherited done;
  283. end;
  284. procedure tunitsym.write;
  285. begin
  286. tsym.write;
  287. current_ppu^.writeentry(ibunitsym);
  288. end;
  289. {$ifdef GDB}
  290. procedure tunitsym.concatstabto(asmlist : paasmoutput);
  291. begin
  292. {Nothing to write to stabs !}
  293. end;
  294. {$endif GDB}
  295. {****************************************************************************
  296. TPROCSYM
  297. ****************************************************************************}
  298. constructor tprocsym.init(const n : string);
  299. begin
  300. tsym.init(n);
  301. typ:=procsym;
  302. definition:=nil;
  303. owner:=nil;
  304. {$ifdef GDB}
  305. is_global := false;
  306. {$endif GDB}
  307. end;
  308. constructor tprocsym.load;
  309. begin
  310. tsym.load;
  311. typ:=procsym;
  312. definition:=pprocdef(readdefref);
  313. {$ifdef GDB}
  314. is_global := false;
  315. {$endif GDB}
  316. end;
  317. destructor tprocsym.done;
  318. begin
  319. check_forward;
  320. tsym.done;
  321. end;
  322. function tprocsym.mangledname : string;
  323. begin
  324. mangledname:=definition^.mangledname;
  325. end;
  326. function tprocsym.demangledname:string;
  327. begin
  328. demangledname:=name+definition^.demangled_paras;
  329. end;
  330. procedure tprocsym.write_parameter_lists;
  331. var
  332. p : pprocdef;
  333. begin
  334. p:=definition;
  335. while assigned(p) do
  336. begin
  337. { force the error to be printed }
  338. Verbose.Message1(sym_b_param_list,name+p^.demangled_paras);
  339. p:=p^.nextoverloaded;
  340. end;
  341. end;
  342. procedure tprocsym.check_forward;
  343. var
  344. pd : pprocdef;
  345. oldaktfilepos : tfileposinfo;
  346. begin
  347. { don't check if errors !! }
  348. if Errorcount>0 then
  349. exit;
  350. pd:=definition;
  351. while assigned(pd) do
  352. begin
  353. if pd^.forwarddef then
  354. begin
  355. oldaktfilepos:=aktfilepos;
  356. aktfilepos:=fileinfo;
  357. if assigned(pd^._class) then
  358. Message1(sym_e_forward_not_resolved,pd^._class^.name^+'.'+name+demangledparas(pd^.demangled_paras))
  359. else
  360. Message1(sym_e_forward_not_resolved,name+pd^.demangled_paras);
  361. aktfilepos:=oldaktfilepos;
  362. end;
  363. pd:=pd^.nextoverloaded;
  364. end;
  365. end;
  366. procedure tprocsym.deref;
  367. var
  368. t : ttoken;
  369. last : pprocdef;
  370. begin
  371. resolvedef(pdef(definition));
  372. if (definition^.options and pooperator) <> 0 then
  373. begin
  374. last:=definition;
  375. while assigned(last^.nextoverloaded) do
  376. last:=last^.nextoverloaded;
  377. for t:=first_overloaded to last_overloaded do
  378. if (name=overloaded_names[t]) then
  379. begin
  380. if assigned(overloaded_operators[t]) then
  381. last^.nextoverloaded:=overloaded_operators[t]^.definition;
  382. overloaded_operators[t]:=@self;
  383. end;
  384. end;
  385. end;
  386. procedure tprocsym.write;
  387. begin
  388. tsym.write;
  389. writedefref(pdef(definition));
  390. current_ppu^.writeentry(ibprocsym);
  391. end;
  392. procedure tprocsym.load_references;
  393. (* var
  394. prdef,prdef2 : pprocdef;
  395. b : byte; *)
  396. begin
  397. inherited load_references;
  398. (* prdef:=definition;
  399. { take care about operators !! }
  400. if (current_module^.flags and uf_has_browser) <>0 then
  401. while assigned(prdef) and (prdef^.owner=definition^.owner) do
  402. begin
  403. b:=current_ppu^.readentry;
  404. if b<>ibdefref then
  405. Message(unit_f_ppu_read_error);
  406. prdef2:=pprocdef(readdefref);
  407. resolvedef(prdef2);
  408. if prdef<>prdef2 then
  409. Message(unit_f_ppu_read_error);
  410. prdef^.load_references;
  411. prdef:=prdef^.nextoverloaded;
  412. end; *)
  413. end;
  414. function tprocsym.write_references : boolean;
  415. var
  416. prdef : pprocdef;
  417. begin
  418. write_references:=false;
  419. if not inherited write_references then
  420. exit;
  421. write_references:=true;
  422. prdef:=definition;
  423. while assigned(prdef) and (prdef^.owner=definition^.owner) do
  424. begin
  425. prdef^.write_references;
  426. prdef:=prdef^.nextoverloaded;
  427. end;
  428. end;
  429. {$ifdef BrowserLog}
  430. procedure tprocsym.add_to_browserlog;
  431. var
  432. prdef : pprocdef;
  433. begin
  434. inherited add_to_browserlog;
  435. prdef:=definition;
  436. while assigned(prdef) do
  437. begin
  438. pprocdef(prdef)^.add_to_browserlog;
  439. prdef:=pprocdef(prdef)^.nextoverloaded;
  440. end;
  441. end;
  442. {$endif BrowserLog}
  443. {$ifdef GDB}
  444. function tprocsym.stabstring : pchar;
  445. Var RetType : Char;
  446. Obj,Info : String;
  447. stabsstr : string;
  448. p : pchar;
  449. begin
  450. obj := name;
  451. info := '';
  452. if is_global then
  453. RetType := 'F'
  454. else
  455. RetType := 'f';
  456. if assigned(owner) then
  457. begin
  458. if (owner^.symtabletype = objectsymtable) then
  459. obj := owner^.name^+'__'+name;
  460. { this code was correct only as long as the local symboltable
  461. of the parent had the same name as the function
  462. but this is no true anymore !! PM
  463. if (owner^.symtabletype=localsymtable) and assigned(owner^.name) then
  464. info := ','+name+','+owner^.name^; }
  465. if (owner^.symtabletype=localsymtable) and assigned(owner^.defowner) and
  466. assigned(owner^.defowner^.sym) then
  467. info := ','+name+','+owner^.defowner^.sym^.name;
  468. end;
  469. stabsstr:=definition^.mangledname;
  470. getmem(p,length(stabsstr)+255);
  471. strpcopy(p,'"'+obj+':'+RetType
  472. +definition^.retdef^.numberstring+info+'",'+tostr(n_function)
  473. +',0,'+
  474. tostr(aktfilepos.line)
  475. +',');
  476. strpcopy(strend(p),stabsstr);
  477. stabstring:=strnew(p);
  478. freemem(p,length(stabsstr)+255);
  479. end;
  480. procedure tprocsym.concatstabto(asmlist : paasmoutput);
  481. begin
  482. if (definition^.options and pointernproc) <> 0 then exit;
  483. if not isstabwritten then
  484. asmlist^.concat(new(pai_stabs,init(stabstring)));
  485. isstabwritten := true;
  486. if assigned(definition^.parast) then
  487. definition^.parast^.concatstabto(asmlist);
  488. if assigned(definition^.localst) then
  489. definition^.localst^.concatstabto(asmlist);
  490. definition^.is_def_stab_written := true;
  491. end;
  492. {$endif GDB}
  493. {****************************************************************************
  494. TPROGRAMSYM
  495. ****************************************************************************}
  496. constructor tprogramsym.init(const n : string);
  497. begin
  498. inherited init(n);
  499. typ:=programsym;
  500. end;
  501. {****************************************************************************
  502. TERRORSYM
  503. ****************************************************************************}
  504. constructor terrorsym.init;
  505. begin
  506. inherited init('');
  507. typ:=errorsym;
  508. end;
  509. {****************************************************************************
  510. TPROPERTYSYM
  511. ****************************************************************************}
  512. constructor tpropertysym.init(const n : string);
  513. begin
  514. inherited init(n);
  515. typ:=propertysym;
  516. options:=0;
  517. proptype:=nil;
  518. readaccessdef:=nil;
  519. writeaccessdef:=nil;
  520. readaccesssym:=nil;
  521. writeaccesssym:=nil;
  522. storedsym:=nil;
  523. storeddef:=nil;
  524. index:=0;
  525. default:=0;
  526. end;
  527. destructor tpropertysym.done;
  528. begin
  529. inherited done;
  530. end;
  531. constructor tpropertysym.load;
  532. begin
  533. inherited load;
  534. typ:=propertysym;
  535. proptype:=readdefref;
  536. options:=readlong;
  537. index:=readlong;
  538. default:=readlong;
  539. { it's hack ... }
  540. readaccesssym:=psym(stringdup(readstring));
  541. writeaccesssym:=psym(stringdup(readstring));
  542. storedsym:=psym(stringdup(readstring));
  543. { now the defs: }
  544. readaccessdef:=readdefref;
  545. writeaccessdef:=readdefref;
  546. storeddef:=readdefref;
  547. end;
  548. procedure tpropertysym.deref;
  549. begin
  550. resolvedef(proptype);
  551. resolvedef(readaccessdef);
  552. resolvedef(writeaccessdef);
  553. resolvedef(storeddef);
  554. { solve the hack we did in load: }
  555. if pstring(readaccesssym)^<>'' then
  556. begin
  557. srsym:=search_class_member(pobjectdef(owner^.defowner),pstring(readaccesssym)^);
  558. if not(assigned(srsym)) then
  559. srsym:=generrorsym;
  560. end
  561. else
  562. srsym:=nil;
  563. stringdispose(pstring(readaccesssym));
  564. readaccesssym:=srsym;
  565. if pstring(writeaccesssym)^<>'' then
  566. begin
  567. srsym:=search_class_member(pobjectdef(owner^.defowner),pstring(writeaccesssym)^);
  568. if not(assigned(srsym)) then
  569. srsym:=generrorsym;
  570. end
  571. else
  572. srsym:=nil;
  573. stringdispose(pstring(writeaccesssym));
  574. writeaccesssym:=srsym;
  575. if pstring(storedsym)^<>'' then
  576. begin
  577. srsym:=search_class_member(pobjectdef(owner^.defowner),pstring(storedsym)^);
  578. if not(assigned(srsym)) then
  579. srsym:=generrorsym;
  580. end
  581. else
  582. srsym:=nil;
  583. stringdispose(pstring(storedsym));
  584. storedsym:=srsym;
  585. end;
  586. function tpropertysym.getsize : longint;
  587. begin
  588. getsize:=0;
  589. end;
  590. procedure tpropertysym.write;
  591. begin
  592. tsym.write;
  593. writedefref(proptype);
  594. writelong(options);
  595. writelong(index);
  596. writelong(default);
  597. if assigned(readaccesssym) then
  598. writestring(readaccesssym^.name)
  599. else
  600. writestring('');
  601. if assigned(writeaccesssym) then
  602. writestring(writeaccesssym^.name)
  603. else
  604. writestring('');
  605. if assigned(storedsym) then
  606. writestring(storedsym^.name)
  607. else
  608. writestring('');
  609. writedefref(readaccessdef);
  610. writedefref(writeaccessdef);
  611. writedefref(storeddef);
  612. current_ppu^.writeentry(ibpropertysym);
  613. end;
  614. {$ifdef GDB}
  615. function tpropertysym.stabstring : pchar;
  616. begin
  617. { !!!! don't know how to handle }
  618. stabstring:=strpnew('');
  619. end;
  620. procedure tpropertysym.concatstabto(asmlist : paasmoutput);
  621. begin
  622. { !!!! don't know how to handle }
  623. end;
  624. {$endif GDB}
  625. {****************************************************************************
  626. TFUNCRETSYM
  627. ****************************************************************************}
  628. constructor tfuncretsym.init(const n : string;approcinfo : pointer{pprocinfo});
  629. begin
  630. tsym.init(n);
  631. typ:=funcretsym;
  632. funcretprocinfo:=approcinfo;
  633. funcretdef:=pprocinfo(approcinfo)^.retdef;
  634. { address valid for ret in param only }
  635. { otherwise set by insert }
  636. address:=pprocinfo(approcinfo)^.retoffset;
  637. end;
  638. constructor tfuncretsym.load;
  639. begin
  640. tsym.load;
  641. funcretdef:=readdefref;
  642. address:=readlong;
  643. funcretprocinfo:=nil;
  644. typ:=funcretsym;
  645. end;
  646. procedure tfuncretsym.write;
  647. begin
  648. (*
  649. Normally all references are
  650. transfered to the function symbol itself !! PM *)
  651. tsym.write;
  652. writedefref(funcretdef);
  653. writelong(address);
  654. current_ppu^.writeentry(ibfuncretsym);
  655. end;
  656. procedure tfuncretsym.deref;
  657. begin
  658. resolvedef(funcretdef);
  659. end;
  660. {$ifdef GDB}
  661. procedure tfuncretsym.concatstabto(asmlist : paasmoutput);
  662. begin
  663. { Nothing to do here, it is done in genexitcode }
  664. end;
  665. {$endif GDB}
  666. procedure tfuncretsym.insert_in_data;
  667. var
  668. l : longint;
  669. begin
  670. { allocate space in local if ret in acc or in fpu }
  671. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  672. begin
  673. l:=funcretdef^.size;
  674. inc(owner^.datasize,l);
  675. {$ifdef m68k}
  676. { word alignment required for motorola }
  677. if (l=1) then
  678. inc(owner^.datasize,1)
  679. else
  680. {$endif}
  681. if (l>=4) and ((owner^.datasize and 3)<>0) then
  682. inc(owner^.datasize,4-(owner^.datasize and 3))
  683. else if (l>=2) and ((owner^.datasize and 1)<>0) then
  684. inc(owner^.datasize,2-(owner^.datasize and 1));
  685. address:=owner^.datasize;
  686. procinfo.retoffset:=-owner^.datasize;
  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. begin
  723. tsym.write;
  724. writebyte(byte(varspez));
  725. if read_member then
  726. writelong(address);
  727. writedefref(definition);
  728. writebyte(var_options and (not vo_regable));
  729. writebyte(byte(abstyp));
  730. case abstyp of
  731. tovar :
  732. writestring(ref^.name);
  733. toasm :
  734. writestring(asmname^);
  735. toaddr :
  736. begin
  737. writelong(address);
  738. writebyte(byte(absseg));
  739. end;
  740. end;
  741. current_ppu^.writeentry(ibabsolutesym);
  742. end;
  743. procedure tabsolutesym.deref;
  744. begin
  745. resolvedef(definition);
  746. if (abstyp=tovar) and (asmname<>nil) then
  747. begin
  748. { search previous loaded symtables }
  749. getsym(asmname^,false);
  750. if not(assigned(srsym)) then
  751. getsymonlyin(owner,asmname^);
  752. if not(assigned(srsym)) then
  753. srsym:=generrorsym;
  754. ref:=srsym;
  755. stringdispose(asmname);
  756. end;
  757. end;
  758. function tabsolutesym.mangledname : string;
  759. begin
  760. case abstyp of
  761. tovar :
  762. mangledname:=ref^.mangledname;
  763. toasm :
  764. mangledname:=asmname^;
  765. toaddr :
  766. mangledname:='$'+tostr(address);
  767. else
  768. internalerror(10002);
  769. end;
  770. end;
  771. procedure tabsolutesym.insert_in_data;
  772. begin
  773. end;
  774. {$ifdef GDB}
  775. procedure tabsolutesym.concatstabto(asmlist : paasmoutput);
  776. begin
  777. { I don't know how to handle this !! }
  778. end;
  779. {$endif GDB}
  780. {****************************************************************************
  781. TVARSYM
  782. ****************************************************************************}
  783. constructor tvarsym.init(const n : string;p : pdef);
  784. begin
  785. tsym.init(n);
  786. typ:=varsym;
  787. definition:=p;
  788. _mangledname:=nil;
  789. varspez:=vs_value;
  790. address:=0;
  791. islocalcopy:=false;
  792. localvarsym:=nil;
  793. refs:=0;
  794. is_valid := 1;
  795. var_options:=0;
  796. { can we load the value into a register ? }
  797. case p^.deftype of
  798. pointerdef,
  799. enumdef,
  800. procvardef :
  801. var_options:=var_options or vo_regable;
  802. orddef :
  803. case porddef(p)^.typ of
  804. bool8bit,bool16bit,bool32bit,
  805. u8bit,u16bit,u32bit,
  806. s8bit,s16bit,s32bit :
  807. var_options:=var_options or vo_regable;
  808. else
  809. var_options:=var_options and not vo_regable;
  810. end;
  811. setdef:
  812. if psetdef(p)^.settype=smallset then
  813. var_options:=var_options or vo_regable;
  814. else
  815. var_options:=var_options and not vo_regable;
  816. end;
  817. reg:=R_NO;
  818. end;
  819. constructor tvarsym.init_dll(const n : string;p : pdef);
  820. begin
  821. { The tvarsym is necessary for 0.99.5 (PFV) }
  822. tvarsym.init(n,p);
  823. var_options:=var_options or vo_is_dll_var;
  824. end;
  825. constructor tvarsym.init_C(const n,mangled : string;p : pdef);
  826. begin
  827. { The tvarsym is necessary for 0.99.5 (PFV) }
  828. tvarsym.init(n,p);
  829. var_options:=var_options or vo_is_C_var;
  830. setmangledname(mangled);
  831. end;
  832. constructor tvarsym.load;
  833. begin
  834. tsym.load;
  835. typ:=varsym;
  836. _mangledname:=nil;
  837. reg:=R_NO;
  838. refs := 0;
  839. is_valid := 1;
  840. varspez:=tvarspez(readbyte);
  841. if read_member then
  842. address:=readlong
  843. else
  844. address:=0;
  845. islocalcopy:=false;
  846. localvarsym:=nil;
  847. definition:=readdefref;
  848. var_options:=readbyte;
  849. if (var_options and vo_is_C_var)<>0 then
  850. setmangledname(readstring);
  851. end;
  852. procedure tvarsym.deref;
  853. begin
  854. resolvedef(definition);
  855. end;
  856. procedure tvarsym.write;
  857. begin
  858. tsym.write;
  859. writebyte(byte(varspez));
  860. if read_member then
  861. writelong(address);
  862. writedefref(definition);
  863. { symbols which are load are never candidates for a register,
  864. turn of the regable }
  865. writebyte(var_options and (not vo_regable));
  866. if (var_options and vo_is_C_var)<>0 then
  867. writestring(mangledname);
  868. current_ppu^.writeentry(ibvarsym);
  869. end;
  870. procedure tvarsym.setmangledname(const s : string);
  871. begin
  872. _mangledname:=strpnew(s);
  873. end;
  874. function tvarsym.mangledname : string;
  875. var
  876. prefix : string;
  877. begin
  878. if assigned(_mangledname) then
  879. begin
  880. mangledname:=strpas(_mangledname);
  881. exit;
  882. end;
  883. case owner^.symtabletype of
  884. staticsymtable :
  885. if (cs_smartlink in aktmoduleswitches) then
  886. prefix:='_'+owner^.name^+'$$$_'
  887. else
  888. prefix:='_';
  889. unitsymtable,
  890. globalsymtable :
  891. prefix:='U_'+owner^.name^+'_';
  892. else
  893. Message(sym_e_invalid_call_tvarsymmangledname);
  894. end;
  895. mangledname:=prefix+name;
  896. end;
  897. function tvarsym.getsize : longint;
  898. begin
  899. if assigned(definition) and (varspez=vs_value) then
  900. getsize:=definition^.size
  901. else
  902. getsize:=0;
  903. end;
  904. function tvarsym.getpushsize : longint;
  905. begin
  906. if assigned(definition) then
  907. begin
  908. case varspez of
  909. vs_var :
  910. getpushsize:=target_os.size_of_pointer;
  911. vs_value,
  912. vs_const :
  913. begin
  914. case definition^.deftype of
  915. arraydef,
  916. setdef,
  917. stringdef,
  918. recorddef,
  919. objectdef :
  920. getpushsize:=target_os.size_of_pointer;
  921. else
  922. getpushsize:=definition^.size;
  923. end;
  924. end;
  925. end;
  926. end
  927. else
  928. getpushsize:=0;
  929. end;
  930. procedure tvarsym.insert_in_data;
  931. var
  932. l,modulo : longint;
  933. begin
  934. if (var_options and vo_is_external)<>0 then
  935. exit;
  936. { handle static variables of objects especially }
  937. if read_member and (owner^.symtabletype=objectsymtable) and
  938. ((properties and sp_static)<>0) then
  939. begin
  940. { the data filed is generated in parser.pas
  941. with a tobject_FIELDNAME variable }
  942. { this symbol can't be loaded to a register }
  943. var_options:=var_options and not vo_regable;
  944. end
  945. else
  946. if not(read_member) then
  947. begin
  948. { made problems with parameters etc. ! (FK) }
  949. { check for instance of an abstract object or class }
  950. {
  951. if (pvarsym(sym)^.definition^.deftype=objectdef) and
  952. ((pobjectdef(pvarsym(sym)^.definition)^.options and oo_is_abstract)<>0) then
  953. Message(sym_e_no_instance_of_abstract_object);
  954. }
  955. l:=getsize;
  956. case owner^.symtabletype of
  957. stt_exceptsymtable:
  958. { can contain only one symbol, address calculated later }
  959. ;
  960. localsymtable :
  961. begin
  962. is_valid := 0;
  963. modulo:=owner^.datasize and 3;
  964. {$ifdef m68k}
  965. { word alignment required for motorola }
  966. if (l=1) then
  967. l:=2
  968. else
  969. {$endif}
  970. if (l>=4) and (modulo<>0) then
  971. inc(l,4-modulo)
  972. else
  973. if (l>=2) and ((modulo and 1)<>0) then
  974. inc(l,2-(modulo and 1));
  975. inc(owner^.datasize,l);
  976. address:=owner^.datasize;
  977. end;
  978. staticsymtable :
  979. begin
  980. { enable unitilized warning for local symbols }
  981. is_valid := 0;
  982. if (cs_smartlink in aktmoduleswitches) then
  983. bsssegment^.concat(new(pai_cut,init));
  984. {$ifdef GDB}
  985. if cs_debuginfo in aktmoduleswitches then
  986. concatstabto(bsssegment);
  987. {$endif GDB}
  988. if (cs_smartlink in aktmoduleswitches) or
  989. ((var_options and vo_is_c_var)<>0) then
  990. bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)))
  991. else
  992. bsssegment^.concat(new(pai_datablock,init(mangledname,l)));
  993. { increase datasize }
  994. inc(owner^.datasize,l);
  995. { this symbol can't be loaded to a register }
  996. var_options:=var_options and not vo_regable;
  997. end;
  998. globalsymtable :
  999. begin
  1000. if (cs_smartlink in aktmoduleswitches) then
  1001. bsssegment^.concat(new(pai_cut,init));
  1002. {$ifdef GDB}
  1003. if cs_debuginfo in aktmoduleswitches then
  1004. concatstabto(bsssegment);
  1005. {$endif GDB}
  1006. bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)));
  1007. inc(owner^.datasize,l);
  1008. { this symbol can't be loaded to a register }
  1009. var_options:=var_options and not vo_regable;
  1010. end;
  1011. recordsymtable,
  1012. objectsymtable :
  1013. begin
  1014. { this symbol can't be loaded to a register }
  1015. var_options:=var_options and not vo_regable;
  1016. { align record and object fields }
  1017. if (l=1) or (aktpackrecords=1) then
  1018. begin
  1019. address:=owner^.datasize;
  1020. inc(owner^.datasize,l)
  1021. end
  1022. else
  1023. if (l=2) or (aktpackrecords=2) then
  1024. begin
  1025. owner^.datasize:=(owner^.datasize+1) and (not 1);
  1026. address:=owner^.datasize;
  1027. inc(owner^.datasize,l)
  1028. end
  1029. else
  1030. if (l<=4) or (aktpackrecords=4) then
  1031. begin
  1032. owner^.datasize:=(owner^.datasize+3) and (not 3);
  1033. address:=owner^.datasize;
  1034. inc(owner^.datasize,l);
  1035. end
  1036. else
  1037. if (l<=8) or (aktpackrecords=8) then
  1038. begin
  1039. owner^.datasize:=(owner^.datasize+7) and (not 7);
  1040. address:=owner^.datasize;
  1041. inc(owner^.datasize,l);
  1042. end
  1043. else
  1044. if (l<=16) or (aktpackrecords=16) then
  1045. begin
  1046. owner^.datasize:=(owner^.datasize+15) and (not 15);
  1047. address:=owner^.datasize;
  1048. inc(owner^.datasize,l);
  1049. end
  1050. else
  1051. if (l<=32) or (aktpackrecords=32) then
  1052. begin
  1053. owner^.datasize:=(owner^.datasize+31) and (not 31);
  1054. address:=owner^.datasize;
  1055. inc(owner^.datasize,l);
  1056. end;
  1057. end;
  1058. parasymtable :
  1059. begin
  1060. { here we need the size of a push instead of the
  1061. size of the data }
  1062. l:=getpushsize;
  1063. address:=owner^.datasize;
  1064. owner^.datasize:=align(owner^.datasize+l,target_os.stackalignment);
  1065. end
  1066. else
  1067. begin
  1068. modulo:=owner^.datasize and 3 ;
  1069. if (l>=4) and (modulo<>0) then
  1070. inc(owner^.datasize,4-modulo)
  1071. else
  1072. if (l>=2) and ((modulo and 1)<>0) then
  1073. inc(owner^.datasize);
  1074. address:=owner^.datasize;
  1075. inc(owner^.datasize,l);
  1076. end;
  1077. end;
  1078. end;
  1079. end;
  1080. {$ifdef GDB}
  1081. function tvarsym.stabstring : pchar;
  1082. var
  1083. st : char;
  1084. begin
  1085. if (owner^.symtabletype = objectsymtable) and
  1086. ((properties and sp_static)<>0) then
  1087. begin
  1088. if (cs_gdb_gsym in aktglobalswitches) then st := 'G' else st := 'S';
  1089. stabstring := strpnew('"'+owner^.name^+'__'+name+':'+
  1090. +definition^.numberstring+'",'+
  1091. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1092. end
  1093. else if (owner^.symtabletype = globalsymtable) or
  1094. (owner^.symtabletype = unitsymtable) then
  1095. begin
  1096. { Here we used S instead of
  1097. because with G GDB doesn't look at the address field
  1098. but searches the same name or with a leading underscore
  1099. but these names don't exist in pascal !}
  1100. if (cs_gdb_gsym in aktglobalswitches) then st := 'G' else st := 'S';
  1101. stabstring := strpnew('"'+name+':'+st
  1102. +definition^.numberstring+'",'+
  1103. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1104. end
  1105. else if owner^.symtabletype = staticsymtable then
  1106. begin
  1107. stabstring := strpnew('"'+name+':S'
  1108. +definition^.numberstring+'",'+
  1109. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1110. end
  1111. else if (owner^.symtabletype=parasymtable) then
  1112. begin
  1113. case varspez of
  1114. vs_var : st := 'v';
  1115. vs_value,
  1116. vs_const : if push_addr_param(definition) then
  1117. st := 'v' { should be 'i' but 'i' doesn't work }
  1118. else
  1119. st := 'p';
  1120. end;
  1121. stabstring := strpnew('"'+name+':'+st
  1122. +definition^.numberstring+'",'+
  1123. tostr(N_PSYM)+',0,'+tostr(fileinfo.line)+','+
  1124. tostr(address+owner^.address_fixup));
  1125. {offset to ebp => will not work if the framepointer is esp
  1126. so some optimizing will make things harder to debug }
  1127. end
  1128. else if (owner^.symtabletype=localsymtable) then
  1129. {$ifdef i386}
  1130. if reg<>R_NO then
  1131. begin
  1132. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1133. { this is the register order for GDB}
  1134. stabstring:=strpnew('"'+name+':r'
  1135. +definition^.numberstring+'",'+
  1136. tostr(N_RSYM)+',0,'+
  1137. tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
  1138. end
  1139. else
  1140. {$endif i386}
  1141. stabstring := strpnew('"'+name+':'
  1142. +definition^.numberstring+'",'+
  1143. tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',-'+tostr(address))
  1144. else
  1145. stabstring := inherited stabstring;
  1146. end;
  1147. procedure tvarsym.concatstabto(asmlist : paasmoutput);
  1148. {$ifdef i386}
  1149. var stab_str : pchar;
  1150. {$endif i386}
  1151. begin
  1152. inherited concatstabto(asmlist);
  1153. {$ifdef i386}
  1154. if (owner^.symtabletype=parasymtable) and
  1155. (reg<>R_NO) then
  1156. begin
  1157. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1158. { this is the register order for GDB}
  1159. stab_str:=strpnew('"'+name+':r'
  1160. +definition^.numberstring+'",'+
  1161. tostr(N_RSYM)+',0,'+
  1162. tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
  1163. asmlist^.concat(new(pai_stabs,init(stab_str)));
  1164. end;
  1165. {$endif i386}
  1166. end;
  1167. {$endif GDB}
  1168. destructor tvarsym.done;
  1169. begin
  1170. strdispose(_mangledname);
  1171. inherited done;
  1172. end;
  1173. {****************************************************************************
  1174. TTYPEDCONSTSYM
  1175. *****************************************************************************}
  1176. constructor ttypedconstsym.init(const n : string;p : pdef);
  1177. begin
  1178. tsym.init(n);
  1179. typ:=typedconstsym;
  1180. definition:=p;
  1181. prefix:=stringdup(procprefix);
  1182. end;
  1183. constructor ttypedconstsym.load;
  1184. begin
  1185. tsym.load;
  1186. typ:=typedconstsym;
  1187. definition:=readdefref;
  1188. prefix:=stringdup(readstring);
  1189. end;
  1190. destructor ttypedconstsym.done;
  1191. begin
  1192. stringdispose(prefix);
  1193. tsym.done;
  1194. end;
  1195. function ttypedconstsym.mangledname : string;
  1196. begin
  1197. mangledname:='TC_'+prefix^+'_'+name;
  1198. end;
  1199. function ttypedconstsym.getsize : longint;
  1200. begin
  1201. if assigned(definition) then
  1202. getsize:=definition^.size
  1203. else
  1204. getsize:=0;
  1205. end;
  1206. procedure ttypedconstsym.deref;
  1207. begin
  1208. resolvedef(definition);
  1209. end;
  1210. procedure ttypedconstsym.write;
  1211. begin
  1212. tsym.write;
  1213. writedefref(definition);
  1214. writestring(prefix^);
  1215. current_ppu^.writeentry(ibtypedconstsym);
  1216. end;
  1217. { for most symbol types ther is nothing to do at all }
  1218. procedure ttypedconstsym.insert_in_data;
  1219. begin
  1220. { here there is a problem for ansistrings !! }
  1221. { we must write the label only after the 12 header bytes (PM)
  1222. if not is_ansistring(definition) then
  1223. }
  1224. { solved, the ansis string is moved to consts (FK) }
  1225. really_insert_in_data;
  1226. end;
  1227. procedure ttypedconstsym.really_insert_in_data;
  1228. begin
  1229. if owner^.symtabletype=globalsymtable then
  1230. begin
  1231. if (cs_smartlink in aktmoduleswitches) then
  1232. datasegment^.concat(new(pai_cut,init));
  1233. {$ifdef GDB}
  1234. if cs_debuginfo in aktmoduleswitches then
  1235. concatstabto(datasegment);
  1236. {$endif GDB}
  1237. datasegment^.concat(new(pai_symbol,init_global(mangledname)));
  1238. end
  1239. else
  1240. if owner^.symtabletype<>unitsymtable then
  1241. begin
  1242. if (cs_smartlink in aktmoduleswitches) then
  1243. datasegment^.concat(new(pai_cut,init));
  1244. {$ifdef GDB}
  1245. if cs_debuginfo in aktmoduleswitches then
  1246. concatstabto(datasegment);
  1247. {$endif GDB}
  1248. if (cs_smartlink in aktmoduleswitches) then
  1249. datasegment^.concat(new(pai_symbol,init_global(mangledname)))
  1250. else
  1251. datasegment^.concat(new(pai_symbol,init(mangledname)));
  1252. end;
  1253. end;
  1254. {$ifdef GDB}
  1255. function ttypedconstsym.stabstring : pchar;
  1256. var
  1257. st : char;
  1258. begin
  1259. if (cs_gdb_gsym in aktglobalswitches) and (owner^.symtabletype in [unitsymtable,globalsymtable]) then
  1260. st := 'G'
  1261. else
  1262. st := 'S';
  1263. stabstring := strpnew('"'+name+':'+st+
  1264. definition^.numberstring+'",'+tostr(n_STSYM)+',0,'+
  1265. tostr(fileinfo.line)+','+mangledname);
  1266. end;
  1267. {$endif GDB}
  1268. {****************************************************************************
  1269. TCONSTSYM
  1270. ****************************************************************************}
  1271. constructor tconstsym.init(const n : string;t : tconsttype;v : longint);
  1272. begin
  1273. inherited init(n);
  1274. typ:=constsym;
  1275. consttype:=t;
  1276. value:=v;
  1277. definition:=nil;
  1278. len:=0;
  1279. end;
  1280. constructor tconstsym.init_def(const n : string;t : tconsttype;v : longint;def : pdef);
  1281. begin
  1282. inherited init(n);
  1283. typ:=constsym;
  1284. consttype:=t;
  1285. value:=v;
  1286. definition:=def;
  1287. len:=0;
  1288. end;
  1289. constructor tconstsym.init_string(const n : string;t : tconsttype;str:pchar;l:longint);
  1290. begin
  1291. inherited init(n);
  1292. typ:=constsym;
  1293. consttype:=t;
  1294. value:=longint(str);
  1295. definition:=nil;
  1296. len:=l;
  1297. end;
  1298. constructor tconstsym.load;
  1299. var
  1300. pd : pbestreal;
  1301. ps : pnormalset;
  1302. begin
  1303. tsym.load;
  1304. typ:=constsym;
  1305. consttype:=tconsttype(readbyte);
  1306. case consttype of
  1307. constint,
  1308. constbool,
  1309. constchar : value:=readlong;
  1310. constord :
  1311. begin
  1312. definition:=readdefref;
  1313. value:=readlong;
  1314. end;
  1315. conststring :
  1316. begin
  1317. len:=readlong;
  1318. getmem(pchar(value),len+1);
  1319. current_ppu^.getdata(pchar(value)^,len);
  1320. end;
  1321. constreal :
  1322. begin
  1323. new(pd);
  1324. pd^:=readreal;
  1325. value:=longint(pd);
  1326. end;
  1327. constset :
  1328. begin
  1329. definition:=readdefref;
  1330. new(ps);
  1331. readnormalset(ps^);
  1332. value:=longint(ps);
  1333. end;
  1334. constnil : ;
  1335. else
  1336. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttype)));
  1337. end;
  1338. end;
  1339. destructor tconstsym.done;
  1340. begin
  1341. case consttype of
  1342. conststring :
  1343. freemem(pchar(value),len+1);
  1344. constreal :
  1345. dispose(pbestreal(value));
  1346. constset :
  1347. dispose(pnormalset(value));
  1348. end;
  1349. inherited done;
  1350. end;
  1351. function tconstsym.mangledname : string;
  1352. begin
  1353. mangledname:=name;
  1354. end;
  1355. procedure tconstsym.deref;
  1356. begin
  1357. if consttype in [constord,constset] then
  1358. resolvedef(pdef(definition));
  1359. end;
  1360. procedure tconstsym.write;
  1361. begin
  1362. tsym.write;
  1363. writebyte(byte(consttype));
  1364. case consttype of
  1365. constnil : ;
  1366. constint,
  1367. constbool,
  1368. constchar :
  1369. writelong(value);
  1370. constord :
  1371. begin
  1372. writedefref(definition);
  1373. writelong(value);
  1374. end;
  1375. conststring :
  1376. begin
  1377. writelong(len);
  1378. current_ppu^.putdata(pchar(value)^,len);
  1379. end;
  1380. constreal :
  1381. writereal(pbestreal(value)^);
  1382. constset :
  1383. begin
  1384. writedefref(definition);
  1385. writenormalset(pointer(value)^);
  1386. end;
  1387. else
  1388. internalerror(13);
  1389. end;
  1390. current_ppu^.writeentry(ibconstsym);
  1391. end;
  1392. {$ifdef GDB}
  1393. function tconstsym.stabstring : pchar;
  1394. var st : string;
  1395. begin
  1396. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1397. case consttype of
  1398. conststring : begin
  1399. { I had to remove ibm2ascii !! }
  1400. st := pstring(value)^;
  1401. {st := ibm2ascii(pstring(value)^);}
  1402. st := 's'''+st+'''';
  1403. end;
  1404. constbool, constint, constord, constchar : st := 'i'+tostr(value);
  1405. constreal : begin
  1406. system.str(pbestreal(value)^,st);
  1407. st := 'r'+st;
  1408. end;
  1409. { if we don't know just put zero !! }
  1410. else st:='i0';
  1411. {***SETCONST}
  1412. {constset:;} {*** I don't know what to do with a set.}
  1413. { sets are not recognized by GDB}
  1414. {***}
  1415. end;
  1416. stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
  1417. tostr(fileinfo.line)+',0');
  1418. end;
  1419. procedure tconstsym.concatstabto(asmlist : paasmoutput);
  1420. begin
  1421. if consttype <> conststring then
  1422. inherited concatstabto(asmlist);
  1423. end;
  1424. {$endif GDB}
  1425. {****************************************************************************
  1426. TENUMSYM
  1427. ****************************************************************************}
  1428. constructor tenumsym.init(const n : string;def : penumdef;v : longint);
  1429. begin
  1430. tsym.init(n);
  1431. typ:=enumsym;
  1432. definition:=def;
  1433. value:=v;
  1434. if def^.min>v then
  1435. def^.setmin(v);
  1436. if def^.max<v then
  1437. def^.setmax(v);
  1438. order;
  1439. end;
  1440. constructor tenumsym.load;
  1441. begin
  1442. tsym.load;
  1443. typ:=enumsym;
  1444. definition:=penumdef(readdefref);
  1445. value:=readlong;
  1446. next := Nil;
  1447. end;
  1448. procedure tenumsym.deref;
  1449. begin
  1450. resolvedef(pdef(definition));
  1451. order;
  1452. end;
  1453. procedure tenumsym.order;
  1454. var
  1455. sym : penumsym;
  1456. begin
  1457. sym := definition^.first;
  1458. if sym = nil then
  1459. begin
  1460. definition^.first := @self;
  1461. next := nil;
  1462. exit;
  1463. end;
  1464. { reorder the symbols in increasing value }
  1465. if value < sym^.value then
  1466. begin
  1467. next := sym;
  1468. definition^.first := @self;
  1469. end
  1470. else
  1471. begin
  1472. while (sym^.value <= value) and assigned(sym^.next) do
  1473. sym := sym^.next;
  1474. next := sym^.next;
  1475. sym^.next := @self;
  1476. end;
  1477. end;
  1478. procedure tenumsym.write;
  1479. begin
  1480. tsym.write;
  1481. writedefref(definition);
  1482. writelong(value);
  1483. current_ppu^.writeentry(ibenumsym);
  1484. end;
  1485. {$ifdef GDB}
  1486. procedure tenumsym.concatstabto(asmlist : paasmoutput);
  1487. begin
  1488. {enum elements have no stab !}
  1489. end;
  1490. {$EndIf GDB}
  1491. {****************************************************************************
  1492. TTYPESYM
  1493. ****************************************************************************}
  1494. constructor ttypesym.init(const n : string;d : pdef);
  1495. begin
  1496. tsym.init(n);
  1497. typ:=typesym;
  1498. definition:=d;
  1499. {$ifdef GDB}
  1500. isusedinstab := false;
  1501. {$endif GDB}
  1502. forwardpointer:=nil;
  1503. { this allows to link definitions with the type with declares }
  1504. { them }
  1505. if assigned(definition) then
  1506. if definition^.sym=nil then
  1507. definition^.sym:=@self;
  1508. end;
  1509. constructor ttypesym.load;
  1510. begin
  1511. tsym.load;
  1512. typ:=typesym;
  1513. forwardpointer:=nil;
  1514. {$ifdef GDB}
  1515. isusedinstab := false;
  1516. {$endif GDB}
  1517. definition:=readdefref;
  1518. end;
  1519. destructor ttypesym.done;
  1520. begin
  1521. if assigned(definition) then
  1522. if definition^.sym=@self then
  1523. definition^.sym:=nil;
  1524. inherited done;
  1525. end;
  1526. procedure ttypesym.deref;
  1527. begin
  1528. resolvedef(definition);
  1529. if assigned(definition) then
  1530. begin
  1531. if definition^.sym=nil then
  1532. definition^.sym:=@self;
  1533. if (definition^.deftype=recorddef) and assigned(precdef(definition)^.symtable) and
  1534. (definition^.sym=@self) then
  1535. precdef(definition)^.symtable^.name:=stringdup('record '+name);
  1536. end;
  1537. end;
  1538. procedure ttypesym.write;
  1539. begin
  1540. tsym.write;
  1541. writedefref(definition);
  1542. current_ppu^.writeentry(ibtypesym);
  1543. end;
  1544. procedure ttypesym.load_references;
  1545. begin
  1546. inherited load_references;
  1547. if (definition^.deftype=recorddef) then
  1548. precdef(definition)^.symtable^.load_browser;
  1549. if (definition^.deftype=objectdef) then
  1550. pobjectdef(definition)^.publicsyms^.load_browser;
  1551. end;
  1552. function ttypesym.write_references : boolean;
  1553. begin
  1554. if not inherited write_references then
  1555. { write address of this symbol if record or object
  1556. even if no real refs are there
  1557. because we need it for the symtable }
  1558. if (definition^.deftype=recorddef) or
  1559. (definition^.deftype=objectdef) then
  1560. begin
  1561. writesymref(@self);
  1562. current_ppu^.writeentry(ibsymref);
  1563. end;
  1564. write_references:=true;
  1565. if (definition^.deftype=recorddef) then
  1566. precdef(definition)^.symtable^.write_browser;
  1567. if (definition^.deftype=objectdef) then
  1568. pobjectdef(definition)^.publicsyms^.write_browser;
  1569. end;
  1570. {$ifdef BrowserLog}
  1571. procedure ttypesym.add_to_browserlog;
  1572. begin
  1573. inherited add_to_browserlog;
  1574. if (definition^.deftype=recorddef) then
  1575. precdef(definition)^.symtable^.writebrowserlog;
  1576. if (definition^.deftype=objectdef) then
  1577. pobjectdef(definition)^.publicsyms^.writebrowserlog;
  1578. end;
  1579. {$endif BrowserLog}
  1580. {$ifdef GDB}
  1581. function ttypesym.stabstring : pchar;
  1582. var stabchar : string[2];
  1583. short : string;
  1584. begin
  1585. if definition^.deftype in tagtypes then
  1586. stabchar := 'Tt'
  1587. else
  1588. stabchar := 't';
  1589. short := '"'+name+':'+stabchar+definition^.numberstring
  1590. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  1591. stabstring := strpnew(short);
  1592. end;
  1593. procedure ttypesym.concatstabto(asmlist : paasmoutput);
  1594. begin
  1595. {not stabs for forward defs }
  1596. if assigned(definition) then
  1597. if (definition^.sym = @self) then
  1598. definition^.concatstabto(asmlist)
  1599. else
  1600. inherited concatstabto(asmlist);
  1601. end;
  1602. {$endif GDB}
  1603. {****************************************************************************
  1604. TSYSSYM
  1605. ****************************************************************************}
  1606. constructor tsyssym.init(const n : string;l : longint);
  1607. begin
  1608. inherited init(n);
  1609. typ:=syssym;
  1610. number:=l;
  1611. end;
  1612. procedure tsyssym.write;
  1613. begin
  1614. end;
  1615. {$ifdef GDB}
  1616. procedure tsyssym.concatstabto(asmlist : paasmoutput);
  1617. begin
  1618. end;
  1619. {$endif GDB}
  1620. {****************************************************************************
  1621. TMACROSYM
  1622. ****************************************************************************}
  1623. constructor tmacrosym.init(const n : string);
  1624. begin
  1625. inherited init(n);
  1626. typ:=macrosym;
  1627. defined:=true;
  1628. buftext:=nil;
  1629. buflen:=0;
  1630. end;
  1631. destructor tmacrosym.done;
  1632. begin
  1633. if assigned(buftext) then
  1634. freemem(buftext,buflen);
  1635. inherited done;
  1636. end;
  1637. {
  1638. $Log$
  1639. Revision 1.77 1999-04-08 10:11:32 pierre
  1640. + enable uninitilized warnings for static symbols
  1641. Revision 1.76 1999/03/31 13:55:21 peter
  1642. * assembler inlining working for ag386bin
  1643. Revision 1.75 1999/03/24 23:17:27 peter
  1644. * fixed bugs 212,222,225,227,229,231,233
  1645. Revision 1.74 1999/02/23 18:29:27 pierre
  1646. * win32 compilation error fix
  1647. + some work for local browser (not cl=omplete yet)
  1648. Revision 1.73 1999/02/22 13:07:09 pierre
  1649. + -b and -bl options work !
  1650. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1651. is not enabled when quitting global section
  1652. * local vars and procedures are not yet stored into PPU
  1653. Revision 1.72 1999/02/08 09:51:22 pierre
  1654. * gdb info for local functions was wrong
  1655. Revision 1.71 1999/01/23 23:29:41 florian
  1656. * first running version of the new code generator
  1657. * when compiling exceptions under Linux fixed
  1658. Revision 1.70 1999/01/21 22:10:48 peter
  1659. * fixed array of const
  1660. * generic platform independent high() support
  1661. Revision 1.69 1999/01/20 10:20:20 peter
  1662. * don't make localvar copies for assembler procedures
  1663. Revision 1.68 1999/01/12 14:25:36 peter
  1664. + BrowserLog for browser.log generation
  1665. + BrowserCol for browser info in TCollections
  1666. * released all other UseBrowser
  1667. Revision 1.67 1998/12/30 22:15:54 peter
  1668. + farpointer type
  1669. * absolutesym now also stores if its far
  1670. Revision 1.66 1998/12/30 13:41:14 peter
  1671. * released valuepara
  1672. Revision 1.65 1998/12/26 15:35:44 peter
  1673. + read/write of constnil
  1674. Revision 1.64 1998/12/08 10:18:15 peter
  1675. + -gh for heaptrc unit
  1676. Revision 1.63 1998/11/28 16:20:56 peter
  1677. + support for dll variables
  1678. Revision 1.62 1998/11/27 14:50:48 peter
  1679. + open strings, $P switch support
  1680. Revision 1.61 1998/11/18 15:44:18 peter
  1681. * VALUEPARA for tp7 compatible value parameters
  1682. Revision 1.60 1998/11/16 10:13:51 peter
  1683. * label defines are checked at the end of the proc
  1684. Revision 1.59 1998/11/13 12:09:11 peter
  1685. * unused label is now a warning
  1686. Revision 1.58 1998/11/10 10:50:57 pierre
  1687. * temporary fix for long mangled procsym names
  1688. Revision 1.57 1998/11/05 23:39:31 peter
  1689. + typedconst.getsize
  1690. Revision 1.56 1998/10/28 18:26:18 pierre
  1691. * removed some erros after other errors (introduced by useexcept)
  1692. * stabs works again correctly (for how long !)
  1693. Revision 1.55 1998/10/20 08:07:00 pierre
  1694. * several memory corruptions due to double freemem solved
  1695. => never use p^.loc.location:=p^.left^.loc.location;
  1696. + finally I added now by default
  1697. that ra386dir translates global and unit symbols
  1698. + added a first field in tsymtable and
  1699. a nextsym field in tsym
  1700. (this allows to obtain ordered type info for
  1701. records and objects in gdb !)
  1702. Revision 1.54 1998/10/19 08:55:07 pierre
  1703. * wrong stabs info corrected once again !!
  1704. + variable vmt offset with vmt field only if required
  1705. implemented now !!!
  1706. Revision 1.53 1998/10/16 08:51:53 peter
  1707. + target_os.stackalignment
  1708. + stack can be aligned at 2 or 4 byte boundaries
  1709. Revision 1.52 1998/10/08 17:17:32 pierre
  1710. * current_module old scanner tagged as invalid if unit is recompiled
  1711. + added ppheap for better info on tracegetmem of heaptrc
  1712. (adds line column and file index)
  1713. * several memory leaks removed ith help of heaptrc !!
  1714. Revision 1.51 1998/10/08 13:48:50 peter
  1715. * fixed memory leaks for do nothing source
  1716. * fixed unit interdependency
  1717. Revision 1.50 1998/10/06 17:16:56 pierre
  1718. * some memory leaks fixed (thanks to Peter for heaptrc !)
  1719. Revision 1.49 1998/10/01 09:22:55 peter
  1720. * fixed value openarray
  1721. * ungettemp of arrayconstruct
  1722. Revision 1.48 1998/09/26 17:45:44 peter
  1723. + idtoken and only one token table
  1724. Revision 1.47 1998/09/24 15:11:17 peter
  1725. * fixed enum for not GDB
  1726. Revision 1.46 1998/09/23 15:39:13 pierre
  1727. * browser bugfixes
  1728. was adding a reference when looking for the symbol
  1729. if -bSYM_NAME was used
  1730. Revision 1.45 1998/09/21 08:45:24 pierre
  1731. + added vmt_offset in tobjectdef.write for fututre use
  1732. (first steps to have objects without vmt if no virtual !!)
  1733. + added fpu_used field for tabstractprocdef :
  1734. sets this level to 2 if the functions return with value in FPU
  1735. (is then set to correct value at parsing of implementation)
  1736. THIS MIGHT refuse some code with FPU expression too complex
  1737. that were accepted before and even in some cases
  1738. that don't overflow in fact
  1739. ( like if f : float; is a forward that finally in implementation
  1740. only uses one fpu register !!)
  1741. Nevertheless I think that it will improve security on
  1742. FPU operations !!
  1743. * most other changes only for UseBrowser code
  1744. (added symtable references for record and objects)
  1745. local switch for refs to args and local of each function
  1746. (static symtable still missing)
  1747. UseBrowser still not stable and probably broken by
  1748. the definition hash array !!
  1749. Revision 1.44 1998/09/18 16:03:47 florian
  1750. * some changes to compile with Delphi
  1751. Revision 1.43 1998/09/18 08:01:38 pierre
  1752. + improvement on the usebrowser part
  1753. (does not work correctly for now)
  1754. Revision 1.42 1998/09/07 19:33:25 florian
  1755. + some stuff for property rtti added:
  1756. - NameIndex of the TPropInfo record is now written correctly
  1757. - the DEFAULT/NODEFAULT keyword is supported now
  1758. - the default value and the storedsym/def are now written to
  1759. the PPU fiel
  1760. Revision 1.41 1998/09/07 18:46:12 peter
  1761. * update smartlinking, uses getdatalabel
  1762. * renamed ptree.value vars to value_str,value_real,value_set
  1763. Revision 1.40 1998/09/07 17:37:04 florian
  1764. * first fixes for published properties
  1765. Revision 1.39 1998/09/05 22:11:02 florian
  1766. + switch -vb
  1767. * while/repeat loops accept now also word/longbool conditions
  1768. * makebooltojump did an invalid ungetregister32, fixed
  1769. Revision 1.38 1998/09/01 12:53:26 peter
  1770. + aktpackenum
  1771. Revision 1.37 1998/09/01 07:54:25 pierre
  1772. * UseBrowser a little updated (might still be buggy !!)
  1773. * bug in psub.pas in function specifier removed
  1774. * stdcall allowed in interface and in implementation
  1775. (FPC will not yet complain if it is missing in either part
  1776. because stdcall is only a dummy !!)
  1777. Revision 1.36 1998/08/25 13:09:26 pierre
  1778. * corrected mangling sheme :
  1779. cvar add Cprefix to the mixed case name whereas
  1780. export or public use direct name
  1781. Revision 1.35 1998/08/25 12:42:46 pierre
  1782. * CDECL changed to CVAR for variables
  1783. specifications are read in structures also
  1784. + started adding GPC compatibility mode ( option -Sp)
  1785. * names changed to lowercase
  1786. Revision 1.34 1998/08/21 14:08:53 pierre
  1787. + TEST_FUNCRET now default (old code removed)
  1788. works also for m68k (at least compiles)
  1789. Revision 1.33 1998/08/20 12:53:27 peter
  1790. * object_options are always written for object syms
  1791. Revision 1.32 1998/08/20 09:26:46 pierre
  1792. + funcret setting in underproc testing
  1793. compile with _dTEST_FUNCRET
  1794. Revision 1.31 1998/08/17 10:10:12 peter
  1795. - removed OLDPPU
  1796. Revision 1.30 1998/08/13 10:57:29 peter
  1797. * constant sets are now written correctly to the ppufile
  1798. Revision 1.29 1998/08/11 15:31:42 peter
  1799. * write extended to ppu file
  1800. * new version 0.99.7
  1801. Revision 1.28 1998/08/11 14:07:27 peter
  1802. * fixed pushing of high value for openarray
  1803. Revision 1.27 1998/08/10 14:50:31 peter
  1804. + localswitches, moduleswitches, globalswitches splitting
  1805. Revision 1.26 1998/08/10 10:18:35 peter
  1806. + Compiler,Comphook unit which are the new interface units to the
  1807. compiler
  1808. Revision 1.25 1998/07/30 11:18:19 florian
  1809. + first implementation of try ... except on .. do end;
  1810. * limitiation of 65535 bytes parameters for cdecl removed
  1811. Revision 1.24 1998/07/20 18:40:16 florian
  1812. * handling of ansi string constants should now work
  1813. Revision 1.23 1998/07/14 21:37:24 peter
  1814. * fixed packrecords as discussed at the alias
  1815. Revision 1.22 1998/07/14 14:47:08 peter
  1816. * released NEWINPUT
  1817. Revision 1.21 1998/07/13 21:17:38 florian
  1818. * changed to compile with TP
  1819. Revision 1.20 1998/07/10 00:00:05 peter
  1820. * fixed ttypesym bug finally
  1821. * fileinfo in the symtable and better using for unused vars
  1822. Revision 1.19 1998/07/07 17:40:39 peter
  1823. * packrecords 4 works
  1824. * word aligning of parameters
  1825. Revision 1.18 1998/07/07 11:20:15 peter
  1826. + NEWINPUT for a better inputfile and scanner object
  1827. Revision 1.17 1998/06/24 14:48:40 peter
  1828. * ifdef newppu -> ifndef oldppu
  1829. Revision 1.16 1998/06/19 15:40:42 peter
  1830. * removed cosntructor/constructor warning and 0.99.5 recompiles it again
  1831. Revision 1.15 1998/06/17 14:10:18 peter
  1832. * small os2 fixes
  1833. * fixed interdependent units with newppu (remake3 under linux works now)
  1834. Revision 1.14 1998/06/16 08:56:34 peter
  1835. + targetcpu
  1836. * cleaner pmodules for newppu
  1837. Revision 1.13 1998/06/15 15:38:10 pierre
  1838. * small bug in systems.pas corrected
  1839. + operators in different units better hanlded
  1840. Revision 1.12 1998/06/15 14:23:44 daniel
  1841. * Reverted my changes.
  1842. Revision 1.10 1998/06/13 00:10:18 peter
  1843. * working browser and newppu
  1844. * some small fixes against crashes which occured in bp7 (but not in
  1845. fpc?!)
  1846. Revision 1.9 1998/06/12 16:15:35 pierre
  1847. * external name 'C_var';
  1848. export name 'intern_C_var';
  1849. cdecl;
  1850. cdecl;external;
  1851. are now supported only with -Sv switch
  1852. Revision 1.8 1998/06/11 10:11:59 peter
  1853. * -gb works again
  1854. Revision 1.7 1998/06/09 16:01:51 pierre
  1855. + added procedure directive parsing for procvars
  1856. (accepted are popstack cdecl and pascal)
  1857. + added C vars with the following syntax
  1858. var C calias 'true_c_name';(can be followed by external)
  1859. reason is that you must add the Cprefix
  1860. which is target dependent
  1861. Revision 1.6 1998/06/08 22:59:53 peter
  1862. * smartlinking works for win32
  1863. * some defines to exclude some compiler parts
  1864. Revision 1.5 1998/06/04 23:52:02 peter
  1865. * m68k compiles
  1866. + .def file creation moved to gendef.pas so it could also be used
  1867. for win32
  1868. Revision 1.4 1998/06/04 09:55:46 pierre
  1869. * demangled name of procsym reworked to become independant of the mangling scheme
  1870. Revision 1.3 1998/06/03 22:14:20 florian
  1871. * problem with sizes of classes fixed (if the anchestor was declared
  1872. forward, the compiler doesn't update the child classes size)
  1873. Revision 1.2 1998/05/28 14:40:29 peter
  1874. * fixes for newppu, remake3 works now with it
  1875. Revision 1.1 1998/05/27 19:45:09 peter
  1876. * symtable.pas splitted into includefiles
  1877. * symtable adapted for $ifndef OLDPPU
  1878. }