types.pas 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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. objects,cobjects,globals,symtable,tree,aasm;
  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. { returns true, if def defines a signed data type (only for ordinal types) }
  30. function is_signed(def : pdef) : boolean;
  31. { returns true, if def uses FPU }
  32. function is_fpu(def : pdef) : boolean;
  33. { true if the return value is in EAX }
  34. function ret_in_acc(def : pdef) : boolean;
  35. { true if uses a parameter as return value }
  36. function ret_in_param(def : pdef) : boolean;
  37. { true if a const parameter is too large to copy }
  38. function dont_copy_const_param(def : pdef) : boolean;
  39. { true if we must never copy this parameter }
  40. const
  41. never_copy_const_param : boolean = false;
  42. { true, if def1 and def2 are semantical the same }
  43. function is_equal(def1,def2 : pdef) : boolean;
  44. { checks for type compatibility (subgroups of type) }
  45. { used for case statements... probably missing stuff }
  46. { to use on other types }
  47. function is_subequal(def1, def2: pdef): boolean;
  48. { true, if two parameter lists are equal }
  49. function equal_paras(def1,def2 : pdefcoll) : boolean;
  50. { gibt den ordinalen Werten der Node zurueck oder falls sie }
  51. { keinen ordinalen Wert hat, wird ein Fehler erzeugt }
  52. function get_ordinal_value(p : ptree) : longint;
  53. { if l isn't in the range of def a range check error is generated }
  54. procedure testrange(def : pdef;l : longint);
  55. { returns the range of def }
  56. procedure getrange(def : pdef;var l : longint;var h : longint);
  57. { generates a VMT for _class }
  58. procedure genvmt(_class : pobjectdef);
  59. { true, if p is a pointer to a const int value }
  60. function is_constintnode(p : ptree) : boolean;
  61. { like is_constintnode }
  62. function is_constboolnode(p : ptree) : boolean;
  63. function is_constrealnode(p : ptree) : boolean;
  64. function is_constcharnode(p : ptree) : boolean;
  65. { some type helper routines for MMX support }
  66. function is_mmx_able_array(p : pdef) : boolean;
  67. { returns the mmx type }
  68. function mmx_type(p : pdef) : tmmxtype;
  69. implementation
  70. uses verbose;
  71. function is_constintnode(p : ptree) : boolean;
  72. begin
  73. {DM: According to me, an orddef with anysize, is
  74. a correct constintnode. Anyway I commented changed s32bit check,
  75. because it caused problems with statements like a:=high(word).}
  76. is_constintnode:=((p^.treetype=ordconstn) and
  77. (p^.resulttype^.deftype=orddef) and
  78. (porddef(p^.resulttype)^.typ in [u8bit,s8bit,u16bit,s16bit,
  79. u32bit,s32bit,uauto]));
  80. end;
  81. function is_constcharnode(p : ptree) : boolean;
  82. begin
  83. is_constcharnode:=((p^.treetype=ordconstn) and
  84. (p^.resulttype^.deftype=orddef) and
  85. (porddef(p^.resulttype)^.typ=uchar));
  86. end;
  87. function is_constrealnode(p : ptree) : boolean;
  88. begin
  89. is_constrealnode:=(p^.treetype=realconstn);
  90. end;
  91. function is_constboolnode(p : ptree) : boolean;
  92. begin
  93. is_constboolnode:=((p^.treetype=ordconstn) and
  94. (p^.resulttype^.deftype=orddef) and
  95. (porddef(p^.resulttype)^.typ=bool8bit));
  96. end;
  97. function equal_paras(def1,def2 : pdefcoll) : boolean;
  98. begin
  99. while (assigned(def1)) and (assigned(def2)) do
  100. begin
  101. if not(is_equal(def1^.data,def2^.data)) or
  102. (def1^.paratyp<>def2^.paratyp) then
  103. begin
  104. equal_paras:=false;
  105. exit;
  106. end;
  107. def1:=def1^.next;
  108. def2:=def2^.next;
  109. end;
  110. if (def1=nil) and (def2=nil) then
  111. equal_paras:=true
  112. else
  113. equal_paras:=false;
  114. end;
  115. { returns true, if def uses FPU }
  116. function is_fpu(def : pdef) : boolean;
  117. begin
  118. is_fpu:=(def^.deftype=floatdef) and (pfloatdef(def)^.typ<>f32bit);
  119. end;
  120. function is_ordinal(def : pdef) : boolean;
  121. var
  122. dt : tbasetype;
  123. begin
  124. case def^.deftype of
  125. orddef : begin
  126. dt:=porddef(def)^.typ;
  127. is_ordinal:=(dt=s32bit) or (dt=u32bit) or (dt=uchar) or (dt=u8bit) or
  128. (dt=s8bit) or (dt=s16bit) or (dt=bool8bit) or (dt=u16bit);
  129. end;
  130. enumdef : is_ordinal:=true;
  131. else is_ordinal:=false;
  132. end;
  133. end;
  134. function is_signed(def : pdef) : boolean;
  135. var
  136. dt : tbasetype;
  137. begin
  138. case def^.deftype of
  139. orddef : begin
  140. dt:=porddef(def)^.typ;
  141. is_signed:=(dt=s32bit) or (dt=s8bit) or (dt=s16bit);
  142. end;
  143. enumdef : is_signed:=false;
  144. else internalerror(1001);
  145. end;
  146. end;
  147. { true, if p points to an open array def }
  148. function is_open_array(p : pdef) : boolean;
  149. begin
  150. is_open_array:=(p^.deftype=arraydef) and
  151. (parraydef(p)^.lowrange=0) and
  152. (parraydef(p)^.highrange=-1);
  153. end;
  154. { true if the return value is in accumulator (EAX for i386), D0 for 68k }
  155. function ret_in_acc(def : pdef) : boolean;
  156. begin
  157. ret_in_acc:=(def^.deftype=orddef) or
  158. (def^.deftype=pointerdef) or
  159. (def^.deftype=enumdef) or
  160. (def^.deftype=procvardef) or
  161. (def^.deftype=classrefdef) or
  162. ((def^.deftype=objectdef) and
  163. ((pobjectdef(def)^.options and oois_class)<>0)
  164. ) or
  165. ((def^.deftype=setdef) and
  166. (psetdef(def)^.settype=smallset)) or
  167. ((def^.deftype=floatdef) and
  168. (pfloatdef(def)^.typ=f32bit));
  169. end;
  170. { true if uses a parameter as return value }
  171. function ret_in_param(def : pdef) : boolean;
  172. begin
  173. ret_in_param:=(def^.deftype=arraydef) or
  174. (def^.deftype=stringdef) or
  175. ((def^.deftype=objectdef) and
  176. ((pobjectdef(def)^.options and oois_class)=0)
  177. ) or
  178. (def^.deftype=recorddef) or
  179. ((def^.deftype=setdef) and
  180. (psetdef(def)^.settype<>smallset));
  181. end;
  182. { true if a const parameter is too large to copy }
  183. function dont_copy_const_param(def : pdef) : boolean;
  184. begin
  185. dont_copy_const_param:=(def^.deftype=arraydef) or
  186. (def^.deftype=stringdef) or
  187. (def^.deftype=objectdef) or
  188. (def^.deftype=formaldef) or
  189. (def^.deftype=recorddef) or
  190. (def^.deftype=formaldef) or
  191. ((def^.deftype=setdef) and
  192. (psetdef(def)^.settype<>smallset));
  193. end;
  194. procedure testrange(def : pdef;l : longint);
  195. var
  196. lv,hv: longint;
  197. begin
  198. getrange(def,lv,hv);
  199. if (def^.deftype=orddef) and
  200. (porddef(def)^.typ=u32bit) then
  201. begin
  202. if lv<=hv then
  203. begin
  204. if (l<lv) or (l>hv) then
  205. Message(parser_e_range_check_error);
  206. end
  207. else
  208. { this happens with the wrap around problem }
  209. { if lv is positive and hv is over $7ffffff }
  210. { so it seems negative }
  211. begin
  212. if ((l>=0) and (l<lv)) or
  213. ((l<0) and (l>hv)) then
  214. Message(parser_e_range_check_error);
  215. end;
  216. end
  217. else if (l<lv) or (l>hv) then
  218. Message(parser_e_range_check_error);
  219. end;
  220. procedure getrange(def : pdef;var l : longint;var h : longint);
  221. begin
  222. if def^.deftype=orddef then
  223. case porddef(def)^.typ of
  224. s32bit,s16bit,u16bit,s8bit,u8bit :
  225. begin
  226. l:=porddef(def)^.von;
  227. h:=porddef(def)^.bis;
  228. end;
  229. bool8bit : begin
  230. l:=0;
  231. h:=1;
  232. end;
  233. uchar : begin
  234. l:=0;
  235. h:=255;
  236. end;
  237. u32bit : begin
  238. { this should work now }
  239. l:=porddef(def)^.von;
  240. h:=porddef(def)^.bis;
  241. end;
  242. end
  243. else
  244. if def^.deftype=enumdef then
  245. begin
  246. l:=0;
  247. h:=penumdef(def)^.max;
  248. end;
  249. end;
  250. function get_ordinal_value(p : ptree) : longint;
  251. begin
  252. if p^.treetype=ordconstn then
  253. get_ordinal_value:=p^.value
  254. else
  255. Message(parser_e_ordinal_expected);
  256. end;
  257. function mmx_type(p : pdef) : tmmxtype;
  258. begin
  259. mmx_type:=mmxno;
  260. if is_mmx_able_array(p) then
  261. begin
  262. if parraydef(p)^.definition^.deftype=floatdef then
  263. case pfloatdef(parraydef(p)^.definition)^.typ of
  264. s32real:
  265. mmx_type:=mmxsingle;
  266. f16bit:
  267. mmx_type:=mmxfixed16
  268. end
  269. else
  270. case porddef(parraydef(p)^.definition)^.typ of
  271. u8bit:
  272. mmx_type:=mmxu8bit;
  273. s8bit:
  274. mmx_type:=mmxs8bit;
  275. u16bit:
  276. mmx_type:=mmxu16bit;
  277. s16bit:
  278. mmx_type:=mmxs16bit;
  279. u32bit:
  280. mmx_type:=mmxu32bit;
  281. s32bit:
  282. mmx_type:=mmxs32bit;
  283. end;
  284. end;
  285. end;
  286. function is_mmx_able_array(p : pdef) : boolean;
  287. begin
  288. {$ifdef SUPPORT_MMX}
  289. if (cs_mmx_saturation in aktswitches) then
  290. begin
  291. is_mmx_able_array:=(p^.deftype=arraydef) and
  292. (
  293. ((parraydef(p)^.definition^.deftype=orddef) and
  294. (
  295. (parraydef(p)^.lowrange=0) and
  296. (parraydef(p)^.highrange=1) and
  297. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  298. ) or
  299. (
  300. (parraydef(p)^.lowrange=0) and
  301. (parraydef(p)^.highrange=3) and
  302. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  303. )
  304. )
  305. ) or
  306. (
  307. ((parraydef(p)^.definition^.deftype=floatdef) and
  308. (
  309. (parraydef(p)^.lowrange=0) and
  310. (parraydef(p)^.highrange=3) and
  311. (pfloatdef(parraydef(p)^.definition)^.typ=f16bit)
  312. ) or
  313. (
  314. (parraydef(p)^.lowrange=0) and
  315. (parraydef(p)^.highrange=1) and
  316. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  317. )
  318. )
  319. );
  320. end
  321. else
  322. begin
  323. is_mmx_able_array:=(p^.deftype=arraydef) and
  324. (
  325. ((parraydef(p)^.definition^.deftype=orddef) and
  326. (
  327. (parraydef(p)^.lowrange=0) and
  328. (parraydef(p)^.highrange=1) and
  329. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  330. ) or
  331. (
  332. (parraydef(p)^.lowrange=0) and
  333. (parraydef(p)^.highrange=3) and
  334. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  335. ) or
  336. (
  337. (parraydef(p)^.lowrange=0) and
  338. (parraydef(p)^.highrange=7) and
  339. (porddef(parraydef(p)^.definition)^.typ in [u8bit,s8bit])
  340. )
  341. )
  342. ) or
  343. (
  344. ((parraydef(p)^.definition^.deftype=floatdef) and
  345. (
  346. (parraydef(p)^.lowrange=0) and
  347. (parraydef(p)^.highrange=3) and
  348. (pfloatdef(parraydef(p)^.definition)^.typ=f32bit)
  349. )
  350. or
  351. (
  352. (parraydef(p)^.lowrange=0) and
  353. (parraydef(p)^.highrange=1) and
  354. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  355. )
  356. )
  357. );
  358. end;
  359. {$else SUPPORT_MMX}
  360. is_mmx_able_array:=false;
  361. {$endif SUPPORT_MMX}
  362. end;
  363. function is_equal(def1,def2 : pdef) : boolean;
  364. var
  365. b : boolean;
  366. hd : pdef;
  367. hp1,hp2 : pdefcoll;
  368. begin
  369. { be sure, that if there is a stringdef, that this is def1 }
  370. if def2^.deftype=stringdef then
  371. begin
  372. hd:=def1;
  373. def1:=def2;
  374. def2:=hd;
  375. end;
  376. b:=false;
  377. { wenn beide auf die gleiche Definition zeigen sind sie wohl gleich...}
  378. if def1=def2 then
  379. b:=true
  380. else
  381. { pointer with an equal definition are equal }
  382. if (def1^.deftype=pointerdef) and (def2^.deftype=pointerdef) then
  383. { here a problem detected in tabsolutesym }
  384. { the types can be forward type !! }
  385. begin
  386. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  387. b:=(def1^.sym=def2^.sym)
  388. else
  389. b:=is_equal(ppointerdef(def1)^.definition,ppointerdef(def2)^.definition);
  390. end
  391. else
  392. { Grundtypen sind gleich, wenn sie den selben Grundtyp haben, }
  393. { und wenn noetig den selben Unterbereich haben }
  394. if (def1^.deftype=orddef) and (def2^.deftype=orddef) then
  395. begin
  396. case porddef(def1)^.typ of
  397. u32bit,u8bit,s32bit,s8bit,u16bit,s16bit : begin
  398. if porddef(def1)^.typ=porddef(def2)^.typ then
  399. if (porddef(def1)^.von=porddef(def2)^.von) and
  400. (porddef(def1)^.bis=porddef(def2)^.bis) then
  401. b:=true;
  402. end;
  403. uvoid,bool8bit,uchar :
  404. b:=porddef(def1)^.typ=porddef(def2)^.typ;
  405. end;
  406. end
  407. else
  408. if (def1^.deftype=floatdef) and (def2^.deftype=floatdef) then
  409. b:=pfloatdef(def1)^.typ=pfloatdef(def2)^.typ
  410. else
  411. { strings with the same length are equal }
  412. if (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  413. (pstringdef(def1)^.len=pstringdef(def2)^.len) then
  414. b:=true
  415. { STRING[N] ist equivalent zu ARRAY[0..N] OF CHAR (N<256) }
  416. {
  417. else if ((def1^.deftype=stringdef) and (def2^.deftype=arraydef)) and
  418. (parraydef(def2)^.definition^.deftype=orddef) and
  419. (porddef(parraydef(def1)^.definition)^.typ=uchar) and
  420. (parraydef(def2)^.lowrange=0) and
  421. (parraydef(def2)^.highrange=pstringdef(def1)^.len) then
  422. b:=true }
  423. else
  424. if (def1^.deftype=formaldef) and (def2^.deftype=formaldef) then
  425. b:=true
  426. { file types with the same file element type are equal }
  427. { this is a problem for assign !! }
  428. { changed to allow if one is untyped }
  429. { all typed files are equal to the special }
  430. { typed file that has voiddef as elemnt type }
  431. { but must NOT match for text file !!! }
  432. else
  433. if (def1^.deftype=filedef) and (def2^.deftype=filedef) then
  434. b:=(pfiledef(def1)^.filetype=pfiledef(def2)^.filetype) and
  435. ((
  436. ((pfiledef(def1)^.typed_as=nil) and
  437. (pfiledef(def2)^.typed_as=nil)) or
  438. (
  439. (pfiledef(def1)^.typed_as<>nil) and
  440. (pfiledef(def2)^.typed_as<>nil) and
  441. is_equal(pfiledef(def1)^.typed_as,pfiledef(def2)^.typed_as)
  442. ) or
  443. ( (pfiledef(def1)^.typed_as=pdef(voiddef)) or
  444. (pfiledef(def2)^.typed_as=pdef(voiddef))
  445. )))
  446. { sets with the same element type are equal }
  447. else
  448. if (def1^.deftype=setdef) and (def2^.deftype=setdef) then
  449. begin
  450. if assigned(psetdef(def1)^.setof) and
  451. assigned(psetdef(def2)^.setof) then
  452. b:=is_equal(psetdef(def1)^.setof,psetdef(def2)^.setof)
  453. else b:=true;
  454. end
  455. else
  456. if (def1^.deftype=procvardef) and (def2^.deftype=procvardef) then
  457. begin
  458. { poassembler isn't important for compatibility }
  459. b:=((pprocvardef(def1)^.options and not(poassembler))=
  460. (pprocvardef(def2)^.options and not(poassembler))
  461. ) and
  462. is_equal(pprocvardef(def1)^.retdef,pprocvardef(def2)^.retdef);
  463. { now evalute the parameters }
  464. if b then
  465. begin
  466. hp1:=pprocvardef(def1)^.para1;
  467. hp2:=pprocvardef(def1)^.para1;
  468. while assigned(hp1) and assigned(hp2) do
  469. begin
  470. if not(is_equal(hp1^.data,hp2^.data)) or
  471. not(hp1^.paratyp=hp2^.paratyp) then
  472. begin
  473. b:=false;
  474. break;
  475. end;
  476. hp1:=hp1^.next;
  477. hp2:=hp2^.next;
  478. end;
  479. b:=(hp1=nil) and (hp2=nil);
  480. end;
  481. end
  482. else
  483. if (def1^.deftype=arraydef) and (def2^.deftype=arraydef) and
  484. (is_open_array(def1) or is_open_array(def2)) then
  485. begin
  486. b:=is_equal(parraydef(def1)^.definition,parraydef(def2)^.definition);
  487. end
  488. else
  489. if (def1^.deftype=classrefdef) and (def2^.deftype=classrefdef) then
  490. begin
  491. { similar to pointerdef: }
  492. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  493. b:=(def1^.sym=def2^.sym)
  494. else
  495. b:=is_equal(pclassrefdef(def1)^.definition,pclassrefdef(def2)^.definition);
  496. end;
  497. is_equal:=b;
  498. end;
  499. function is_subequal(def1, def2: pdef): boolean;
  500. Begin
  501. if assigned(def1) and assigned(def2) then
  502. Begin
  503. is_subequal := FALSE;
  504. if (def1^.deftype = orddef) and (def2^.deftype = orddef) then
  505. Begin
  506. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  507. { range checking for case statements is done with testrange }
  508. case porddef(def1)^.typ of
  509. s32bit,u32bit,u8bit,s8bit,s16bit,u16bit:
  510. Begin
  511. { PROBABLE CODE GENERATION BUG HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! }
  512. { if porddef(def2)^.typ in [s32bit,u32bit,u8bit,s8bit,s16bit,u16bit] then
  513. is_subequal := TRUE; }
  514. if (porddef(def2)^.typ = s32bit) or
  515. (porddef(def2)^.typ = u32bit) or
  516. (porddef(def2)^.typ = u8bit) or
  517. (porddef(def2)^.typ = s8bit) or
  518. (porddef(def2)^.typ = s16bit) or
  519. (porddef(def2)^.typ = u16bit) then
  520. Begin
  521. is_subequal:=TRUE;
  522. end;
  523. end;
  524. bool8bit: if porddef(def2)^.typ = bool8bit then is_subequal := TRUE;
  525. uchar: if porddef(def2)^.typ = uchar then is_subequal := TRUE;
  526. end;
  527. end
  528. else
  529. Begin
  530. { I assume that both enumerations are equal when the first }
  531. { pointers are equal. }
  532. if (def1^.deftype = enumdef) and (def2^.deftype =enumdef) then
  533. Begin
  534. if penumdef(def1)^.first = penumdef(def2)^.first then
  535. is_subequal := TRUE;
  536. end;
  537. end;
  538. end; { endif assigned ... }
  539. end;
  540. type
  541. pprocdefcoll = ^tprocdefcoll;
  542. tprocdefcoll = record
  543. next : pprocdefcoll;
  544. data : pprocdef;
  545. end;
  546. psymcoll = ^tsymcoll;
  547. tsymcoll = record
  548. next : psymcoll;
  549. name : pstring;
  550. data : pprocdefcoll;
  551. end;
  552. var
  553. wurzel : psymcoll;
  554. nextvirtnumber : longint;
  555. _c : pobjectdef;
  556. has_constructor,has_virtual_method : boolean;
  557. procedure eachsym(sym : psym);{$ifndef FPC}far;{$endif}
  558. var
  559. procdefcoll : pprocdefcoll;
  560. hp : pprocdef;
  561. symcoll : psymcoll;
  562. _name : string;
  563. stored : boolean;
  564. begin
  565. { nur Unterprogrammsymbole werden in die VMT aufgenommen }
  566. if sym^.typ=procsym then
  567. begin
  568. _name:=sym^.name;
  569. symcoll:=wurzel;
  570. while assigned(symcoll) do
  571. begin
  572. { wenn das Symbol in der Liste schon existiert }
  573. if _name=symcoll^.name^ then
  574. begin
  575. { walk thorugh all defs of the symbol }
  576. hp:=pprocsym(sym)^.definition;
  577. while assigned(hp) do
  578. begin
  579. { compare with all stored definitions }
  580. procdefcoll:=symcoll^.data;
  581. stored:=false;
  582. while assigned(procdefcoll) do
  583. begin
  584. { compare parameters }
  585. if equal_paras(procdefcoll^.data^.para1,hp^.para1) and
  586. (
  587. ((procdefcoll^.data^.options and povirtualmethod)<>0) or
  588. ((hp^.options and povirtualmethod)<>0)
  589. ) then
  590. begin
  591. { wenn sie gleich sind }
  592. { und eine davon virtual deklariert ist }
  593. { Fehler falls nur eine VIRTUAL }
  594. if (procdefcoll^.data^.options and povirtualmethod)<>
  595. (hp^.options and povirtualmethod) then
  596. Message1(parser_e_overloaded_are_not_both_virtual,_c^.name^+'.'+_name);
  597. { check, if the overridden directive is set }
  598. { (povirtualmethod is set! }
  599. { class ? }
  600. if ((_c^.options and oois_class)<>0) and
  601. ((hp^.options and pooverridingmethod)=0) then
  602. Message1(parser_e_must_use_override,_c^.name^+'.'+_name);
  603. { error, if the return types aren't equal }
  604. if not(is_equal(procdefcoll^.data^.retdef,hp^.retdef)) then
  605. Message1(parser_e_overloaded_methodes_not_same_ret,_c^.name^+'.'+_name);
  606. { the flags have to match }
  607. { except abstract and override }
  608. if (procdefcoll^.data^.options and not(poabstractmethod or pooverridingmethod))<>
  609. (hp^.options and not(poabstractmethod or pooverridingmethod)) then
  610. Message1(parser_e_header_dont_match_forward,_c^.name^+'.'+_name);
  611. { now set the number }
  612. hp^.extnumber:=procdefcoll^.data^.extnumber;
  613. { and exchange }
  614. procdefcoll^.data:=hp;
  615. stored:=true;
  616. end;
  617. procdefcoll:=procdefcoll^.next;
  618. end;
  619. { if it isn't saved in the list }
  620. { we create a new entry }
  621. if not(stored) then
  622. begin
  623. new(procdefcoll);
  624. procdefcoll^.data:=hp;
  625. procdefcoll^.next:=symcoll^.data;
  626. symcoll^.data:=procdefcoll;
  627. { if the method is virtual ... }
  628. if (hp^.options and povirtualmethod)<>0 then
  629. begin
  630. { ... it will get a number }
  631. hp^.extnumber:=nextvirtnumber;
  632. inc(nextvirtnumber);
  633. end;
  634. { check, if a method should be overridden }
  635. if (hp^.options and pooverridingmethod)<>0 then
  636. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  637. end;
  638. hp:=hp^.nextoverloaded;
  639. end;
  640. exit;
  641. end;
  642. symcoll:=symcoll^.next;
  643. end;
  644. { if not, generate a new symbol item }
  645. new(symcoll);
  646. symcoll^.name:=stringdup(sym^.name);
  647. symcoll^.next:=wurzel;
  648. symcoll^.data:=nil;
  649. wurzel:=symcoll;
  650. hp:=pprocsym(sym)^.definition;
  651. { inserts all definitions }
  652. while assigned(hp) do
  653. begin
  654. new(procdefcoll);
  655. procdefcoll^.data:=hp;
  656. procdefcoll^.next:=symcoll^.data;
  657. symcoll^.data:=procdefcoll;
  658. { if it's a virtual method }
  659. if (hp^.options and povirtualmethod)<>0 then
  660. begin
  661. { then it gets a number ... }
  662. hp^.extnumber:=nextvirtnumber;
  663. { and we inc the number }
  664. inc(nextvirtnumber);
  665. has_virtual_method:=true;
  666. end;
  667. if (hp^.options and poconstructor)<>0 then
  668. has_constructor:=true;
  669. { check, if a method should be overridden }
  670. if (hp^.options and pooverridingmethod)<>0 then
  671. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  672. { next overloaded method }
  673. hp:=hp^.nextoverloaded;
  674. end;
  675. end;
  676. end;
  677. procedure genvmt(_class : pobjectdef);
  678. procedure do_genvmt(p : pobjectdef);
  679. begin
  680. { start with the base class }
  681. if assigned(p^.childof) then
  682. do_genvmt(p^.childof);
  683. { walk through all public syms }
  684. _c:=_class;
  685. {$ifdef tp}
  686. p^.publicsyms^.foreach(eachsym);
  687. {$else}
  688. p^.publicsyms^.foreach(@eachsym);
  689. {$endif}
  690. end;
  691. var
  692. symcoll : psymcoll;
  693. procdefcoll : pprocdefcoll;
  694. i : longint;
  695. begin
  696. wurzel:=nil;
  697. nextvirtnumber:=0;
  698. has_constructor:=false;
  699. has_virtual_method:=false;
  700. { generates a tree of all used methods }
  701. do_genvmt(_class);
  702. if has_virtual_method and not(has_constructor) then
  703. begin
  704. exterror:=strpnew(_class^.name^);
  705. Message(parser_w_virtual_without_constructor);
  706. end;
  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. datasegment^.concat(new(pai_const,init_symbol(
  736. strpnew(procdefcoll^.data^.mangledname))));
  737. end;
  738. end;
  739. procdefcoll:=procdefcoll^.next;
  740. end;
  741. symcoll:=symcoll^.next;
  742. end;
  743. end;
  744. { disposes the above generated tree }
  745. symcoll:=wurzel;
  746. while assigned(symcoll) do
  747. begin
  748. wurzel:=symcoll^.next;
  749. stringdispose(symcoll^.name);
  750. procdefcoll:=symcoll^.data;
  751. while assigned(procdefcoll) do
  752. begin
  753. symcoll^.data:=procdefcoll^.next;
  754. dispose(procdefcoll);
  755. procdefcoll:=symcoll^.data;
  756. end;
  757. dispose(symcoll);
  758. symcoll:=wurzel;
  759. end;
  760. end;
  761. end.
  762. {
  763. $Log$
  764. Revision 1.1 1998-03-25 11:18:15 root
  765. Initial revision
  766. Revision 1.24 1998/03/21 23:59:40 florian
  767. * indexed properties fixed
  768. * ppu i/o of properties fixed
  769. * field can be also used for write access
  770. * overriding of properties
  771. Revision 1.23 1998/03/20 23:31:35 florian
  772. * bug0113 fixed
  773. * problem with interdepened units fixed ("options.pas problem")
  774. * two small extensions for future AMD 3D support
  775. Revision 1.22 1998/03/10 01:17:30 peter
  776. * all files have the same header
  777. * messages are fully implemented, EXTDEBUG uses Comment()
  778. + AG... files for the Assembler generation
  779. Revision 1.21 1998/03/06 01:09:01 peter
  780. * removed the conflicts that had occured
  781. Revision 1.20 1998/03/06 00:53:01 peter
  782. * replaced all old messages from errore.msg, only ExtDebug and some
  783. Comment() calls are left
  784. * fixed options.pas
  785. Revision 1.19 1998/03/05 22:40:56 florian
  786. + warning about missing constructor added
  787. Revision 1.18 1998/03/04 17:34:14 michael
  788. + Changed ifdef FPK to ifdef FPC
  789. Revision 1.17 1998/03/02 01:49:38 peter
  790. * renamed target_DOS to target_GO32V1
  791. + new verbose system, merged old errors and verbose units into one new
  792. verbose.pas, so errors.pas is obsolete
  793. Revision 1.16 1998/02/13 10:35:55 daniel
  794. * Made Motorola version compilable.
  795. * Fixed optimizer
  796. Revision 1.15 1998/02/12 17:19:33 florian
  797. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  798. also that aktswitches isn't a pointer)
  799. Revision 1.14 1998/02/12 11:50:52 daniel
  800. Yes! Finally! After three retries, my patch!
  801. Changes:
  802. Complete rewrite of psub.pas.
  803. Added support for DLL's.
  804. Compiler requires less memory.
  805. Platform units for each platform.
  806. Revision 1.13 1998/02/11 21:56:41 florian
  807. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  808. Revision 1.12 1998/02/07 23:05:08 florian
  809. * once more MMX
  810. Revision 1.11 1998/02/06 10:34:35 florian
  811. * bug0082 and bug0084 fixed
  812. Revision 1.10 1998/02/05 22:27:07 florian
  813. * small problems fixed: remake3 should now work
  814. Revision 1.9 1998/02/05 21:54:36 florian
  815. + more MMX
  816. Revision 1.8 1998/01/31 00:43:37 carl
  817. - removed in in is_subequal, because the code generator is buggy!
  818. (instead uses if...)
  819. Revision 1.7 1998/01/16 18:03:21 florian
  820. * small bug fixes, some stuff of delphi styled constructores added
  821. Revision 1.6 1998/01/11 19:24:35 carl
  822. + type checking routine (is_subequal) for case statements
  823. Revision 1.5 1998/01/09 23:08:38 florian
  824. + C++/Delphi styled //-comments
  825. * some bugs in Delphi object model fixed
  826. + override directive
  827. Revision 1.4 1998/01/09 16:08:24 florian
  828. * abstract methods call now abstracterrorproc if they are called
  829. a class with an abstract method can be create with a class reference else
  830. the compiler forbides this
  831. Revision 1.3 1998/01/07 00:17:12 michael
  832. Restored released version (plus fixes) as current
  833. Revision 1.2 1997/11/28 18:14:51 pierre
  834. working version with several bug fixes
  835. Revision 1.1.1.1 1997/11/27 08:33:03 michael
  836. FPC Compiler CVS start
  837. Pre-CVS log:
  838. CEC Carl-Eric Codere
  839. FK Florian Klaempfl
  840. PM Pierre Muller
  841. + feature added
  842. - removed
  843. * bug fixed or changed
  844. History:
  845. 22th september 1997
  846. + function dont_copy_const_param added (FK)
  847. 25th september 1997
  848. + is_open_array added (FK)
  849. + is_equal handles now also open arrays (FK)
  850. 2nd october 1997
  851. + added then boolean never_copy_const_param for use in typed write
  852. where we must push the reference anyway (PM)
  853. 3rd october 1997:
  854. + renamed ret_in_eax to ret_in_acc (for accumulator for port.) (CEC)
  855. - removed reference to i386 unit (CEC)
  856. 25th october 1997:
  857. * poassembler isn't important for compatiblity of proc vars (FK)
  858. 3rd november 1997:
  859. + added formaldef type to types where we dont_copy_const_param (PM)
  860. 20rd november 1997:
  861. + added is_fpu function (PM)
  862. }