hcgdata.pas 26 KB

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