hcgdata.pas 26 KB

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