nobj.pas 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404
  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 nobj;
  20. {$i defines.inc}
  21. interface
  22. uses
  23. cutils,cclasses,
  24. symdef,aasm;
  25. type
  26. pprocdeftree = ^tprocdeftree;
  27. tprocdeftree = record
  28. data : tprocdef;
  29. nl : tasmlabel;
  30. l,r : pprocdeftree;
  31. end;
  32. pprocdefcoll = ^tprocdefcoll;
  33. tprocdefcoll = record
  34. data : tprocdef;
  35. hidden : boolean;
  36. next : pprocdefcoll;
  37. end;
  38. psymcoll = ^tsymcoll;
  39. tsymcoll = record
  40. name : pstring;
  41. data : pprocdefcoll;
  42. next : psymcoll;
  43. end;
  44. tclassheader=class
  45. private
  46. _Class : tobjectdef;
  47. count : integer;
  48. private
  49. { message tables }
  50. root : pprocdeftree;
  51. procedure disposeprocdeftree(p : pprocdeftree);
  52. procedure insertmsgint(p : tnamedindexitem);
  53. procedure insertmsgstr(p : tnamedindexitem);
  54. procedure insertint(p : pprocdeftree;var at : pprocdeftree);
  55. procedure insertstr(p : pprocdeftree;var at : pprocdeftree);
  56. procedure writenames(p : pprocdeftree);
  57. procedure writeintentry(p : pprocdeftree);
  58. procedure writestrentry(p : pprocdeftree);
  59. {$ifdef WITHDMT}
  60. private
  61. { dmt }
  62. procedure insertdmtentry(p : tnamedindexitem);
  63. procedure writedmtindexentry(p : pprocdeftree);
  64. procedure writedmtaddressentry(p : pprocdeftree);
  65. {$endif}
  66. private
  67. { published methods }
  68. procedure do_count(p : tnamedindexitem);
  69. procedure genpubmethodtableentry(p : tnamedindexitem);
  70. private
  71. { vmt }
  72. wurzel : psymcoll;
  73. nextvirtnumber : integer;
  74. has_constructor,
  75. has_virtual_method : boolean;
  76. procedure eachsym(sym : tnamedindexitem);
  77. procedure disposevmttree;
  78. procedure writevirtualmethods(List:TAAsmoutput);
  79. private
  80. { interface tables }
  81. function gintfgetvtbllabelname(intfindex: integer): string;
  82. procedure gintfcreatevtbl(intfindex: integer; rawdata,rawcode: TAAsmoutput);
  83. procedure gintfgenentry(intfindex, contintfindex: integer; rawdata: TAAsmoutput);
  84. procedure gintfoptimizevtbls(implvtbl : plongint);
  85. procedure gintfwritedata;
  86. function gintfgetcprocdef(proc: tprocdef;const name: string): tprocdef;
  87. procedure gintfdoonintf(intf: tobjectdef; intfindex: longint);
  88. procedure gintfwalkdowninterface(intf: tobjectdef; intfindex: longint);
  89. protected
  90. procedure cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract;
  91. public
  92. constructor create(c:tobjectdef);
  93. destructor destroy;override;
  94. { generates the message tables for a class }
  95. function genstrmsgtab : tasmlabel;
  96. function genintmsgtab : tasmlabel;
  97. function genpublishedmethodstable : tasmlabel;
  98. { generates a VMT entries }
  99. procedure genvmt;
  100. {$ifdef WITHDMT}
  101. { generates a DMT for _class }
  102. function gendmt : tasmlabel;
  103. {$endif WITHDMT}
  104. { interfaces }
  105. function genintftable: tasmlabel;
  106. { write the VMT to datasegment }
  107. procedure writevmt;
  108. procedure writeinterfaceids;
  109. end;
  110. tclassheaderclass=class of tclassheader;
  111. var
  112. cclassheader : tclassheaderclass;
  113. implementation
  114. uses
  115. {$ifdef delphi}
  116. sysutils,
  117. {$else}
  118. strings,
  119. {$endif}
  120. globtype,globals,verbose,
  121. symtable,symconst,symtype,symsym,types,
  122. fmodule,
  123. {$ifdef GDB}
  124. gdb,
  125. {$endif GDB}
  126. cpuinfo,cpubase
  127. ;
  128. {*****************************************************************************
  129. TClassHeader
  130. *****************************************************************************}
  131. constructor tclassheader.create(c:tobjectdef);
  132. begin
  133. inherited Create;
  134. _Class:=c;
  135. end;
  136. destructor tclassheader.destroy;
  137. begin
  138. disposevmttree;
  139. end;
  140. {**************************************
  141. Message Tables
  142. **************************************}
  143. procedure tclassheader.disposeprocdeftree(p : pprocdeftree);
  144. begin
  145. if assigned(p^.l) then
  146. disposeprocdeftree(p^.l);
  147. if assigned(p^.r) then
  148. disposeprocdeftree(p^.r);
  149. dispose(p);
  150. end;
  151. procedure tclassheader.insertint(p : pprocdeftree;var at : pprocdeftree);
  152. begin
  153. if at=nil then
  154. begin
  155. at:=p;
  156. inc(count);
  157. end
  158. else
  159. begin
  160. if p^.data.messageinf.i<at^.data.messageinf.i then
  161. insertint(p,at^.l)
  162. else if p^.data.messageinf.i>at^.data.messageinf.i then
  163. insertint(p,at^.r)
  164. else
  165. Message1(parser_e_duplicate_message_label,tostr(p^.data.messageinf.i));
  166. end;
  167. end;
  168. procedure tclassheader.insertstr(p : pprocdeftree;var at : pprocdeftree);
  169. var
  170. i : integer;
  171. begin
  172. if at=nil then
  173. begin
  174. at:=p;
  175. inc(count);
  176. end
  177. else
  178. begin
  179. i:=strcomp(p^.data.messageinf.str,at^.data.messageinf.str);
  180. if i<0 then
  181. insertstr(p,at^.l)
  182. else if i>0 then
  183. insertstr(p,at^.r)
  184. else
  185. Message1(parser_e_duplicate_message_label,strpas(p^.data.messageinf.str));
  186. end;
  187. end;
  188. procedure tclassheader.insertmsgint(p : tnamedindexitem);
  189. var
  190. hp : pprocdeflist;
  191. pt : pprocdeftree;
  192. begin
  193. if tsym(p).typ=procsym then
  194. begin
  195. hp:=tprocsym(p).defs;
  196. while assigned(hp) do
  197. begin
  198. if (po_msgint in hp^.def.procoptions) then
  199. begin
  200. new(pt);
  201. pt^.data:=hp^.def;
  202. pt^.l:=nil;
  203. pt^.r:=nil;
  204. insertint(pt,root);
  205. end;
  206. hp:=hp^.next;
  207. end;
  208. end;
  209. end;
  210. procedure tclassheader.insertmsgstr(p : tnamedindexitem);
  211. var
  212. hp : pprocdeflist;
  213. pt : pprocdeftree;
  214. begin
  215. if tsym(p).typ=procsym then
  216. begin
  217. hp:=tprocsym(p).defs;
  218. while assigned(hp) do
  219. begin
  220. if (po_msgstr in hp^.def.procoptions) then
  221. begin
  222. new(pt);
  223. pt^.data:=hp^.def;
  224. pt^.l:=nil;
  225. pt^.r:=nil;
  226. insertstr(pt,root);
  227. end;
  228. hp:=hp^.next;
  229. end;
  230. end;
  231. end;
  232. procedure tclassheader.writenames(p : pprocdeftree);
  233. begin
  234. getdatalabel(p^.nl);
  235. if assigned(p^.l) then
  236. writenames(p^.l);
  237. dataSegment.concat(Tai_label.Create(p^.nl));
  238. dataSegment.concat(Tai_const.Create_8bit(strlen(p^.data.messageinf.str)));
  239. dataSegment.concat(Tai_string.Create_pchar(p^.data.messageinf.str));
  240. if assigned(p^.r) then
  241. writenames(p^.r);
  242. end;
  243. procedure tclassheader.writestrentry(p : pprocdeftree);
  244. begin
  245. if assigned(p^.l) then
  246. writestrentry(p^.l);
  247. { write name label }
  248. dataSegment.concat(Tai_const_symbol.Create(p^.nl));
  249. dataSegment.concat(Tai_const_symbol.Createname(p^.data.mangledname));
  250. if assigned(p^.r) then
  251. writestrentry(p^.r);
  252. end;
  253. function tclassheader.genstrmsgtab : tasmlabel;
  254. var
  255. r : tasmlabel;
  256. begin
  257. root:=nil;
  258. count:=0;
  259. { insert all message handlers into a tree, sorted by name }
  260. _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgstr);
  261. { write all names }
  262. if assigned(root) then
  263. writenames(root);
  264. { now start writing of the message string table }
  265. getdatalabel(r);
  266. dataSegment.concat(Tai_label.Create(r));
  267. genstrmsgtab:=r;
  268. dataSegment.concat(Tai_const.Create_32bit(count));
  269. if assigned(root) then
  270. begin
  271. writestrentry(root);
  272. disposeprocdeftree(root);
  273. end;
  274. end;
  275. procedure tclassheader.writeintentry(p : pprocdeftree);
  276. begin
  277. if assigned(p^.l) then
  278. writeintentry(p^.l);
  279. { write name label }
  280. dataSegment.concat(Tai_const.Create_32bit(p^.data.messageinf.i));
  281. dataSegment.concat(Tai_const_symbol.Createname(p^.data.mangledname));
  282. if assigned(p^.r) then
  283. writeintentry(p^.r);
  284. end;
  285. function tclassheader.genintmsgtab : tasmlabel;
  286. var
  287. r : tasmlabel;
  288. begin
  289. root:=nil;
  290. count:=0;
  291. { insert all message handlers into a tree, sorted by name }
  292. _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertmsgint);
  293. { now start writing of the message string table }
  294. getdatalabel(r);
  295. dataSegment.concat(Tai_label.Create(r));
  296. genintmsgtab:=r;
  297. dataSegment.concat(Tai_const.Create_32bit(count));
  298. if assigned(root) then
  299. begin
  300. writeintentry(root);
  301. disposeprocdeftree(root);
  302. end;
  303. end;
  304. {$ifdef WITHDMT}
  305. {**************************************
  306. DMT
  307. **************************************}
  308. procedure tclassheader.insertdmtentry(p : tnamedindexitem);
  309. var
  310. hp : tprocdef;
  311. pt : pprocdeftree;
  312. begin
  313. if tsym(p).typ=procsym then
  314. begin
  315. hp:=tprocsym(p).definition;
  316. while assigned(hp) do
  317. begin
  318. if (po_msgint in hp.procoptions) then
  319. begin
  320. new(pt);
  321. pt^.p:=hp;
  322. pt^.l:=nil;
  323. pt^.r:=nil;
  324. insertint(pt,root);
  325. end;
  326. hp:=hp.nextoverloaded;
  327. end;
  328. end;
  329. end;
  330. procedure tclassheader.writedmtindexentry(p : pprocdeftree);
  331. begin
  332. if assigned(p^.l) then
  333. writedmtindexentry(p^.l);
  334. dataSegment.concat(Tai_const.Create_32bit(p^.data.messageinf.i));
  335. if assigned(p^.r) then
  336. writedmtindexentry(p^.r);
  337. end;
  338. procedure tclassheader.writedmtaddressentry(p : pprocdeftree);
  339. begin
  340. if assigned(p^.l) then
  341. writedmtaddressentry(p^.l);
  342. dataSegment.concat(Tai_const_symbol.Createname(p^.data.mangledname));
  343. if assigned(p^.r) then
  344. writedmtaddressentry(p^.r);
  345. end;
  346. function tclassheader.gendmt : tasmlabel;
  347. var
  348. r : tasmlabel;
  349. begin
  350. root:=nil;
  351. count:=0;
  352. gendmt:=nil;
  353. { insert all message handlers into a tree, sorted by number }
  354. _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}insertdmtentry);
  355. if count>0 then
  356. begin
  357. getdatalabel(r);
  358. gendmt:=r;
  359. dataSegment.concat(Tai_label.Create(r));
  360. { entries for caching }
  361. dataSegment.concat(Tai_const.Create_32bit(0));
  362. dataSegment.concat(Tai_const.Create_32bit(0));
  363. dataSegment.concat(Tai_const.Create_32bit(count));
  364. if assigned(root) then
  365. begin
  366. writedmtindexentry(root);
  367. writedmtaddressentry(root);
  368. disposeprocdeftree(root);
  369. end;
  370. end;
  371. end;
  372. {$endif WITHDMT}
  373. {**************************************
  374. Published Methods
  375. **************************************}
  376. procedure tclassheader.do_count(p : tnamedindexitem);
  377. begin
  378. if (tsym(p).typ=procsym) and (sp_published in tsym(p).symoptions) then
  379. inc(count);
  380. end;
  381. procedure tclassheader.genpubmethodtableentry(p : tnamedindexitem);
  382. var
  383. hp : tprocdef;
  384. l : tasmlabel;
  385. begin
  386. if (tsym(p).typ=procsym) and (sp_published in tsym(p).symoptions) then
  387. begin
  388. if assigned(tprocsym(p).defs^.next) then
  389. internalerror(1209992);
  390. hp:=tprocsym(p).defs^.def;
  391. getdatalabel(l);
  392. Consts.concat(Tai_label.Create(l));
  393. Consts.concat(Tai_const.Create_8bit(length(p.name)));
  394. Consts.concat(Tai_string.Create(p.name));
  395. dataSegment.concat(Tai_const_symbol.Create(l));
  396. dataSegment.concat(Tai_const_symbol.Createname(hp.mangledname));
  397. end;
  398. end;
  399. function tclassheader.genpublishedmethodstable : tasmlabel;
  400. var
  401. l : tasmlabel;
  402. begin
  403. count:=0;
  404. _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}do_count);
  405. if count>0 then
  406. begin
  407. getdatalabel(l);
  408. dataSegment.concat(Tai_label.Create(l));
  409. dataSegment.concat(Tai_const.Create_32bit(count));
  410. _class.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}genpubmethodtableentry);
  411. genpublishedmethodstable:=l;
  412. end
  413. else
  414. genpublishedmethodstable:=nil;
  415. end;
  416. {**************************************
  417. VMT
  418. **************************************}
  419. procedure tclassheader.eachsym(sym : tnamedindexitem);
  420. var
  421. procdefcoll : pprocdefcoll;
  422. hp : pprocdeflist;
  423. symcoll : psymcoll;
  424. _name : string;
  425. procedure newdefentry(pd:tprocdef);
  426. begin
  427. new(procdefcoll);
  428. procdefcoll^.data:=pd;
  429. procdefcoll^.hidden:=false;
  430. procdefcoll^.next:=symcoll^.data;
  431. symcoll^.data:=procdefcoll;
  432. { if it's a virtual method }
  433. if (po_virtualmethod in pd.procoptions) then
  434. begin
  435. { then it gets a number ... }
  436. pd.extnumber:=nextvirtnumber;
  437. { and we inc the number }
  438. inc(nextvirtnumber);
  439. has_virtual_method:=true;
  440. end;
  441. if (pd.proctypeoption=potype_constructor) then
  442. has_constructor:=true;
  443. { check, if a method should be overridden }
  444. if (pd._class=_class) and
  445. (po_overridingmethod in pd.procoptions) then
  446. MessagePos1(pd.fileinfo,parser_e_nothing_to_be_overridden,pd.fullprocname);
  447. end;
  448. { creates a new entry in the procsym list }
  449. procedure newentry;
  450. begin
  451. { if not, generate a new symbol item }
  452. new(symcoll);
  453. symcoll^.name:=stringdup(sym.name);
  454. symcoll^.next:=wurzel;
  455. symcoll^.data:=nil;
  456. wurzel:=symcoll;
  457. { inserts all definitions }
  458. hp:=tprocsym(sym).defs;
  459. while assigned(hp) do
  460. begin
  461. newdefentry(hp^.def);
  462. hp:=hp^.next;
  463. end;
  464. end;
  465. label
  466. handlenextdef;
  467. var
  468. pd : tprocdef;
  469. pdoverload : boolean;
  470. begin
  471. { put only sub routines into the VMT }
  472. if tsym(sym).typ=procsym then
  473. begin
  474. { check the current list of symbols }
  475. _name:=sym.name;
  476. symcoll:=wurzel;
  477. while assigned(symcoll) do
  478. begin
  479. { does the symbol already exist in the list ? }
  480. if _name=symcoll^.name^ then
  481. begin
  482. { walk through all defs of the symbol }
  483. hp:=tprocsym(sym).defs;
  484. while assigned(hp) do
  485. begin
  486. pd:=hp^.def;
  487. if pd.procsym=sym then
  488. begin
  489. pdoverload:=(po_overload in pd.procoptions);
  490. { compare with all stored definitions }
  491. procdefcoll:=symcoll^.data;
  492. while assigned(procdefcoll) do
  493. begin
  494. { compare only if the definition is not hidden }
  495. if not procdefcoll^.hidden then
  496. begin
  497. { check if one of the two methods has virtual }
  498. if (po_virtualmethod in procdefcoll^.data.procoptions) or
  499. (po_virtualmethod in pd.procoptions) then
  500. begin
  501. { if the current definition has no virtual then hide the
  502. old virtual if the new definition has the same arguments or
  503. has no overload directive }
  504. if not(po_virtualmethod in pd.procoptions) then
  505. begin
  506. if (not pdoverload or
  507. equal_paras(procdefcoll^.data.para,pd.para,cp_value_equal_const)) and
  508. (tstoredsym(procdefcoll^.data.procsym).is_visible_for_object(pd._class)) then
  509. begin
  510. procdefcoll^.hidden:=true;
  511. if _class=pd._class then
  512. MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname);
  513. end;
  514. end
  515. { if both are virtual we check the header }
  516. else if (po_virtualmethod in pd.procoptions) and
  517. (po_virtualmethod in procdefcoll^.data.procoptions) then
  518. begin
  519. { new one has not override }
  520. if is_class(_class) and
  521. not(po_overridingmethod in pd.procoptions) then
  522. begin
  523. { we start a new virtual tree, hide the old }
  524. if (not pdoverload or
  525. equal_paras(procdefcoll^.data.para,pd.para,cp_value_equal_const)) and
  526. (tstoredsym(procdefcoll^.data.procsym).is_visible_for_object(pd._class)) then
  527. begin
  528. procdefcoll^.hidden:=true;
  529. if _class=pd._class then
  530. MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname);
  531. end;
  532. end
  533. { check if the method to override is visible }
  534. else if (po_overridingmethod in pd.procoptions) and
  535. (not tstoredsym(procdefcoll^.data.procsym).is_visible_for_object(pd._class)) then
  536. begin
  537. { do nothing, the error will follow when adding the entry }
  538. end
  539. { same parameters }
  540. else if (equal_paras(procdefcoll^.data.para,pd.para,cp_value_equal_const)) then
  541. begin
  542. { overload is inherited }
  543. if (po_overload in procdefcoll^.data.procoptions) then
  544. include(pd.procoptions,po_overload);
  545. { the flags have to match except abstract and override }
  546. { only if both are virtual !! }
  547. if (procdefcoll^.data.proccalloption<>pd.proccalloption) or
  548. (procdefcoll^.data.proctypeoption<>pd.proctypeoption) or
  549. ((procdefcoll^.data.procoptions-
  550. [po_abstractmethod,po_overridingmethod,po_assembler,po_overload])<>
  551. (pd.procoptions-[po_abstractmethod,po_overridingmethod,po_assembler,po_overload])) then
  552. MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,pd.fullprocname);
  553. { error, if the return types aren't equal }
  554. if not(is_equal(procdefcoll^.data.rettype.def,pd.rettype.def)) and
  555. not((procdefcoll^.data.rettype.def.deftype=objectdef) and
  556. (pd.rettype.def.deftype=objectdef) and
  557. is_class(procdefcoll^.data.rettype.def) and
  558. is_class(pd.rettype.def) and
  559. (tobjectdef(pd.rettype.def).is_related(
  560. tobjectdef(procdefcoll^.data.rettype.def)))) then
  561. Message2(parser_e_overridden_methods_not_same_ret,pd.fullprocnamewithret,
  562. procdefcoll^.data.fullprocnamewithret);
  563. { now set the number }
  564. pd.extnumber:=procdefcoll^.data.extnumber;
  565. { and exchange }
  566. procdefcoll^.data:=pd;
  567. goto handlenextdef;
  568. end
  569. { different parameters }
  570. else
  571. begin
  572. { when we got an override directive then can search futher for
  573. the procedure to override.
  574. If we are starting a new virtual tree then hide the old tree }
  575. if not(po_overridingmethod in pd.procoptions) and
  576. not pdoverload then
  577. begin
  578. procdefcoll^.hidden:=true;
  579. if _class=pd._class then
  580. MessagePos1(pd.fileinfo,parser_w_should_use_override,pd.fullprocname);
  581. end;
  582. end;
  583. end
  584. else
  585. begin
  586. { the new definition is virtual and the old static, we hide the old one
  587. if the new defintion has not the overload directive }
  588. if not pdoverload or
  589. equal_paras(procdefcoll^.data.para,pd.para,cp_value_equal_const) then
  590. procdefcoll^.hidden:=true;
  591. end;
  592. end
  593. else
  594. begin
  595. { both are static, we hide the old one if the new defintion
  596. has not the overload directive }
  597. if equal_paras(procdefcoll^.data.para,pd.para,cp_value_equal_const) or
  598. not pdoverload then
  599. procdefcoll^.hidden:=true;
  600. end;
  601. end; { not hidden }
  602. procdefcoll:=procdefcoll^.next;
  603. end;
  604. { if it isn't saved in the list we create a new entry }
  605. newdefentry(pd);
  606. end;
  607. handlenextdef:
  608. hp:=hp^.next;
  609. end;
  610. exit;
  611. end;
  612. symcoll:=symcoll^.next;
  613. end;
  614. newentry;
  615. end;
  616. end;
  617. procedure tclassheader.disposevmttree;
  618. var
  619. symcoll : psymcoll;
  620. procdefcoll : pprocdefcoll;
  621. begin
  622. { disposes the above generated tree }
  623. symcoll:=wurzel;
  624. while assigned(symcoll) do
  625. begin
  626. wurzel:=symcoll^.next;
  627. stringdispose(symcoll^.name);
  628. procdefcoll:=symcoll^.data;
  629. while assigned(procdefcoll) do
  630. begin
  631. symcoll^.data:=procdefcoll^.next;
  632. dispose(procdefcoll);
  633. procdefcoll:=symcoll^.data;
  634. end;
  635. dispose(symcoll);
  636. symcoll:=wurzel;
  637. end;
  638. end;
  639. procedure tclassheader.genvmt;
  640. procedure do_genvmt(p : tobjectdef);
  641. begin
  642. { start with the base class }
  643. if assigned(p.childof) then
  644. do_genvmt(p.childof);
  645. { walk through all public syms }
  646. p.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym);
  647. end;
  648. begin
  649. wurzel:=nil;
  650. nextvirtnumber:=0;
  651. has_constructor:=false;
  652. has_virtual_method:=false;
  653. { generates a tree of all used methods }
  654. do_genvmt(_class);
  655. if not(is_interface(_class)) and
  656. has_virtual_method and
  657. not(has_constructor) then
  658. Message1(parser_w_virtual_without_constructor,_class.objrealname^);
  659. end;
  660. {**************************************
  661. Interface tables
  662. **************************************}
  663. function tclassheader.gintfgetvtbllabelname(intfindex: integer): string;
  664. begin
  665. gintfgetvtbllabelname:=mangledname_prefix('VTBL',_class.owner)+_class.objname^+
  666. '_$_'+_class.implementedinterfaces.interfaces(intfindex).objname^;
  667. end;
  668. procedure tclassheader.gintfcreatevtbl(intfindex: integer; rawdata,rawcode: TAAsmoutput);
  669. var
  670. implintf: timplementedinterfaces;
  671. curintf: tobjectdef;
  672. proccount: integer;
  673. tmps: string;
  674. i: longint;
  675. begin
  676. implintf:=_class.implementedinterfaces;
  677. curintf:=implintf.interfaces(intfindex);
  678. if (cs_create_smart in aktmoduleswitches) then
  679. rawdata.concat(Tai_symbol.Createname_global(gintfgetvtbllabelname(intfindex),0))
  680. else
  681. rawdata.concat(Tai_symbol.Createname(gintfgetvtbllabelname(intfindex),0));
  682. proccount:=implintf.implproccount(intfindex);
  683. for i:=1 to proccount do
  684. begin
  685. tmps:=implintf.implprocs(intfindex,i).mangledname+'_$_'+curintf.objname^;
  686. { create wrapper code }
  687. cgintfwrapper(rawcode,implintf.implprocs(intfindex,i),tmps,implintf.ioffsets(intfindex)^);
  688. { create reference }
  689. rawdata.concat(Tai_const_symbol.Createname(tmps));
  690. end;
  691. end;
  692. procedure tclassheader.gintfgenentry(intfindex, contintfindex: integer; rawdata: TAAsmoutput);
  693. var
  694. implintf: timplementedinterfaces;
  695. curintf: tobjectdef;
  696. tmplabel: tasmlabel;
  697. i: longint;
  698. begin
  699. implintf:=_class.implementedinterfaces;
  700. curintf:=implintf.interfaces(intfindex);
  701. { GUID }
  702. if curintf.objecttype in [odt_interfacecom] then
  703. begin
  704. { label for GUID }
  705. getdatalabel(tmplabel);
  706. rawdata.concat(Tai_label.Create(tmplabel));
  707. rawdata.concat(Tai_const.Create_32bit(curintf.iidguid.D1));
  708. rawdata.concat(Tai_const.Create_16bit(curintf.iidguid.D2));
  709. rawdata.concat(Tai_const.Create_16bit(curintf.iidguid.D3));
  710. for i:=Low(curintf.iidguid.D4) to High(curintf.iidguid.D4) do
  711. rawdata.concat(Tai_const.Create_8bit(curintf.iidguid.D4[i]));
  712. dataSegment.concat(Tai_const_symbol.Create(tmplabel));
  713. end
  714. else
  715. begin
  716. { nil for Corba interfaces }
  717. dataSegment.concat(Tai_const.Create_32bit(0)); { nil }
  718. end;
  719. { VTable }
  720. dataSegment.concat(Tai_const_symbol.Createname(gintfgetvtbllabelname(contintfindex)));
  721. { IOffset field }
  722. dataSegment.concat(Tai_const.Create_32bit(implintf.ioffsets(contintfindex)^));
  723. { IIDStr }
  724. getdatalabel(tmplabel);
  725. rawdata.concat(Tai_label.Create(tmplabel));
  726. rawdata.concat(Tai_const.Create_8bit(length(curintf.iidstr^)));
  727. if curintf.objecttype=odt_interfacecom then
  728. rawdata.concat(Tai_string.Create(upper(curintf.iidstr^)))
  729. else
  730. rawdata.concat(Tai_string.Create(curintf.iidstr^));
  731. dataSegment.concat(Tai_const_symbol.Create(tmplabel));
  732. end;
  733. procedure tclassheader.gintfoptimizevtbls(implvtbl : plongint);
  734. type
  735. tcompintfentry = record
  736. weight: longint;
  737. compintf: longint;
  738. end;
  739. { Max 1000 interface in the class header interfaces it's enough imho }
  740. tcompintfs = packed array[1..1000] of tcompintfentry;
  741. pcompintfs = ^tcompintfs;
  742. tequals = packed array[1..1000] of longint;
  743. pequals = ^tequals;
  744. var
  745. max: longint;
  746. equals: pequals;
  747. compats: pcompintfs;
  748. i: longint;
  749. j: longint;
  750. w: longint;
  751. cij: boolean;
  752. cji: boolean;
  753. begin
  754. max:=_class.implementedinterfaces.count;
  755. if max>High(tequals) then
  756. Internalerror(200006135);
  757. getmem(compats,sizeof(tcompintfentry)*max);
  758. getmem(equals,sizeof(longint)*max);
  759. fillchar(compats^,sizeof(tcompintfentry)*max,0);
  760. fillchar(equals^,sizeof(longint)*max,0);
  761. { ismergepossible is a containing relation
  762. meaning of ismergepossible(a,b,w) =
  763. if implementorfunction map of a is contained implementorfunction map of b
  764. imp(a,b) and imp(b,c) => imp(a,c) ; imp(a,b) and imp(b,a) => a == b
  765. }
  766. { the order is very important for correct allocation }
  767. for i:=1 to max do
  768. begin
  769. for j:=i+1 to max do
  770. begin
  771. cij:=_class.implementedinterfaces.isimplmergepossible(i,j,w);
  772. cji:=_class.implementedinterfaces.isimplmergepossible(j,i,w);
  773. if cij and cji then { i equal j }
  774. begin
  775. { get minimum index of equal }
  776. if equals^[j]=0 then
  777. equals^[j]:=i;
  778. end
  779. else if cij then
  780. begin
  781. { get minimum index of maximum weight }
  782. if compats^[i].weight<w then
  783. begin
  784. compats^[i].weight:=w;
  785. compats^[i].compintf:=j;
  786. end;
  787. end
  788. else if cji then
  789. begin
  790. { get minimum index of maximum weight }
  791. if (compats^[j].weight<w) then
  792. begin
  793. compats^[j].weight:=w;
  794. compats^[j].compintf:=i;
  795. end;
  796. end;
  797. end;
  798. end;
  799. for i:=1 to max do
  800. begin
  801. if compats^[i].compintf<>0 then
  802. implvtbl[i]:=compats^[i].compintf
  803. else if equals^[i]<>0 then
  804. implvtbl[i]:=equals^[i]
  805. else
  806. implvtbl[i]:=i;
  807. end;
  808. freemem(compats,sizeof(tcompintfentry)*max);
  809. freemem(equals,sizeof(longint)*max);
  810. end;
  811. procedure tclassheader.gintfwritedata;
  812. var
  813. rawdata,rawcode: taasmoutput;
  814. impintfindexes: plongint;
  815. max: longint;
  816. i: longint;
  817. begin
  818. max:=_class.implementedinterfaces.count;
  819. getmem(impintfindexes,(max+1)*sizeof(longint));
  820. gintfoptimizevtbls(impintfindexes);
  821. rawdata:=TAAsmOutput.Create;
  822. rawcode:=TAAsmOutput.Create;
  823. dataSegment.concat(Tai_const.Create_16bit(max));
  824. { Two pass, one for allocation and vtbl creation }
  825. for i:=1 to max do
  826. begin
  827. if impintfindexes[i]=i then { if implement itself }
  828. begin
  829. { allocate a pointer in the object memory }
  830. with tstoredsymtable(_class.symtable) do
  831. begin
  832. if (dataalignment>=pointer_size) then
  833. datasize:=align(datasize,dataalignment)
  834. else
  835. datasize:=align(datasize,pointer_size);
  836. _class.implementedinterfaces.ioffsets(i)^:=datasize;
  837. datasize:=datasize+pointer_size;
  838. end;
  839. { write vtbl }
  840. gintfcreatevtbl(i,rawdata,rawcode);
  841. end;
  842. end;
  843. { second pass: for fill interfacetable and remained ioffsets }
  844. for i:=1 to max do
  845. begin
  846. if i<>impintfindexes[i] then { why execute x:=x ? }
  847. with _class.implementedinterfaces do
  848. ioffsets(i)^:=ioffsets(impintfindexes[i])^;
  849. gintfgenentry(i,impintfindexes[i],rawdata);
  850. end;
  851. dataSegment.concatlist(rawdata);
  852. rawdata.free;
  853. codeSegment.concatlist(rawcode);
  854. rawcode.free;
  855. freemem(impintfindexes,(max+1)*sizeof(longint));
  856. end;
  857. function tclassheader.gintfgetcprocdef(proc: tprocdef;const name: string): tprocdef;
  858. var
  859. sym: tprocsym;
  860. implprocdef : pprocdeflist;
  861. begin
  862. gintfgetcprocdef:=nil;
  863. sym:=tprocsym(search_class_member(_class,name));
  864. if assigned(sym) and (sym.typ=procsym) then
  865. begin
  866. implprocdef:=sym.defs;
  867. while assigned(implprocdef) do
  868. begin
  869. if equal_paras(proc.para,implprocdef^.def.para,cp_none) and
  870. (proc.proccalloption=implprocdef^.def.proccalloption) then
  871. begin
  872. gintfgetcprocdef:=implprocdef^.def;
  873. exit;
  874. end;
  875. implprocdef:=implprocdef^.next;
  876. end;
  877. end;
  878. end;
  879. procedure tclassheader.gintfdoonintf(intf: tobjectdef; intfindex: longint);
  880. var
  881. i: longint;
  882. proc: tprocdef;
  883. procname: string; { for error }
  884. mappedname: string;
  885. nextexist: pointer;
  886. implprocdef: tprocdef;
  887. begin
  888. for i:=1 to intf.symtable.defindex.count do
  889. begin
  890. proc:=tprocdef(intf.symtable.defindex.search(i));
  891. if proc.deftype=procdef then
  892. begin
  893. procname:='';
  894. implprocdef:=nil;
  895. nextexist:=nil;
  896. repeat
  897. mappedname:=_class.implementedinterfaces.getmappings(intfindex,proc.procsym.name,nextexist);
  898. if procname='' then
  899. procname:=proc.procsym.name;
  900. //mappedname; { for error messages }
  901. if mappedname<>'' then
  902. implprocdef:=gintfgetcprocdef(proc,mappedname);
  903. until assigned(implprocdef) or not assigned(nextexist);
  904. if not assigned(implprocdef) then
  905. implprocdef:=gintfgetcprocdef(proc,proc.procsym.name);
  906. if procname='' then
  907. procname:=proc.procsym.name;
  908. if assigned(implprocdef) then
  909. _class.implementedinterfaces.addimplproc(intfindex,implprocdef)
  910. else
  911. Message1(sym_e_id_not_found,procname);
  912. end;
  913. end;
  914. end;
  915. procedure tclassheader.gintfwalkdowninterface(intf: tobjectdef; intfindex: longint);
  916. begin
  917. if assigned(intf.childof) then
  918. gintfwalkdowninterface(intf.childof,intfindex);
  919. gintfdoonintf(intf,intfindex);
  920. end;
  921. function tclassheader.genintftable: tasmlabel;
  922. var
  923. intfindex: longint;
  924. curintf: tobjectdef;
  925. intftable: tasmlabel;
  926. begin
  927. { 1. step collect implementor functions into the implementedinterfaces.implprocs }
  928. for intfindex:=1 to _class.implementedinterfaces.count do
  929. begin
  930. curintf:=_class.implementedinterfaces.interfaces(intfindex);
  931. gintfwalkdowninterface(curintf,intfindex);
  932. end;
  933. { 2. step calc required fieldcount and their offsets in the object memory map
  934. and write data }
  935. getdatalabel(intftable);
  936. dataSegment.concat(Tai_label.Create(intftable));
  937. gintfwritedata;
  938. _class.implementedinterfaces.clearimplprocs; { release temporary information }
  939. genintftable:=intftable;
  940. end;
  941. { Write interface identifiers to the data section }
  942. procedure tclassheader.writeinterfaceids;
  943. var
  944. i: longint;
  945. begin
  946. if _class.isiidguidvalid then
  947. begin
  948. if (cs_create_smart in aktmoduleswitches) then
  949. dataSegment.concat(Tai_cut.Create);
  950. dataSegment.concat(Tai_symbol.Createname_global(mangledname_prefix('IID',_class.owner)+_class.objname^,0));
  951. dataSegment.concat(Tai_const.Create_32bit(longint(_class.iidguid.D1)));
  952. dataSegment.concat(Tai_const.Create_16bit(_class.iidguid.D2));
  953. dataSegment.concat(Tai_const.Create_16bit(_class.iidguid.D3));
  954. for i:=Low(_class.iidguid.D4) to High(_class.iidguid.D4) do
  955. dataSegment.concat(Tai_const.Create_8bit(_class.iidguid.D4[i]));
  956. end;
  957. if (cs_create_smart in aktmoduleswitches) then
  958. dataSegment.concat(Tai_cut.Create);
  959. dataSegment.concat(Tai_symbol.Createname_global(mangledname_prefix('IIDSTR',_class.owner)+_class.objname^,0));
  960. dataSegment.concat(Tai_const.Create_8bit(length(_class.iidstr^)));
  961. dataSegment.concat(Tai_string.Create(_class.iidstr^));
  962. end;
  963. procedure tclassheader.writevirtualmethods(List:TAAsmoutput);
  964. var
  965. symcoll : psymcoll;
  966. procdefcoll : pprocdefcoll;
  967. i : longint;
  968. begin
  969. { walk trough all numbers for virtual methods and search }
  970. { the method }
  971. for i:=0 to nextvirtnumber-1 do
  972. begin
  973. symcoll:=wurzel;
  974. { walk trough all symbols }
  975. while assigned(symcoll) do
  976. begin
  977. { walk trough all methods }
  978. procdefcoll:=symcoll^.data;
  979. while assigned(procdefcoll) do
  980. begin
  981. { writes the addresses to the VMT }
  982. { but only this which are declared as virtual }
  983. if procdefcoll^.data.extnumber=i then
  984. begin
  985. if (po_virtualmethod in procdefcoll^.data.procoptions) then
  986. begin
  987. { if a method is abstract, then is also the }
  988. { class abstract and it's not allow to }
  989. { generates an instance }
  990. if (po_abstractmethod in procdefcoll^.data.procoptions) then
  991. begin
  992. include(_class.objectoptions,oo_has_abstract);
  993. List.concat(Tai_const_symbol.Createname('FPC_ABSTRACTERROR'));
  994. end
  995. else
  996. begin
  997. List.concat(Tai_const_symbol.createname(procdefcoll^.data.mangledname));
  998. end;
  999. end;
  1000. end;
  1001. procdefcoll:=procdefcoll^.next;
  1002. end;
  1003. symcoll:=symcoll^.next;
  1004. end;
  1005. end;
  1006. end;
  1007. { generates the vmt for classes as well as for objects }
  1008. procedure tclassheader.writevmt;
  1009. var
  1010. methodnametable,intmessagetable,
  1011. strmessagetable,classnamelabel,
  1012. fieldtablelabel : tasmlabel;
  1013. {$ifdef WITHDMT}
  1014. dmtlabel : tasmlabel;
  1015. {$endif WITHDMT}
  1016. interfacetable : tasmlabel;
  1017. begin
  1018. {$ifdef WITHDMT}
  1019. dmtlabel:=gendmt;
  1020. {$endif WITHDMT}
  1021. if (cs_create_smart in aktmoduleswitches) then
  1022. dataSegment.concat(Tai_cut.Create);
  1023. { write tables for classes, this must be done before the actual
  1024. class is written, because we need the labels defined }
  1025. if is_class(_class) then
  1026. begin
  1027. { interface table }
  1028. if _class.implementedinterfaces.count>0 then
  1029. begin
  1030. if (cs_create_smart in aktmoduleswitches) then
  1031. codeSegment.concat(Tai_cut.Create);
  1032. interfacetable:=genintftable;
  1033. end;
  1034. methodnametable:=genpublishedmethodstable;
  1035. fieldtablelabel:=_class.generate_field_table;
  1036. { write class name }
  1037. getdatalabel(classnamelabel);
  1038. dataSegment.concat(Tai_label.Create(classnamelabel));
  1039. dataSegment.concat(Tai_const.Create_8bit(length(_class.objrealname^)));
  1040. dataSegment.concat(Tai_string.Create(_class.objrealname^));
  1041. { generate message and dynamic tables }
  1042. if (oo_has_msgstr in _class.objectoptions) then
  1043. strmessagetable:=genstrmsgtab;
  1044. if (oo_has_msgint in _class.objectoptions) then
  1045. intmessagetable:=genintmsgtab
  1046. else
  1047. dataSegment.concat(Tai_const.Create_32bit(0));
  1048. end;
  1049. { write debug info }
  1050. {$ifdef GDB}
  1051. if (cs_debuginfo in aktmoduleswitches) then
  1052. begin
  1053. do_count_dbx:=true;
  1054. if assigned(_class.owner) and assigned(_class.owner.name) then
  1055. dataSegment.concat(Tai_stabs.Create(strpnew('"vmt_'+_class.owner.name^+_class.name+':S'+
  1056. typeglobalnumber('__vtbl_ptr_type')+'",'+tostr(N_STSYM)+',0,0,'+_class.vmt_mangledname)));
  1057. end;
  1058. {$endif GDB}
  1059. dataSegment.concat(Tai_symbol.Createdataname_global(_class.vmt_mangledname,0));
  1060. { determine the size with symtable.datasize, because }
  1061. { size gives back 4 for classes }
  1062. dataSegment.concat(Tai_const.Create_32bit(_class.symtable.datasize));
  1063. dataSegment.concat(Tai_const.Create_32bit(-_class.symtable.datasize));
  1064. {$ifdef WITHDMT}
  1065. if _class.classtype=ct_object then
  1066. begin
  1067. if assigned(dmtlabel) then
  1068. dataSegment.concat(Tai_const_symbol.Create(dmtlabel)))
  1069. else
  1070. dataSegment.concat(Tai_const.Create_32bit(0));
  1071. end;
  1072. {$endif WITHDMT}
  1073. { write pointer to parent VMT, this isn't implemented in TP }
  1074. { but this is not used in FPC ? (PM) }
  1075. { it's not used yet, but the delphi-operators as and is need it (FK) }
  1076. { it is not written for parents that don't have any vmt !! }
  1077. if assigned(_class.childof) and
  1078. (oo_has_vmt in _class.childof.objectoptions) then
  1079. dataSegment.concat(Tai_const_symbol.Createname(_class.childof.vmt_mangledname))
  1080. else
  1081. dataSegment.concat(Tai_const.Create_32bit(0));
  1082. { write extended info for classes, for the order see rtl/inc/objpash.inc }
  1083. if is_class(_class) then
  1084. begin
  1085. { pointer to class name string }
  1086. dataSegment.concat(Tai_const_symbol.Create(classnamelabel));
  1087. { pointer to dynamic table }
  1088. if (oo_has_msgint in _class.objectoptions) then
  1089. dataSegment.concat(Tai_const_symbol.Create(intmessagetable))
  1090. else
  1091. dataSegment.concat(Tai_const.Create_32bit(0));
  1092. { pointer to method table }
  1093. if assigned(methodnametable) then
  1094. dataSegment.concat(Tai_const_symbol.Create(methodnametable))
  1095. else
  1096. dataSegment.concat(Tai_const.Create_32bit(0));
  1097. { pointer to field table }
  1098. dataSegment.concat(Tai_const_symbol.Create(fieldtablelabel));
  1099. { pointer to type info of published section }
  1100. if (oo_can_have_published in _class.objectoptions) then
  1101. dataSegment.concat(Tai_const_symbol.Create(_class.get_rtti_label(fullrtti)))
  1102. else
  1103. dataSegment.concat(Tai_const.Create_32bit(0));
  1104. { inittable for con-/destruction, for classes this is always generated }
  1105. dataSegment.concat(Tai_const_symbol.Create(_class.get_rtti_label(initrtti)));
  1106. { auto table }
  1107. dataSegment.concat(Tai_const.Create_32bit(0));
  1108. { interface table }
  1109. if _class.implementedinterfaces.count>0 then
  1110. dataSegment.concat(Tai_const_symbol.Create(interfacetable))
  1111. else
  1112. dataSegment.concat(Tai_const.Create_32bit(0));
  1113. { table for string messages }
  1114. if (oo_has_msgstr in _class.objectoptions) then
  1115. dataSegment.concat(Tai_const_symbol.Create(strmessagetable))
  1116. else
  1117. dataSegment.concat(Tai_const.Create_32bit(0));
  1118. end;
  1119. { write virtual methods }
  1120. writevirtualmethods(dataSegment);
  1121. { write the size of the VMT }
  1122. dataSegment.concat(Tai_symbol_end.Createname(_class.vmt_mangledname));
  1123. end;
  1124. initialization
  1125. cclassheader:=tclassheader;
  1126. end.
  1127. {
  1128. $Log$
  1129. Revision 1.16 2002-04-20 21:32:24 carl
  1130. + generic FPC_CHECKPOINTER
  1131. + first parameter offset in stack now portable
  1132. * rename some constants
  1133. + move some cpu stuff to other units
  1134. - remove unused constents
  1135. * fix stacksize for some targets
  1136. * fix generic size problems which depend now on EXTEND_SIZE constant
  1137. Revision 1.15 2002/04/19 15:46:01 peter
  1138. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  1139. in most cases and not written to the ppu
  1140. * add mangeledname_prefix() routine to generate the prefix of
  1141. manglednames depending on the current procedure, object and module
  1142. * removed static procprefix since the mangledname is now build only
  1143. on demand from tprocdef.mangledname
  1144. Revision 1.14 2002/04/15 18:59:07 carl
  1145. + target_info.size_of_pointer -> pointer_Size
  1146. Revision 1.13 2002/02/11 18:51:35 peter
  1147. * fixed vmt generation for private procedures that were skipped after
  1148. my previous changes
  1149. Revision 1.12 2001/12/31 16:59:41 peter
  1150. * protected/private symbols parsing fixed
  1151. Revision 1.11 2001/11/20 18:49:43 peter
  1152. * require overload for cross object overloading
  1153. Revision 1.10 2001/11/18 20:18:54 peter
  1154. * use cp_value_equal_const instead of cp_all
  1155. Revision 1.9 2001/11/18 18:43:14 peter
  1156. * overloading supported in child classes
  1157. * fixed parsing of classes with private and virtual and overloaded
  1158. so it is compatible with delphi
  1159. Revision 1.8 2001/11/02 22:58:02 peter
  1160. * procsym definition rewrite
  1161. Revision 1.7 2001/10/25 21:22:35 peter
  1162. * calling convention rewrite
  1163. Revision 1.6 2001/10/20 19:28:38 peter
  1164. * interface 2 guid support
  1165. * guid constants support
  1166. Revision 1.5 2001/10/20 17:20:14 peter
  1167. * fixed generation of rtti for virtualmethods
  1168. Revision 1.4 2001/09/19 11:04:42 michael
  1169. * Smartlinking with interfaces fixed
  1170. * Better smartlinking for rtti and init tables
  1171. Revision 1.3 2001/08/30 20:13:53 peter
  1172. * rtti/init table updates
  1173. * rttisym for reusable global rtti/init info
  1174. * support published for interfaces
  1175. Revision 1.2 2001/08/22 21:16:20 florian
  1176. * some interfaces related problems regarding
  1177. mapping of interface implementions fixed
  1178. Revision 1.1 2001/04/21 13:37:16 peter
  1179. * made tclassheader using class of to implement cpu dependent code
  1180. Revision 1.20 2001/04/18 22:01:54 peter
  1181. * registration of targets and assemblers
  1182. Revision 1.19 2001/04/13 01:22:07 peter
  1183. * symtable change to classes
  1184. * range check generation and errors fixed, make cycle DEBUG=1 works
  1185. * memory leaks fixed
  1186. Revision 1.18 2001/04/04 21:30:43 florian
  1187. * applied several fixes to get the DD8 Delphi Unit compiled
  1188. e.g. "forward"-interfaces are working now
  1189. Revision 1.17 2000/12/25 00:07:26 peter
  1190. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1191. tlinkedlist objects)
  1192. Revision 1.16 2000/11/29 00:30:30 florian
  1193. * unused units removed from uses clause
  1194. * some changes for widestrings
  1195. Revision 1.15 2000/11/19 16:23:35 florian
  1196. *** empty log message ***
  1197. Revision 1.14 2000/11/12 23:24:10 florian
  1198. * interfaces are basically running
  1199. Revision 1.13 2000/11/08 00:07:40 florian
  1200. * potential range check error fixed
  1201. Revision 1.12 2000/11/06 23:13:53 peter
  1202. * uppercase manglednames
  1203. Revision 1.11 2000/11/04 17:31:00 florian
  1204. * fixed some problems of previous commit
  1205. Revision 1.10 2000/11/04 14:25:19 florian
  1206. + merged Attila's changes for interfaces, not tested yet
  1207. Revision 1.9 2000/11/01 23:04:37 peter
  1208. * tprocdef.fullprocname added for better casesensitve writing of
  1209. procedures
  1210. Revision 1.8 2000/10/31 22:02:47 peter
  1211. * symtable splitted, no real code changes
  1212. Revision 1.7 2000/10/14 10:14:47 peter
  1213. * moehrendorf oct 2000 rewrite
  1214. Revision 1.6 2000/09/24 21:19:50 peter
  1215. * delphi compile fixes
  1216. Revision 1.5 2000/09/24 15:06:17 peter
  1217. * use defines.inc
  1218. Revision 1.4 2000/08/27 16:11:51 peter
  1219. * moved some util functions from globals,cobjects to cutils
  1220. * splitted files into finput,fmodule
  1221. Revision 1.3 2000/07/13 12:08:26 michael
  1222. + patched to 1.1.0 with former 1.09patch from peter
  1223. Revision 1.2 2000/07/13 11:32:41 michael
  1224. + removed logs
  1225. }