types.pas 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. {
  2. $Id$
  3. Copyright (C) 1993-98 by Florian Klaempfl
  4. This unit provides some help routines for type handling
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit types;
  19. interface
  20. uses
  21. cobjects,globals,symtable;
  22. type
  23. tmmxtype = (mmxno,mmxu8bit,mmxs8bit,mmxu16bit,mmxs16bit,
  24. mmxu32bit,mmxs32bit,mmxfixed16,mmxsingle);
  25. { returns true, if def defines an ordinal type }
  26. function is_ordinal(def : pdef) : boolean;
  27. { true if p points to an open array def }
  28. function is_open_array(p : pdef) : boolean;
  29. { true if o is an ansi string def }
  30. function is_ansistring(p : pdef) : boolean;
  31. { true if o is a long string def }
  32. function is_longstring(p : pdef) : boolean;
  33. { true if o is a wide string def }
  34. function is_widestring(p : pdef) : boolean;
  35. { true if o is a short string def }
  36. function is_shortstring(p : pdef) : boolean;
  37. { returns true, if def defines a signed data type (only for ordinal types) }
  38. function is_signed(def : pdef) : boolean;
  39. { returns true, if def uses FPU }
  40. function is_fpu(def : pdef) : boolean;
  41. { true if the return value is in EAX }
  42. function ret_in_acc(def : pdef) : boolean;
  43. { true if uses a parameter as return value }
  44. function ret_in_param(def : pdef) : boolean;
  45. { true if a const parameter is too large to copy }
  46. function dont_copy_const_param(def : pdef) : boolean;
  47. { true if we must never copy this parameter }
  48. const
  49. never_copy_const_param : boolean = false;
  50. { true, if def1 and def2 are semantical the same }
  51. function is_equal(def1,def2 : pdef) : boolean;
  52. { checks for type compatibility (subgroups of type) }
  53. { used for case statements... probably missing stuff }
  54. { to use on other types }
  55. function is_subequal(def1, def2: pdef): boolean;
  56. { true, if two parameter lists are equal }
  57. { if value_equal_const is true, call by value }
  58. { and call by const parameter are assumed as }
  59. { equal }
  60. function equal_paras(def1,def2 : pdefcoll;value_equal_const : boolean) : boolean;
  61. { if l isn't in the range of def a range check error is generated }
  62. procedure testrange(def : pdef;l : longint);
  63. { returns the range of def }
  64. procedure getrange(def : pdef;var l : longint;var h : longint);
  65. { generates a VMT for _class }
  66. procedure genvmt(_class : pobjectdef);
  67. { some type helper routines for MMX support }
  68. function is_mmx_able_array(p : pdef) : boolean;
  69. { returns the mmx type }
  70. function mmx_type(p : pdef) : tmmxtype;
  71. implementation
  72. uses verbose,aasm;
  73. function equal_paras(def1,def2 : pdefcoll;value_equal_const : boolean) : boolean;
  74. begin
  75. while (assigned(def1)) and (assigned(def2)) do
  76. begin
  77. if value_equal_const then
  78. begin
  79. if not(is_equal(def1^.data,def2^.data)) or
  80. ((def1^.paratyp<>def2^.paratyp) and
  81. ((def1^.paratyp=vs_var) or
  82. (def1^.paratyp=vs_var)
  83. )
  84. ) then
  85. begin
  86. equal_paras:=false;
  87. exit;
  88. end;
  89. end
  90. else
  91. begin
  92. if not(is_equal(def1^.data,def2^.data)) or
  93. (def1^.paratyp<>def2^.paratyp) then
  94. begin
  95. equal_paras:=false;
  96. exit;
  97. end;
  98. end;
  99. def1:=def1^.next;
  100. def2:=def2^.next;
  101. end;
  102. if (def1=nil) and (def2=nil) then
  103. equal_paras:=true
  104. else
  105. equal_paras:=false;
  106. end;
  107. { returns true, if def uses FPU }
  108. function is_fpu(def : pdef) : boolean;
  109. begin
  110. is_fpu:=(def^.deftype=floatdef) and (pfloatdef(def)^.typ<>f32bit);
  111. end;
  112. function is_ordinal(def : pdef) : boolean;
  113. var
  114. dt : tbasetype;
  115. begin
  116. case def^.deftype of
  117. orddef : begin
  118. dt:=porddef(def)^.typ;
  119. is_ordinal:=dt in [uchar,u8bit,u16bit,u32bit,s8bit,s16bit,s32bit,bool8bit,bool16bit,bool32bit];
  120. end;
  121. enumdef : is_ordinal:=true;
  122. else
  123. is_ordinal:=false;
  124. end;
  125. end;
  126. function is_signed(def : pdef) : boolean;
  127. var
  128. dt : tbasetype;
  129. begin
  130. case def^.deftype of
  131. orddef : begin
  132. dt:=porddef(def)^.typ;
  133. is_signed:=(dt in [s8bit,s16bit,s32bit]);
  134. end;
  135. enumdef : is_signed:=false;
  136. else
  137. is_signed:=false;
  138. end;
  139. end;
  140. { true, if p points to an open array def }
  141. function is_open_array(p : pdef) : boolean;
  142. begin
  143. is_open_array:=(p^.deftype=arraydef) and
  144. (parraydef(p)^.lowrange=0) and
  145. (parraydef(p)^.highrange=-1);
  146. end;
  147. { true if o is an ansi string def }
  148. function is_ansistring(p : pdef) : boolean;
  149. begin
  150. is_ansistring:=(p^.deftype=stringdef) and
  151. (pstringdef(p)^.string_typ=st_ansistring);
  152. end;
  153. { true if o is an long string def }
  154. function is_longstring(p : pdef) : boolean;
  155. begin
  156. is_longstring:=(p^.deftype=stringdef) and
  157. (pstringdef(p)^.string_typ=st_longstring);
  158. end;
  159. { true if o is an wide string def }
  160. function is_widestring(p : pdef) : boolean;
  161. begin
  162. is_widestring:=(p^.deftype=stringdef) and
  163. (pstringdef(p)^.string_typ=st_widestring);
  164. end;
  165. { true if o is an short string def }
  166. function is_shortstring(p : pdef) : boolean;
  167. begin
  168. is_shortstring:=(p^.deftype=stringdef) and
  169. (pstringdef(p)^.string_typ=st_shortstring);
  170. end;
  171. { true if the return value is in accumulator (EAX for i386), D0 for 68k }
  172. function ret_in_acc(def : pdef) : boolean;
  173. begin
  174. ret_in_acc:=(def^.deftype in [orddef,pointerdef,enumdef,classrefdef]) or
  175. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_ansistring,st_widestring])) or
  176. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)=0)) or
  177. ((def^.deftype=objectdef) and pobjectdef(def)^.isclass) or
  178. ((def^.deftype=setdef) and (psetdef(def)^.settype=smallset)) or
  179. ((def^.deftype=floatdef) and (pfloatdef(def)^.typ=f32bit));
  180. end;
  181. { true if uses a parameter as return value }
  182. function ret_in_param(def : pdef) : boolean;
  183. begin
  184. ret_in_param:=(def^.deftype in [arraydef,recorddef]) or
  185. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
  186. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)<>0)) or
  187. ((def^.deftype=objectdef) and ((pobjectdef(def)^.options and oois_class)=0)) or
  188. ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
  189. end;
  190. { true if a const parameter is too large to copy }
  191. function dont_copy_const_param(def : pdef) : boolean;
  192. begin
  193. dont_copy_const_param:=(def^.deftype in [arraydef,objectdef,formaldef,recorddef]) or
  194. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
  195. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)<>0)) or
  196. ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
  197. end;
  198. procedure testrange(def : pdef;l : longint);
  199. var
  200. lv,hv: longint;
  201. begin
  202. getrange(def,lv,hv);
  203. if (def^.deftype=orddef) and
  204. (porddef(def)^.typ=u32bit) then
  205. begin
  206. if lv<=hv then
  207. begin
  208. if (l<lv) or (l>hv) then
  209. Message(parser_e_range_check_error);
  210. end
  211. else
  212. { this happens with the wrap around problem }
  213. { if lv is positive and hv is over $7ffffff }
  214. { so it seems negative }
  215. begin
  216. if ((l>=0) and (l<lv)) or
  217. ((l<0) and (l>hv)) then
  218. Message(parser_e_range_check_error);
  219. end;
  220. end
  221. else if (l<lv) or (l>hv) then
  222. Message(parser_e_range_check_error);
  223. end;
  224. procedure getrange(def : pdef;var l : longint;var h : longint);
  225. begin
  226. case def^.deftype of
  227. orddef : begin
  228. l:=porddef(def)^.low;
  229. h:=porddef(def)^.high;
  230. end;
  231. enumdef : begin
  232. l:=0;
  233. h:=penumdef(def)^.max;
  234. end;
  235. end;
  236. end;
  237. function mmx_type(p : pdef) : tmmxtype;
  238. begin
  239. mmx_type:=mmxno;
  240. if is_mmx_able_array(p) then
  241. begin
  242. if parraydef(p)^.definition^.deftype=floatdef then
  243. case pfloatdef(parraydef(p)^.definition)^.typ of
  244. s32real:
  245. mmx_type:=mmxsingle;
  246. f16bit:
  247. mmx_type:=mmxfixed16
  248. end
  249. else
  250. case porddef(parraydef(p)^.definition)^.typ of
  251. u8bit:
  252. mmx_type:=mmxu8bit;
  253. s8bit:
  254. mmx_type:=mmxs8bit;
  255. u16bit:
  256. mmx_type:=mmxu16bit;
  257. s16bit:
  258. mmx_type:=mmxs16bit;
  259. u32bit:
  260. mmx_type:=mmxu32bit;
  261. s32bit:
  262. mmx_type:=mmxs32bit;
  263. end;
  264. end;
  265. end;
  266. function is_mmx_able_array(p : pdef) : boolean;
  267. begin
  268. {$ifdef SUPPORT_MMX}
  269. if (cs_mmx_saturation in aktlocalswitches) then
  270. begin
  271. is_mmx_able_array:=(p^.deftype=arraydef) and
  272. (
  273. ((parraydef(p)^.definition^.deftype=orddef) and
  274. (
  275. (parraydef(p)^.lowrange=0) and
  276. (parraydef(p)^.highrange=1) and
  277. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  278. ) or
  279. (
  280. (parraydef(p)^.lowrange=0) and
  281. (parraydef(p)^.highrange=3) and
  282. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  283. )
  284. )
  285. ) or
  286. (
  287. ((parraydef(p)^.definition^.deftype=floatdef) and
  288. (
  289. (parraydef(p)^.lowrange=0) and
  290. (parraydef(p)^.highrange=3) and
  291. (pfloatdef(parraydef(p)^.definition)^.typ=f16bit)
  292. ) or
  293. (
  294. (parraydef(p)^.lowrange=0) and
  295. (parraydef(p)^.highrange=1) and
  296. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  297. )
  298. )
  299. );
  300. end
  301. else
  302. begin
  303. is_mmx_able_array:=(p^.deftype=arraydef) and
  304. (
  305. ((parraydef(p)^.definition^.deftype=orddef) and
  306. (
  307. (parraydef(p)^.lowrange=0) and
  308. (parraydef(p)^.highrange=1) and
  309. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  310. ) or
  311. (
  312. (parraydef(p)^.lowrange=0) and
  313. (parraydef(p)^.highrange=3) and
  314. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  315. ) or
  316. (
  317. (parraydef(p)^.lowrange=0) and
  318. (parraydef(p)^.highrange=7) and
  319. (porddef(parraydef(p)^.definition)^.typ in [u8bit,s8bit])
  320. )
  321. )
  322. ) or
  323. (
  324. ((parraydef(p)^.definition^.deftype=floatdef) and
  325. (
  326. (parraydef(p)^.lowrange=0) and
  327. (parraydef(p)^.highrange=3) and
  328. (pfloatdef(parraydef(p)^.definition)^.typ=f32bit)
  329. )
  330. or
  331. (
  332. (parraydef(p)^.lowrange=0) and
  333. (parraydef(p)^.highrange=1) and
  334. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  335. )
  336. )
  337. );
  338. end;
  339. {$else SUPPORT_MMX}
  340. is_mmx_able_array:=false;
  341. {$endif SUPPORT_MMX}
  342. end;
  343. function is_equal(def1,def2 : pdef) : boolean;
  344. var
  345. b : boolean;
  346. hd : pdef;
  347. hp1,hp2 : pdefcoll;
  348. begin
  349. { both types must exists }
  350. if not (assigned(def1) and assigned(def2)) then
  351. begin
  352. is_equal:=false;
  353. exit;
  354. end;
  355. { be sure, that if there is a stringdef, that this is def1 }
  356. if def2^.deftype=stringdef then
  357. begin
  358. hd:=def1;
  359. def1:=def2;
  360. def2:=hd;
  361. end;
  362. b:=false;
  363. { wenn beide auf die gleiche Definition zeigen sind sie wohl gleich...}
  364. if def1=def2 then
  365. b:=true
  366. else
  367. { pointer with an equal definition are equal }
  368. if (def1^.deftype=pointerdef) and (def2^.deftype=pointerdef) then
  369. { here a problem detected in tabsolutesym }
  370. { the types can be forward type !! }
  371. begin
  372. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  373. b:=(def1^.sym=def2^.sym)
  374. else
  375. b:=is_equal(ppointerdef(def1)^.definition,ppointerdef(def2)^.definition);
  376. end
  377. else
  378. { ordinals are equal only when the ordinal type is equal }
  379. if (def1^.deftype=orddef) and (def2^.deftype=orddef) then
  380. begin
  381. case porddef(def1)^.typ of
  382. u8bit,u16bit,u32bit,
  383. s8bit,s16bit,s32bit:
  384. b:=((porddef(def1)^.typ=porddef(def2)^.typ) and
  385. (porddef(def1)^.low=porddef(def2)^.low) and
  386. (porddef(def1)^.high=porddef(def2)^.high));
  387. uvoid,uchar,
  388. bool8bit,bool16bit,bool32bit:
  389. b:=(porddef(def1)^.typ=porddef(def2)^.typ);
  390. end;
  391. end
  392. else
  393. if (def1^.deftype=floatdef) and (def2^.deftype=floatdef) then
  394. b:=pfloatdef(def1)^.typ=pfloatdef(def2)^.typ
  395. else
  396. { strings with the same length are equal }
  397. if (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  398. (pstringdef(def1)^.string_typ=pstringdef(def2)^.string_typ) then
  399. begin
  400. b:=not(is_shortstring(def1)) or
  401. (pstringdef(def1)^.len=pstringdef(def2)^.len);
  402. end
  403. { STRING[N] ist equivalent zu ARRAY[0..N] OF CHAR (N<256) }
  404. {
  405. else if ((def1^.deftype=stringdef) and (def2^.deftype=arraydef)) and
  406. (parraydef(def2)^.definition^.deftype=orddef) and
  407. (porddef(parraydef(def1)^.definition)^.typ=uchar) and
  408. (parraydef(def2)^.lowrange=0) and
  409. (parraydef(def2)^.highrange=pstringdef(def1)^.len) then
  410. b:=true }
  411. else
  412. if (def1^.deftype=formaldef) and (def2^.deftype=formaldef) then
  413. b:=true
  414. { file types with the same file element type are equal }
  415. { this is a problem for assign !! }
  416. { changed to allow if one is untyped }
  417. { all typed files are equal to the special }
  418. { typed file that has voiddef as elemnt type }
  419. { but must NOT match for text file !!! }
  420. else
  421. if (def1^.deftype=filedef) and (def2^.deftype=filedef) then
  422. b:=(pfiledef(def1)^.filetype=pfiledef(def2)^.filetype) and
  423. ((
  424. ((pfiledef(def1)^.typed_as=nil) and
  425. (pfiledef(def2)^.typed_as=nil)) or
  426. (
  427. (pfiledef(def1)^.typed_as<>nil) and
  428. (pfiledef(def2)^.typed_as<>nil) and
  429. is_equal(pfiledef(def1)^.typed_as,pfiledef(def2)^.typed_as)
  430. ) or
  431. ( (pfiledef(def1)^.typed_as=pdef(voiddef)) or
  432. (pfiledef(def2)^.typed_as=pdef(voiddef))
  433. )))
  434. { sets with the same element type are equal }
  435. else
  436. if (def1^.deftype=setdef) and (def2^.deftype=setdef) then
  437. begin
  438. if assigned(psetdef(def1)^.setof) and
  439. assigned(psetdef(def2)^.setof) then
  440. b:=(psetdef(def1)^.setof^.deftype=psetdef(def2)^.setof^.deftype)
  441. else
  442. b:=true;
  443. end
  444. else
  445. if (def1^.deftype=procvardef) and (def2^.deftype=procvardef) then
  446. begin
  447. { poassembler isn't important for compatibility }
  448. b:=((pprocvardef(def1)^.options and not(poassembler))=
  449. (pprocvardef(def2)^.options and not(poassembler))
  450. ) and
  451. is_equal(pprocvardef(def1)^.retdef,pprocvardef(def2)^.retdef);
  452. { now evalute the parameters }
  453. if b then
  454. begin
  455. hp1:=pprocvardef(def1)^.para1;
  456. hp2:=pprocvardef(def1)^.para1;
  457. while assigned(hp1) and assigned(hp2) do
  458. begin
  459. if not(is_equal(hp1^.data,hp2^.data)) or
  460. not(hp1^.paratyp=hp2^.paratyp) then
  461. begin
  462. b:=false;
  463. break;
  464. end;
  465. hp1:=hp1^.next;
  466. hp2:=hp2^.next;
  467. end;
  468. b:=(hp1=nil) and (hp2=nil);
  469. end;
  470. end
  471. else
  472. if (def1^.deftype=arraydef) and (def2^.deftype=arraydef) and
  473. (is_open_array(def1) or is_open_array(def2)) then
  474. begin
  475. b:=is_equal(parraydef(def1)^.definition,parraydef(def2)^.definition);
  476. end
  477. else
  478. if (def1^.deftype=classrefdef) and (def2^.deftype=classrefdef) then
  479. begin
  480. { similar to pointerdef: }
  481. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  482. b:=(def1^.sym=def2^.sym)
  483. else
  484. b:=is_equal(pclassrefdef(def1)^.definition,pclassrefdef(def2)^.definition);
  485. end;
  486. is_equal:=b;
  487. end;
  488. function is_subequal(def1, def2: pdef): boolean;
  489. Begin
  490. if assigned(def1) and assigned(def2) then
  491. Begin
  492. is_subequal := FALSE;
  493. if (def1^.deftype = orddef) and (def2^.deftype = orddef) then
  494. Begin
  495. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  496. { range checking for case statements is done with testrange }
  497. case porddef(def1)^.typ of
  498. u8bit,u16bit,u32bit,
  499. s8bit,s16bit,s32bit : is_subequal:=(porddef(def2)^.typ in [s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  500. bool8bit,bool16bit,bool32bit : is_subequal:=(porddef(def2)^.typ in [bool8bit,bool16bit,bool32bit]);
  501. uchar : is_subequal:=(porddef(def2)^.typ=uchar);
  502. end;
  503. end
  504. else
  505. Begin
  506. { I assume that both enumerations are equal when the first }
  507. { pointers are equal. }
  508. if (def1^.deftype = enumdef) and (def2^.deftype =enumdef) then
  509. Begin
  510. if penumdef(def1)^.first = penumdef(def2)^.first then
  511. is_subequal := TRUE;
  512. end;
  513. end;
  514. end; { endif assigned ... }
  515. end;
  516. type
  517. pprocdefcoll = ^tprocdefcoll;
  518. tprocdefcoll = record
  519. next : pprocdefcoll;
  520. data : pprocdef;
  521. end;
  522. psymcoll = ^tsymcoll;
  523. tsymcoll = record
  524. next : psymcoll;
  525. name : pstring;
  526. data : pprocdefcoll;
  527. end;
  528. var
  529. wurzel : psymcoll;
  530. nextvirtnumber : longint;
  531. _c : pobjectdef;
  532. has_constructor,has_virtual_method : boolean;
  533. procedure eachsym(sym : psym);{$ifndef FPC}far;{$endif}
  534. var
  535. procdefcoll : pprocdefcoll;
  536. hp : pprocdef;
  537. symcoll : psymcoll;
  538. _name : string;
  539. stored : boolean;
  540. { creates a new entry in the procsym list }
  541. procedure newentry;
  542. begin
  543. { if not, generate a new symbol item }
  544. new(symcoll);
  545. symcoll^.name:=stringdup(sym^.name);
  546. symcoll^.next:=wurzel;
  547. symcoll^.data:=nil;
  548. wurzel:=symcoll;
  549. hp:=pprocsym(sym)^.definition;
  550. { inserts all definitions }
  551. while assigned(hp) do
  552. begin
  553. new(procdefcoll);
  554. procdefcoll^.data:=hp;
  555. procdefcoll^.next:=symcoll^.data;
  556. symcoll^.data:=procdefcoll;
  557. { if it's a virtual method }
  558. if (hp^.options and povirtualmethod)<>0 then
  559. begin
  560. { then it gets a number ... }
  561. hp^.extnumber:=nextvirtnumber;
  562. { and we inc the number }
  563. inc(nextvirtnumber);
  564. has_virtual_method:=true;
  565. end;
  566. if (hp^.options and poconstructor)<>0 then
  567. has_constructor:=true;
  568. { check, if a method should be overridden }
  569. if (hp^.options and pooverridingmethod)<>0 then
  570. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  571. { next overloaded method }
  572. hp:=hp^.nextoverloaded;
  573. end;
  574. end;
  575. begin
  576. { put only sub routines into the VMT }
  577. if sym^.typ=procsym then
  578. begin
  579. _name:=sym^.name;
  580. symcoll:=wurzel;
  581. while assigned(symcoll) do
  582. begin
  583. { does the symbol already exist in the list ? }
  584. if _name=symcoll^.name^ then
  585. begin
  586. { walk through all defs of the symbol }
  587. hp:=pprocsym(sym)^.definition;
  588. while assigned(hp) do
  589. begin
  590. { compare with all stored definitions }
  591. procdefcoll:=symcoll^.data;
  592. stored:=false;
  593. while assigned(procdefcoll) do
  594. begin
  595. { compare parameters }
  596. if equal_paras(procdefcoll^.data^.para1,hp^.para1,false) and
  597. (
  598. ((procdefcoll^.data^.options and povirtualmethod)<>0) or
  599. ((hp^.options and povirtualmethod)<>0)
  600. ) then
  601. begin
  602. { wenn sie gleich sind }
  603. { und eine davon virtual deklariert ist }
  604. { Fehler falls nur eine VIRTUAL }
  605. if (procdefcoll^.data^.options and povirtualmethod)<>
  606. (hp^.options and povirtualmethod) then
  607. begin
  608. { in classes, we hide the old method }
  609. if _c^.isclass then
  610. begin
  611. { warn only if it is the first time,
  612. we hide the method }
  613. if _c=hp^._class then
  614. Message1(parser_w_should_use_override,_c^.name^+'.'+_name);
  615. newentry;
  616. exit;
  617. end
  618. else
  619. begin
  620. Message1(parser_e_overloaded_are_not_both_virtual,_c^.name^+'.'+_name);
  621. end;
  622. end;
  623. { check, if the overridden directive is set }
  624. { (povirtualmethod is set! }
  625. { class ? }
  626. if _c^.isclass and
  627. ((hp^.options and pooverridingmethod)=0) then
  628. begin
  629. { warn only if it is the first time,
  630. we hide the method }
  631. if _c=hp^._class then
  632. Message1(parser_w_should_use_override,_c^.name^+'.'+_name);
  633. newentry;
  634. exit;
  635. end;
  636. { error, if the return types aren't equal }
  637. if not(is_equal(procdefcoll^.data^.retdef,hp^.retdef)) then
  638. Message1(parser_e_overloaded_methodes_not_same_ret,_c^.name^+'.'+_name);
  639. { the flags have to match }
  640. { except abstract and override }
  641. if (procdefcoll^.data^.options and not(poabstractmethod or pooverridingmethod))<>
  642. (hp^.options and not(poabstractmethod or pooverridingmethod)) then
  643. Message1(parser_e_header_dont_match_forward,_c^.name^+'.'+_name);
  644. { now set the number }
  645. hp^.extnumber:=procdefcoll^.data^.extnumber;
  646. { and exchange }
  647. procdefcoll^.data:=hp;
  648. stored:=true;
  649. end;
  650. procdefcoll:=procdefcoll^.next;
  651. end;
  652. { if it isn't saved in the list }
  653. { we create a new entry }
  654. if not(stored) then
  655. begin
  656. new(procdefcoll);
  657. procdefcoll^.data:=hp;
  658. procdefcoll^.next:=symcoll^.data;
  659. symcoll^.data:=procdefcoll;
  660. { if the method is virtual ... }
  661. if (hp^.options and povirtualmethod)<>0 then
  662. begin
  663. { ... it will get a number }
  664. hp^.extnumber:=nextvirtnumber;
  665. inc(nextvirtnumber);
  666. end;
  667. { check, if a method should be overridden }
  668. if (hp^.options and pooverridingmethod)<>0 then
  669. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  670. end;
  671. hp:=hp^.nextoverloaded;
  672. end;
  673. exit;
  674. end;
  675. symcoll:=symcoll^.next;
  676. end;
  677. newentry;
  678. end;
  679. end;
  680. procedure genvmt(_class : pobjectdef);
  681. procedure do_genvmt(p : pobjectdef);
  682. begin
  683. { start with the base class }
  684. if assigned(p^.childof) then
  685. do_genvmt(p^.childof);
  686. { walk through all public syms }
  687. _c:=_class;
  688. {$ifdef tp}
  689. p^.publicsyms^.foreach(eachsym);
  690. {$else}
  691. p^.publicsyms^.foreach(@eachsym);
  692. {$endif}
  693. end;
  694. var
  695. symcoll : psymcoll;
  696. procdefcoll : pprocdefcoll;
  697. i : longint;
  698. begin
  699. wurzel:=nil;
  700. nextvirtnumber:=0;
  701. has_constructor:=false;
  702. has_virtual_method:=false;
  703. { generates a tree of all used methods }
  704. do_genvmt(_class);
  705. if has_virtual_method and not(has_constructor) then
  706. Message1(parser_w_virtual_without_constructor,_class^.name^);
  707. { generates the VMT }
  708. { walk trough all numbers for virtual methods and search }
  709. { the method }
  710. for i:=0 to nextvirtnumber-1 do
  711. begin
  712. symcoll:=wurzel;
  713. { walk trough all symbols }
  714. while assigned(symcoll) do
  715. begin
  716. { walk trough all methods }
  717. procdefcoll:=symcoll^.data;
  718. while assigned(procdefcoll) do
  719. begin
  720. { writes the addresses to the VMT }
  721. { but only this which are declared as virtual }
  722. if procdefcoll^.data^.extnumber=i then
  723. begin
  724. if (procdefcoll^.data^.options and povirtualmethod)<>0 then
  725. begin
  726. { if a method is abstract, then is also the }
  727. { class abstract and it's not allow to }
  728. { generates an instance }
  729. if (procdefcoll^.data^.options and poabstractmethod)<>0 then
  730. begin
  731. _class^.options:=_class^.options or oois_abstract;
  732. datasegment^.concat(new(pai_const,init_symbol('ABSTRACTERROR')));
  733. end
  734. else
  735. begin
  736. datasegment^.concat(new(pai_const,init_symbol(
  737. strpnew(procdefcoll^.data^.mangledname))));
  738. maybe_concat_external(procdefcoll^.data^.owner,
  739. procdefcoll^.data^.mangledname);
  740. end;
  741. end;
  742. end;
  743. procdefcoll:=procdefcoll^.next;
  744. end;
  745. symcoll:=symcoll^.next;
  746. end;
  747. end;
  748. { disposes the above generated tree }
  749. symcoll:=wurzel;
  750. while assigned(symcoll) do
  751. begin
  752. wurzel:=symcoll^.next;
  753. stringdispose(symcoll^.name);
  754. procdefcoll:=symcoll^.data;
  755. while assigned(procdefcoll) do
  756. begin
  757. symcoll^.data:=procdefcoll^.next;
  758. dispose(procdefcoll);
  759. procdefcoll:=symcoll^.data;
  760. end;
  761. dispose(symcoll);
  762. symcoll:=wurzel;
  763. end;
  764. end;
  765. end.
  766. {
  767. $Log$
  768. Revision 1.19 1998-08-18 09:24:48 pierre
  769. * small warning position bug fixed
  770. * support_mmx switches splitting was missing
  771. * rhide error and warning output corrected
  772. Revision 1.18 1998/08/14 18:18:49 peter
  773. + dynamic set contruction
  774. * smallsets are now working (always longint size)
  775. Revision 1.17 1998/08/05 16:00:17 florian
  776. * some fixes for ansi strings
  777. * $log$ to $Log$
  778. * $log$ to Revision 1.19 1998-08-18 09:24:48 pierre
  779. * $log$ to * small warning position bug fixed
  780. * $log$ to * support_mmx switches splitting was missing
  781. * $log$ to * rhide error and warning output corrected
  782. * $log$ to
  783. * $log$ to Revision 1.18 1998/08/14 18:18:49 peter
  784. * $log$ to + dynamic set contruction
  785. * $log$ to * smallsets are now working (always longint size)
  786. * $log$ to changed
  787. Revision 1.16 1998/07/20 23:35:50 michael
  788. Const ansistrings are not copied.
  789. Revision 1.15 1998/07/18 22:54:32 florian
  790. * some ansi/wide/longstring support fixed:
  791. o parameter passing
  792. o returning as result from functions
  793. Revision 1.14 1998/06/12 14:50:50 peter
  794. * removed the tree dependency to types.pas
  795. * long_fil.pas support (not fully tested yet)
  796. Revision 1.13 1998/06/03 22:49:07 peter
  797. + wordbool,longbool
  798. * rename bis,von -> high,low
  799. * moved some systemunit loading/creating to psystem.pas
  800. Revision 1.12 1998/05/12 10:47:00 peter
  801. * moved printstatus to verb_def
  802. + V_Normal which is between V_Error and V_Warning and doesn't have a
  803. prefix like error: warning: and is included in V_Default
  804. * fixed some messages
  805. * first time parameter scan is only for -v and -T
  806. - removed old style messages
  807. Revision 1.11 1998/05/01 16:38:46 florian
  808. * handling of private and protected fixed
  809. + change_keywords_to_tp implemented to remove
  810. keywords which aren't supported by tp
  811. * break and continue are now symbols of the system unit
  812. + widestring, longstring and ansistring type released
  813. Revision 1.10 1998/04/29 10:34:08 pierre
  814. + added some code for ansistring (not complete nor working yet)
  815. * corrected operator overloading
  816. * corrected nasm output
  817. + started inline procedures
  818. + added starstarn : use ** for exponentiation (^ gave problems)
  819. + started UseTokenInfo cond to get accurate positions
  820. Revision 1.9 1998/04/21 10:16:49 peter
  821. * patches from strasbourg
  822. * objects is not used anymore in the fpc compiled version
  823. Revision 1.8 1998/04/12 22:39:44 florian
  824. * problem with read access to properties solved
  825. * correct handling of hidding methods via virtual (COM)
  826. * correct result type of constructor calls (COM), the resulttype
  827. depends now on the type of the class reference
  828. Revision 1.7 1998/04/10 21:36:56 florian
  829. + some stuff to support method pointers (procedure of object) added
  830. (declaration, parameter handling)
  831. Revision 1.6 1998/04/10 15:39:49 florian
  832. * more fixes to get classes.pas compiled
  833. Revision 1.5 1998/04/09 23:02:16 florian
  834. * small problems solved to get remake3 work
  835. Revision 1.4 1998/04/08 16:58:09 pierre
  836. * several bugfixes
  837. ADD ADC and AND are also sign extended
  838. nasm output OK (program still crashes at end
  839. and creates wrong assembler files !!)
  840. procsym types sym in tdef removed !!
  841. Revision 1.3 1998/04/08 11:34:22 peter
  842. * nasm works (linux only tested)
  843. }