hcgdata.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Routines for the code generation of data structures
  5. like VMT, Messages, VTables, Interfaces descs
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit hcgdata;
  20. {$i defines.inc}
  21. interface
  22. uses
  23. symtable,aasm;
  24. { generates the message tables for a class }
  25. function genstrmsgtab(_class : pobjectdef) : pasmlabel;
  26. function genintmsgtab(_class : pobjectdef) : pasmlabel;
  27. { generates the method name table }
  28. function genpublishedmethodstable(_class : pobjectdef) : pasmlabel;
  29. { generates a VMT for _class }
  30. procedure genvmt(list : paasmoutput;_class : pobjectdef);
  31. {$ifdef WITHDMT}
  32. { generates a DMT for _class }
  33. function gendmt(_class : pobjectdef) : pasmlabel;
  34. {$endif WITHDMT}
  35. { define INTERFACE_SUPPORT}
  36. {$ifdef INTERFACE_SUPPORT}
  37. function genintftable(_class: pobjectdef): pasmlabel;
  38. {$endif INTERFACE_SUPPORT}
  39. implementation
  40. uses
  41. strings,cutils,cobjects,
  42. globtype,globals,verbose,
  43. symconst,types,
  44. hcodegen, systems,fmodule
  45. {$ifdef INTERFACE_SUPPORT}
  46. {$ifdef i386}
  47. ,cg386ic
  48. {$endif}
  49. {$endif INTERFACE_SUPPORT}
  50. ;
  51. {*****************************************************************************
  52. Message
  53. *****************************************************************************}
  54. type
  55. pprocdeftree = ^tprocdeftree;
  56. tprocdeftree = record
  57. p : pprocdef;
  58. nl : pasmlabel;
  59. l,r : pprocdeftree;
  60. end;
  61. var
  62. root : pprocdeftree;
  63. count : longint;
  64. procedure insertstr(p : pprocdeftree;var at : pprocdeftree);
  65. var
  66. i : longint;
  67. begin
  68. if at=nil then
  69. begin
  70. at:=p;
  71. inc(count);
  72. end
  73. else
  74. begin
  75. i:=strcomp(p^.p^.messageinf.str,at^.p^.messageinf.str);
  76. if i<0 then
  77. insertstr(p,at^.l)
  78. else if i>0 then
  79. insertstr(p,at^.r)
  80. else
  81. Message1(parser_e_duplicate_message_label,strpas(p^.p^.messageinf.str));
  82. end;
  83. end;
  84. procedure disposeprocdeftree(p : pprocdeftree);
  85. begin
  86. if assigned(p^.l) then
  87. disposeprocdeftree(p^.l);
  88. if assigned(p^.r) then
  89. disposeprocdeftree(p^.r);
  90. dispose(p);
  91. end;
  92. procedure insertmsgstr(p : pnamedindexobject);
  93. var
  94. hp : pprocdef;
  95. pt : pprocdeftree;
  96. begin
  97. if psym(p)^.typ=procsym then
  98. begin
  99. hp:=pprocsym(p)^.definition;
  100. while assigned(hp) do
  101. begin
  102. if (po_msgstr in hp^.procoptions) then
  103. begin
  104. new(pt);
  105. pt^.p:=hp;
  106. pt^.l:=nil;
  107. pt^.r:=nil;
  108. insertstr(pt,root);
  109. end;
  110. hp:=hp^.nextoverloaded;
  111. end;
  112. end;
  113. end;
  114. procedure insertint(p : pprocdeftree;var at : pprocdeftree);
  115. begin
  116. if at=nil then
  117. begin
  118. at:=p;
  119. inc(count);
  120. end
  121. else
  122. begin
  123. if p^.p^.messageinf.i<at^.p^.messageinf.i then
  124. insertint(p,at^.l)
  125. else if p^.p^.messageinf.i>at^.p^.messageinf.i then
  126. insertint(p,at^.r)
  127. else
  128. Message1(parser_e_duplicate_message_label,tostr(p^.p^.messageinf.i));
  129. end;
  130. end;
  131. procedure insertmsgint(p : pnamedindexobject);
  132. var
  133. hp : pprocdef;
  134. pt : pprocdeftree;
  135. begin
  136. if psym(p)^.typ=procsym then
  137. begin
  138. hp:=pprocsym(p)^.definition;
  139. while assigned(hp) do
  140. begin
  141. if (po_msgint in hp^.procoptions) then
  142. begin
  143. new(pt);
  144. pt^.p:=hp;
  145. pt^.l:=nil;
  146. pt^.r:=nil;
  147. insertint(pt,root);
  148. end;
  149. hp:=hp^.nextoverloaded;
  150. end;
  151. end;
  152. end;
  153. procedure writenames(p : pprocdeftree);
  154. begin
  155. getdatalabel(p^.nl);
  156. if assigned(p^.l) then
  157. writenames(p^.l);
  158. datasegment^.concat(new(pai_label,init(p^.nl)));
  159. datasegment^.concat(new(pai_const,init_8bit(strlen(p^.p^.messageinf.str))));
  160. datasegment^.concat(new(pai_string,init_pchar(p^.p^.messageinf.str)));
  161. if assigned(p^.r) then
  162. writenames(p^.r);
  163. end;
  164. procedure writestrentry(p : pprocdeftree);
  165. begin
  166. if assigned(p^.l) then
  167. writestrentry(p^.l);
  168. { write name label }
  169. datasegment^.concat(new(pai_const_symbol,init(p^.nl)));
  170. datasegment^.concat(new(pai_const_symbol,initname(p^.p^.mangledname)));
  171. if assigned(p^.r) then
  172. writestrentry(p^.r);
  173. end;
  174. function genstrmsgtab(_class : pobjectdef) : pasmlabel;
  175. var
  176. r : pasmlabel;
  177. begin
  178. root:=nil;
  179. count:=0;
  180. { insert all message handlers into a tree, sorted by name }
  181. _class^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgstr);
  182. { write all names }
  183. if assigned(root) then
  184. writenames(root);
  185. { now start writing of the message string table }
  186. getdatalabel(r);
  187. datasegment^.concat(new(pai_label,init(r)));
  188. genstrmsgtab:=r;
  189. datasegment^.concat(new(pai_const,init_32bit(count)));
  190. if assigned(root) then
  191. begin
  192. writestrentry(root);
  193. disposeprocdeftree(root);
  194. end;
  195. end;
  196. procedure writeintentry(p : pprocdeftree);
  197. begin
  198. if assigned(p^.l) then
  199. writeintentry(p^.l);
  200. { write name label }
  201. datasegment^.concat(new(pai_const,init_32bit(p^.p^.messageinf.i)));
  202. datasegment^.concat(new(pai_const_symbol,initname(p^.p^.mangledname)));
  203. if assigned(p^.r) then
  204. writeintentry(p^.r);
  205. end;
  206. function genintmsgtab(_class : pobjectdef) : pasmlabel;
  207. var
  208. r : pasmlabel;
  209. begin
  210. root:=nil;
  211. count:=0;
  212. { insert all message handlers into a tree, sorted by name }
  213. _class^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgint);
  214. { now start writing of the message string table }
  215. getdatalabel(r);
  216. datasegment^.concat(new(pai_label,init(r)));
  217. genintmsgtab:=r;
  218. datasegment^.concat(new(pai_const,init_32bit(count)));
  219. if assigned(root) then
  220. begin
  221. writeintentry(root);
  222. disposeprocdeftree(root);
  223. end;
  224. end;
  225. {$ifdef WITHDMT}
  226. procedure insertdmtentry(p : pnamedindexobject);
  227. var
  228. hp : pprocdef;
  229. pt : pprocdeftree;
  230. begin
  231. if psym(p)^.typ=procsym then
  232. begin
  233. hp:=pprocsym(p)^.definition;
  234. while assigned(hp) do
  235. begin
  236. if (po_msgint in hp^.procoptions) then
  237. begin
  238. new(pt);
  239. pt^.p:=hp;
  240. pt^.l:=nil;
  241. pt^.r:=nil;
  242. insertint(pt,root);
  243. end;
  244. hp:=hp^.nextoverloaded;
  245. end;
  246. end;
  247. end;
  248. procedure writedmtindexentry(p : pprocdeftree);
  249. begin
  250. if assigned(p^.l) then
  251. writedmtindexentry(p^.l);
  252. datasegment^.concat(new(pai_const,init_32bit(p^.p^.messageinf.i)));
  253. if assigned(p^.r) then
  254. writedmtindexentry(p^.r);
  255. end;
  256. procedure writedmtaddressentry(p : pprocdeftree);
  257. begin
  258. if assigned(p^.l) then
  259. writedmtaddressentry(p^.l);
  260. datasegment^.concat(new(pai_const_symbol,initname(p^.p^.mangledname)));
  261. if assigned(p^.r) then
  262. writedmtaddressentry(p^.r);
  263. end;
  264. function gendmt(_class : pobjectdef) : pasmlabel;
  265. var
  266. r : pasmlabel;
  267. begin
  268. root:=nil;
  269. count:=0;
  270. gendmt:=nil;
  271. { insert all message handlers into a tree, sorted by number }
  272. _class^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}insertdmtentry);
  273. if count>0 then
  274. begin
  275. getdatalabel(r);
  276. gendmt:=r;
  277. datasegment^.concat(new(pai_label,init(r)));
  278. { entries for caching }
  279. datasegment^.concat(new(pai_const,init_32bit(0)));
  280. datasegment^.concat(new(pai_const,init_32bit(0)));
  281. datasegment^.concat(new(pai_const,init_32bit(count)));
  282. if assigned(root) then
  283. begin
  284. writedmtindexentry(root);
  285. writedmtaddressentry(root);
  286. disposeprocdeftree(root);
  287. end;
  288. end;
  289. end;
  290. {$endif WITHDMT}
  291. procedure do_count(p : pnamedindexobject);
  292. begin
  293. if (psym(p)^.typ=procsym) and (sp_published in psym(p)^.symoptions) then
  294. inc(count);
  295. end;
  296. procedure genpubmethodtableentry(p : pnamedindexobject);
  297. var
  298. hp : pprocdef;
  299. l : pasmlabel;
  300. begin
  301. if (psym(p)^.typ=procsym) and (sp_published in psym(p)^.symoptions) then
  302. begin
  303. hp:=pprocsym(p)^.definition;
  304. if assigned(hp^.nextoverloaded) then
  305. internalerror(1209992);
  306. getdatalabel(l);
  307. consts^.concat(new(pai_label,init(l)));
  308. consts^.concat(new(pai_const,init_8bit(length(p^.name))));
  309. consts^.concat(new(pai_string,init(p^.name)));
  310. datasegment^.concat(new(pai_const_symbol,init(l)));
  311. datasegment^.concat(new(pai_const_symbol,initname(hp^.mangledname)));
  312. end;
  313. end;
  314. function genpublishedmethodstable(_class : pobjectdef) : pasmlabel;
  315. var
  316. l : pasmlabel;
  317. begin
  318. count:=0;
  319. _class^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}do_count);
  320. if count>0 then
  321. begin
  322. getdatalabel(l);
  323. datasegment^.concat(new(pai_label,init(l)));
  324. datasegment^.concat(new(pai_const,init_32bit(count)));
  325. _class^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}genpubmethodtableentry);
  326. genpublishedmethodstable:=l;
  327. end
  328. else
  329. genpublishedmethodstable:=nil;
  330. end;
  331. {*****************************************************************************
  332. VMT
  333. *****************************************************************************}
  334. type
  335. pprocdefcoll = ^tprocdefcoll;
  336. tprocdefcoll = record
  337. next : pprocdefcoll;
  338. data : pprocdef;
  339. end;
  340. psymcoll = ^tsymcoll;
  341. tsymcoll = record
  342. next : psymcoll;
  343. name : pstring;
  344. data : pprocdefcoll;
  345. end;
  346. var
  347. wurzel : psymcoll;
  348. nextvirtnumber : longint;
  349. _c : pobjectdef;
  350. has_constructor,has_virtual_method : boolean;
  351. procedure eachsym(sym : pnamedindexobject);
  352. var
  353. procdefcoll : pprocdefcoll;
  354. hp : pprocdef;
  355. symcoll : psymcoll;
  356. _name : string;
  357. stored : boolean;
  358. { creates a new entry in the procsym list }
  359. procedure newentry;
  360. begin
  361. { if not, generate a new symbol item }
  362. new(symcoll);
  363. symcoll^.name:=stringdup(sym^.name);
  364. symcoll^.next:=wurzel;
  365. symcoll^.data:=nil;
  366. wurzel:=symcoll;
  367. hp:=pprocsym(sym)^.definition;
  368. { inserts all definitions }
  369. while assigned(hp) do
  370. begin
  371. new(procdefcoll);
  372. procdefcoll^.data:=hp;
  373. procdefcoll^.next:=symcoll^.data;
  374. symcoll^.data:=procdefcoll;
  375. { if it's a virtual method }
  376. if (po_virtualmethod in hp^.procoptions) then
  377. begin
  378. { then it gets a number ... }
  379. hp^.extnumber:=nextvirtnumber;
  380. { and we inc the number }
  381. inc(nextvirtnumber);
  382. has_virtual_method:=true;
  383. end;
  384. if (hp^.proctypeoption=potype_constructor) then
  385. has_constructor:=true;
  386. { check, if a method should be overridden }
  387. if (po_overridingmethod in hp^.procoptions) then
  388. MessagePos1(hp^.fileinfo,parser_e_nothing_to_be_overridden,_c^.objname^+'.'+_name+hp^.demangled_paras);
  389. { next overloaded method }
  390. hp:=hp^.nextoverloaded;
  391. end;
  392. end;
  393. procedure newdefentry;
  394. begin
  395. new(procdefcoll);
  396. procdefcoll^.data:=hp;
  397. procdefcoll^.next:=symcoll^.data;
  398. symcoll^.data:=procdefcoll;
  399. { if it's a virtual method }
  400. if (po_virtualmethod in hp^.procoptions) then
  401. begin
  402. { then it gets a number ... }
  403. hp^.extnumber:=nextvirtnumber;
  404. { and we inc the number }
  405. inc(nextvirtnumber);
  406. has_virtual_method:=true;
  407. end;
  408. if (hp^.proctypeoption=potype_constructor) then
  409. has_constructor:=true;
  410. { check, if a method should be overridden }
  411. if (po_overridingmethod in hp^.procoptions) then
  412. MessagePos1(hp^.fileinfo,parser_e_nothing_to_be_overridden,_c^.objname^+'.'+_name+hp^.demangled_paras);
  413. end;
  414. label
  415. handlenextdef;
  416. begin
  417. { put only sub routines into the VMT }
  418. if psym(sym)^.typ=procsym then
  419. begin
  420. _name:=sym^.name;
  421. symcoll:=wurzel;
  422. while assigned(symcoll) do
  423. begin
  424. { does the symbol already exist in the list ? }
  425. if _name=symcoll^.name^ then
  426. begin
  427. { walk through all defs of the symbol }
  428. hp:=pprocsym(sym)^.definition;
  429. while assigned(hp) do
  430. begin
  431. { compare with all stored definitions }
  432. procdefcoll:=symcoll^.data;
  433. stored:=false;
  434. while assigned(procdefcoll) do
  435. begin
  436. { compare parameters }
  437. if equal_paras(procdefcoll^.data^.para,hp^.para,cp_all) and
  438. (
  439. (po_virtualmethod in procdefcoll^.data^.procoptions) or
  440. (po_virtualmethod in hp^.procoptions)
  441. ) then
  442. begin { same parameters }
  443. { wenn sie gleich sind }
  444. { und eine davon virtual deklariert ist }
  445. { Fehler falls nur eine VIRTUAL }
  446. if (po_virtualmethod in procdefcoll^.data^.procoptions)<>
  447. (po_virtualmethod in hp^.procoptions) then
  448. begin
  449. { in classes, we hide the old method }
  450. if _c^.is_class then
  451. begin
  452. { warn only if it is the first time,
  453. we hide the method }
  454. if _c=hp^._class then
  455. Message1(parser_w_should_use_override,_c^.objname^+'.'+_name);
  456. end
  457. else
  458. if _c=hp^._class then
  459. begin
  460. if (po_virtualmethod in procdefcoll^.data^.procoptions) then
  461. Message1(parser_w_overloaded_are_not_both_virtual,_c^.objname^+'.'+_name)
  462. else
  463. Message1(parser_w_overloaded_are_not_both_non_virtual,
  464. _c^.objname^+'.'+_name);
  465. end;
  466. { was newentry; exit; (FK) }
  467. newdefentry;
  468. goto handlenextdef;
  469. end
  470. else
  471. { the flags have to match }
  472. { except abstract and override }
  473. { only if both are virtual !! }
  474. if (procdefcoll^.data^.proccalloptions<>hp^.proccalloptions) or
  475. (procdefcoll^.data^.proctypeoption<>hp^.proctypeoption) or
  476. ((procdefcoll^.data^.procoptions-
  477. [po_abstractmethod,po_overridingmethod,po_assembler])<>
  478. (hp^.procoptions-[po_abstractmethod,po_overridingmethod,po_assembler])) then
  479. Message1(parser_e_header_dont_match_forward,_c^.objname^+'.'+_name);
  480. { check, if the overridden directive is set }
  481. { (povirtualmethod is set! }
  482. { class ? }
  483. if _c^.is_class and
  484. not(po_overridingmethod in hp^.procoptions) then
  485. begin
  486. { warn only if it is the first time,
  487. we hide the method }
  488. if _c=hp^._class then
  489. Message1(parser_w_should_use_override,_c^.objname^+'.'+_name);
  490. { was newentry; (FK) }
  491. newdefentry;
  492. exit;
  493. end;
  494. { error, if the return types aren't equal }
  495. if not(is_equal(procdefcoll^.data^.rettype.def,hp^.rettype.def)) and
  496. not((procdefcoll^.data^.rettype.def^.deftype=objectdef) and
  497. (hp^.rettype.def^.deftype=objectdef) and
  498. (pobjectdef(procdefcoll^.data^.rettype.def)^.is_class) and
  499. (pobjectdef(hp^.rettype.def)^.is_class) and
  500. (pobjectdef(hp^.rettype.def)^.is_related(
  501. pobjectdef(procdefcoll^.data^.rettype.def)))) then
  502. Message1(parser_e_overloaded_methodes_not_same_ret,_c^.objname^+'.'+_name);
  503. { now set the number }
  504. hp^.extnumber:=procdefcoll^.data^.extnumber;
  505. { and exchange }
  506. procdefcoll^.data:=hp;
  507. stored:=true;
  508. goto handlenextdef;
  509. end; { same parameters }
  510. procdefcoll:=procdefcoll^.next;
  511. end;
  512. { if it isn't saved in the list }
  513. { we create a new entry }
  514. if not(stored) then
  515. begin
  516. new(procdefcoll);
  517. procdefcoll^.data:=hp;
  518. procdefcoll^.next:=symcoll^.data;
  519. symcoll^.data:=procdefcoll;
  520. { if the method is virtual ... }
  521. if (po_virtualmethod in hp^.procoptions) then
  522. begin
  523. { ... it will get a number }
  524. hp^.extnumber:=nextvirtnumber;
  525. inc(nextvirtnumber);
  526. end;
  527. { check, if a method should be overridden }
  528. if (po_overridingmethod in hp^.procoptions) then
  529. MessagePos1(hp^.fileinfo,parser_e_nothing_to_be_overridden,
  530. _c^.objname^+'.'+_name+hp^.demangled_paras);
  531. end;
  532. handlenextdef:
  533. hp:=hp^.nextoverloaded;
  534. end;
  535. exit;
  536. end;
  537. symcoll:=symcoll^.next;
  538. end;
  539. newentry;
  540. end;
  541. end;
  542. procedure genvmt(list : paasmoutput;_class : pobjectdef);
  543. procedure do_genvmt(p : pobjectdef);
  544. begin
  545. { start with the base class }
  546. if assigned(p^.childof) then
  547. do_genvmt(p^.childof);
  548. { walk through all public syms }
  549. { I had to change that to solve bug0260 (PM)}
  550. { _c:=p; }
  551. _c:=_class;
  552. { Florian, please check if you agree (PM) }
  553. { no it wasn't correct, but I fixed it at }
  554. { another place: your fix hides only a bug }
  555. { _c is only used to give correct warnings }
  556. p^.symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym);
  557. end;
  558. var
  559. symcoll : psymcoll;
  560. procdefcoll : pprocdefcoll;
  561. i : longint;
  562. begin
  563. wurzel:=nil;
  564. nextvirtnumber:=0;
  565. has_constructor:=false;
  566. has_virtual_method:=false;
  567. { generates a tree of all used methods }
  568. do_genvmt(_class);
  569. if has_virtual_method and not(has_constructor) then
  570. Message1(parser_w_virtual_without_constructor,_class^.objname^);
  571. { generates the VMT }
  572. { walk trough all numbers for virtual methods and search }
  573. { the method }
  574. for i:=0 to nextvirtnumber-1 do
  575. begin
  576. symcoll:=wurzel;
  577. { walk trough all symbols }
  578. while assigned(symcoll) do
  579. begin
  580. { walk trough all methods }
  581. procdefcoll:=symcoll^.data;
  582. while assigned(procdefcoll) do
  583. begin
  584. { writes the addresses to the VMT }
  585. { but only this which are declared as virtual }
  586. if procdefcoll^.data^.extnumber=i then
  587. begin
  588. if (po_virtualmethod in procdefcoll^.data^.procoptions) then
  589. begin
  590. { if a method is abstract, then is also the }
  591. { class abstract and it's not allow to }
  592. { generates an instance }
  593. if (po_abstractmethod in procdefcoll^.data^.procoptions) then
  594. begin
  595. include(_class^.objectoptions,oo_has_abstract);
  596. list^.concat(new(pai_const_symbol,initname('FPC_ABSTRACTERROR')));
  597. end
  598. else
  599. begin
  600. list^.concat(new(pai_const_symbol,
  601. initname(procdefcoll^.data^.mangledname)));
  602. end;
  603. end;
  604. end;
  605. procdefcoll:=procdefcoll^.next;
  606. end;
  607. symcoll:=symcoll^.next;
  608. end;
  609. end;
  610. { disposes the above generated tree }
  611. symcoll:=wurzel;
  612. while assigned(symcoll) do
  613. begin
  614. wurzel:=symcoll^.next;
  615. stringdispose(symcoll^.name);
  616. procdefcoll:=symcoll^.data;
  617. while assigned(procdefcoll) do
  618. begin
  619. symcoll^.data:=procdefcoll^.next;
  620. dispose(procdefcoll);
  621. procdefcoll:=symcoll^.data;
  622. end;
  623. dispose(symcoll);
  624. symcoll:=wurzel;
  625. end;
  626. end;
  627. end.
  628. {
  629. $Log$
  630. Revision 1.5 2000-09-24 15:06:17 peter
  631. * use defines.inc
  632. Revision 1.4 2000/08/27 16:11:51 peter
  633. * moved some util functions from globals,cobjects to cutils
  634. * splitted files into finput,fmodule
  635. Revision 1.3 2000/07/13 12:08:26 michael
  636. + patched to 1.1.0 with former 1.09patch from peter
  637. Revision 1.2 2000/07/13 11:32:41 michael
  638. + removed logs
  639. }