types.pas 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  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. { both types must exists }
  370. if not (assigned(def1) and assigned(def2)) then
  371. begin
  372. is_equal:=false;
  373. exit;
  374. end;
  375. { be sure, that if there is a stringdef, that this is def1 }
  376. if def2^.deftype=stringdef then
  377. begin
  378. hd:=def1;
  379. def1:=def2;
  380. def2:=hd;
  381. end;
  382. b:=false;
  383. { wenn beide auf die gleiche Definition zeigen sind sie wohl gleich...}
  384. if def1=def2 then
  385. b:=true
  386. else
  387. { pointer with an equal definition are equal }
  388. if (def1^.deftype=pointerdef) and (def2^.deftype=pointerdef) then
  389. { here a problem detected in tabsolutesym }
  390. { the types can be forward type !! }
  391. begin
  392. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  393. b:=(def1^.sym=def2^.sym)
  394. else
  395. b:=is_equal(ppointerdef(def1)^.definition,ppointerdef(def2)^.definition);
  396. end
  397. else
  398. { Grundtypen sind gleich, wenn sie den selben Grundtyp haben, }
  399. { und wenn noetig den selben Unterbereich haben }
  400. if (def1^.deftype=orddef) and (def2^.deftype=orddef) then
  401. begin
  402. case porddef(def1)^.typ of
  403. u32bit,u8bit,s32bit,s8bit,u16bit,s16bit : begin
  404. if porddef(def1)^.typ=porddef(def2)^.typ then
  405. if (porddef(def1)^.von=porddef(def2)^.von) and
  406. (porddef(def1)^.bis=porddef(def2)^.bis) then
  407. b:=true;
  408. end;
  409. uvoid,bool8bit,uchar :
  410. b:=porddef(def1)^.typ=porddef(def2)^.typ;
  411. end;
  412. end
  413. else
  414. if (def1^.deftype=floatdef) and (def2^.deftype=floatdef) then
  415. b:=pfloatdef(def1)^.typ=pfloatdef(def2)^.typ
  416. else
  417. { strings with the same length are equal }
  418. if (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  419. (pstringdef(def1)^.len=pstringdef(def2)^.len) then
  420. b:=true
  421. { STRING[N] ist equivalent zu ARRAY[0..N] OF CHAR (N<256) }
  422. {
  423. else if ((def1^.deftype=stringdef) and (def2^.deftype=arraydef)) and
  424. (parraydef(def2)^.definition^.deftype=orddef) and
  425. (porddef(parraydef(def1)^.definition)^.typ=uchar) and
  426. (parraydef(def2)^.lowrange=0) and
  427. (parraydef(def2)^.highrange=pstringdef(def1)^.len) then
  428. b:=true }
  429. else
  430. if (def1^.deftype=formaldef) and (def2^.deftype=formaldef) then
  431. b:=true
  432. { file types with the same file element type are equal }
  433. { this is a problem for assign !! }
  434. { changed to allow if one is untyped }
  435. { all typed files are equal to the special }
  436. { typed file that has voiddef as elemnt type }
  437. { but must NOT match for text file !!! }
  438. else
  439. if (def1^.deftype=filedef) and (def2^.deftype=filedef) then
  440. b:=(pfiledef(def1)^.filetype=pfiledef(def2)^.filetype) and
  441. ((
  442. ((pfiledef(def1)^.typed_as=nil) and
  443. (pfiledef(def2)^.typed_as=nil)) or
  444. (
  445. (pfiledef(def1)^.typed_as<>nil) and
  446. (pfiledef(def2)^.typed_as<>nil) and
  447. is_equal(pfiledef(def1)^.typed_as,pfiledef(def2)^.typed_as)
  448. ) or
  449. ( (pfiledef(def1)^.typed_as=pdef(voiddef)) or
  450. (pfiledef(def2)^.typed_as=pdef(voiddef))
  451. )))
  452. { sets with the same element type are equal }
  453. else
  454. if (def1^.deftype=setdef) and (def2^.deftype=setdef) then
  455. begin
  456. if assigned(psetdef(def1)^.setof) and
  457. assigned(psetdef(def2)^.setof) then
  458. b:=is_equal(psetdef(def1)^.setof,psetdef(def2)^.setof)
  459. else b:=true;
  460. end
  461. else
  462. if (def1^.deftype=procvardef) and (def2^.deftype=procvardef) then
  463. begin
  464. { poassembler isn't important for compatibility }
  465. b:=((pprocvardef(def1)^.options and not(poassembler))=
  466. (pprocvardef(def2)^.options and not(poassembler))
  467. ) and
  468. is_equal(pprocvardef(def1)^.retdef,pprocvardef(def2)^.retdef);
  469. { now evalute the parameters }
  470. if b then
  471. begin
  472. hp1:=pprocvardef(def1)^.para1;
  473. hp2:=pprocvardef(def1)^.para1;
  474. while assigned(hp1) and assigned(hp2) do
  475. begin
  476. if not(is_equal(hp1^.data,hp2^.data)) or
  477. not(hp1^.paratyp=hp2^.paratyp) then
  478. begin
  479. b:=false;
  480. break;
  481. end;
  482. hp1:=hp1^.next;
  483. hp2:=hp2^.next;
  484. end;
  485. b:=(hp1=nil) and (hp2=nil);
  486. end;
  487. end
  488. else
  489. if (def1^.deftype=arraydef) and (def2^.deftype=arraydef) and
  490. (is_open_array(def1) or is_open_array(def2)) then
  491. begin
  492. b:=is_equal(parraydef(def1)^.definition,parraydef(def2)^.definition);
  493. end
  494. else
  495. if (def1^.deftype=classrefdef) and (def2^.deftype=classrefdef) then
  496. begin
  497. { similar to pointerdef: }
  498. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  499. b:=(def1^.sym=def2^.sym)
  500. else
  501. b:=is_equal(pclassrefdef(def1)^.definition,pclassrefdef(def2)^.definition);
  502. end;
  503. is_equal:=b;
  504. end;
  505. function is_subequal(def1, def2: pdef): boolean;
  506. Begin
  507. if assigned(def1) and assigned(def2) then
  508. Begin
  509. is_subequal := FALSE;
  510. if (def1^.deftype = orddef) and (def2^.deftype = orddef) then
  511. Begin
  512. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  513. { range checking for case statements is done with testrange }
  514. case porddef(def1)^.typ of
  515. s32bit,u32bit,u8bit,s8bit,s16bit,u16bit:
  516. Begin
  517. { PROBABLE CODE GENERATION BUG HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! }
  518. { if porddef(def2)^.typ in [s32bit,u32bit,u8bit,s8bit,s16bit,u16bit] then
  519. is_subequal := TRUE; }
  520. if (porddef(def2)^.typ = s32bit) or
  521. (porddef(def2)^.typ = u32bit) or
  522. (porddef(def2)^.typ = u8bit) or
  523. (porddef(def2)^.typ = s8bit) or
  524. (porddef(def2)^.typ = s16bit) or
  525. (porddef(def2)^.typ = u16bit) then
  526. Begin
  527. is_subequal:=TRUE;
  528. end;
  529. end;
  530. bool8bit: if porddef(def2)^.typ = bool8bit then is_subequal := TRUE;
  531. uchar: if porddef(def2)^.typ = uchar then is_subequal := TRUE;
  532. end;
  533. end
  534. else
  535. Begin
  536. { I assume that both enumerations are equal when the first }
  537. { pointers are equal. }
  538. if (def1^.deftype = enumdef) and (def2^.deftype =enumdef) then
  539. Begin
  540. if penumdef(def1)^.first = penumdef(def2)^.first then
  541. is_subequal := TRUE;
  542. end;
  543. end;
  544. end; { endif assigned ... }
  545. end;
  546. type
  547. pprocdefcoll = ^tprocdefcoll;
  548. tprocdefcoll = record
  549. next : pprocdefcoll;
  550. data : pprocdef;
  551. end;
  552. psymcoll = ^tsymcoll;
  553. tsymcoll = record
  554. next : psymcoll;
  555. name : pstring;
  556. data : pprocdefcoll;
  557. end;
  558. var
  559. wurzel : psymcoll;
  560. nextvirtnumber : longint;
  561. _c : pobjectdef;
  562. has_constructor,has_virtual_method : boolean;
  563. procedure eachsym(sym : psym);{$ifndef FPC}far;{$endif}
  564. var
  565. procdefcoll : pprocdefcoll;
  566. hp : pprocdef;
  567. symcoll : psymcoll;
  568. _name : string;
  569. stored : boolean;
  570. begin
  571. { nur Unterprogrammsymbole werden in die VMT aufgenommen }
  572. if sym^.typ=procsym then
  573. begin
  574. _name:=sym^.name;
  575. symcoll:=wurzel;
  576. while assigned(symcoll) do
  577. begin
  578. { wenn das Symbol in der Liste schon existiert }
  579. if _name=symcoll^.name^ then
  580. begin
  581. { walk thorugh all defs of the symbol }
  582. hp:=pprocsym(sym)^.definition;
  583. while assigned(hp) do
  584. begin
  585. { compare with all stored definitions }
  586. procdefcoll:=symcoll^.data;
  587. stored:=false;
  588. while assigned(procdefcoll) do
  589. begin
  590. { compare parameters }
  591. if equal_paras(procdefcoll^.data^.para1,hp^.para1) and
  592. (
  593. ((procdefcoll^.data^.options and povirtualmethod)<>0) or
  594. ((hp^.options and povirtualmethod)<>0)
  595. ) then
  596. begin
  597. { wenn sie gleich sind }
  598. { und eine davon virtual deklariert ist }
  599. { Fehler falls nur eine VIRTUAL }
  600. if (procdefcoll^.data^.options and povirtualmethod)<>
  601. (hp^.options and povirtualmethod) then
  602. Message1(parser_e_overloaded_are_not_both_virtual,_c^.name^+'.'+_name);
  603. { check, if the overridden directive is set }
  604. { (povirtualmethod is set! }
  605. { class ? }
  606. if ((_c^.options and oois_class)<>0) and
  607. ((hp^.options and pooverridingmethod)=0) then
  608. Message1(parser_e_must_use_override,_c^.name^+'.'+_name);
  609. { error, if the return types aren't equal }
  610. if not(is_equal(procdefcoll^.data^.retdef,hp^.retdef)) then
  611. Message1(parser_e_overloaded_methodes_not_same_ret,_c^.name^+'.'+_name);
  612. { the flags have to match }
  613. { except abstract and override }
  614. if (procdefcoll^.data^.options and not(poabstractmethod or pooverridingmethod))<>
  615. (hp^.options and not(poabstractmethod or pooverridingmethod)) then
  616. Message1(parser_e_header_dont_match_forward,_c^.name^+'.'+_name);
  617. { now set the number }
  618. hp^.extnumber:=procdefcoll^.data^.extnumber;
  619. { and exchange }
  620. procdefcoll^.data:=hp;
  621. stored:=true;
  622. end;
  623. procdefcoll:=procdefcoll^.next;
  624. end;
  625. { if it isn't saved in the list }
  626. { we create a new entry }
  627. if not(stored) then
  628. begin
  629. new(procdefcoll);
  630. procdefcoll^.data:=hp;
  631. procdefcoll^.next:=symcoll^.data;
  632. symcoll^.data:=procdefcoll;
  633. { if the method is virtual ... }
  634. if (hp^.options and povirtualmethod)<>0 then
  635. begin
  636. { ... it will get a number }
  637. hp^.extnumber:=nextvirtnumber;
  638. inc(nextvirtnumber);
  639. end;
  640. { check, if a method should be overridden }
  641. if (hp^.options and pooverridingmethod)<>0 then
  642. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  643. end;
  644. hp:=hp^.nextoverloaded;
  645. end;
  646. exit;
  647. end;
  648. symcoll:=symcoll^.next;
  649. end;
  650. { if not, generate a new symbol item }
  651. new(symcoll);
  652. symcoll^.name:=stringdup(sym^.name);
  653. symcoll^.next:=wurzel;
  654. symcoll^.data:=nil;
  655. wurzel:=symcoll;
  656. hp:=pprocsym(sym)^.definition;
  657. { inserts all definitions }
  658. while assigned(hp) do
  659. begin
  660. new(procdefcoll);
  661. procdefcoll^.data:=hp;
  662. procdefcoll^.next:=symcoll^.data;
  663. symcoll^.data:=procdefcoll;
  664. { if it's a virtual method }
  665. if (hp^.options and povirtualmethod)<>0 then
  666. begin
  667. { then it gets a number ... }
  668. hp^.extnumber:=nextvirtnumber;
  669. { and we inc the number }
  670. inc(nextvirtnumber);
  671. has_virtual_method:=true;
  672. end;
  673. if (hp^.options and poconstructor)<>0 then
  674. has_constructor:=true;
  675. { check, if a method should be overridden }
  676. if (hp^.options and pooverridingmethod)<>0 then
  677. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  678. { next overloaded method }
  679. hp:=hp^.nextoverloaded;
  680. end;
  681. end;
  682. end;
  683. procedure genvmt(_class : pobjectdef);
  684. procedure do_genvmt(p : pobjectdef);
  685. begin
  686. { start with the base class }
  687. if assigned(p^.childof) then
  688. do_genvmt(p^.childof);
  689. { walk through all public syms }
  690. _c:=_class;
  691. {$ifdef tp}
  692. p^.publicsyms^.foreach(eachsym);
  693. {$else}
  694. p^.publicsyms^.foreach(@eachsym);
  695. {$endif}
  696. end;
  697. var
  698. symcoll : psymcoll;
  699. procdefcoll : pprocdefcoll;
  700. i : longint;
  701. begin
  702. wurzel:=nil;
  703. nextvirtnumber:=0;
  704. has_constructor:=false;
  705. has_virtual_method:=false;
  706. { generates a tree of all used methods }
  707. do_genvmt(_class);
  708. if has_virtual_method and not(has_constructor) then
  709. begin
  710. exterror:=strpnew(_class^.name^);
  711. Message(parser_w_virtual_without_constructor);
  712. end;
  713. { generates the VMT }
  714. { walk trough all numbers for virtual methods and search }
  715. { the method }
  716. for i:=0 to nextvirtnumber-1 do
  717. begin
  718. symcoll:=wurzel;
  719. { walk trough all symbols }
  720. while assigned(symcoll) do
  721. begin
  722. { walk trough all methods }
  723. procdefcoll:=symcoll^.data;
  724. while assigned(procdefcoll) do
  725. begin
  726. { writes the addresses to the VMT }
  727. { but only this which are declared as virtual }
  728. if procdefcoll^.data^.extnumber=i then
  729. begin
  730. if (procdefcoll^.data^.options and povirtualmethod)<>0 then
  731. begin
  732. { if a method is abstract, then is also the }
  733. { class abstract and it's not allow to }
  734. { generates an instance }
  735. if (procdefcoll^.data^.options and poabstractmethod)<>0 then
  736. begin
  737. _class^.options:=_class^.options or oois_abstract;
  738. datasegment^.concat(new(pai_const,init_symbol('ABSTRACTERROR')));
  739. end
  740. else
  741. datasegment^.concat(new(pai_const,init_symbol(
  742. strpnew(procdefcoll^.data^.mangledname))));
  743. end;
  744. end;
  745. procdefcoll:=procdefcoll^.next;
  746. end;
  747. symcoll:=symcoll^.next;
  748. end;
  749. end;
  750. { disposes the above generated tree }
  751. symcoll:=wurzel;
  752. while assigned(symcoll) do
  753. begin
  754. wurzel:=symcoll^.next;
  755. stringdispose(symcoll^.name);
  756. procdefcoll:=symcoll^.data;
  757. while assigned(procdefcoll) do
  758. begin
  759. symcoll^.data:=procdefcoll^.next;
  760. dispose(procdefcoll);
  761. procdefcoll:=symcoll^.data;
  762. end;
  763. dispose(symcoll);
  764. symcoll:=wurzel;
  765. end;
  766. end;
  767. end.
  768. {
  769. $Log$
  770. Revision 1.2 1998-03-28 23:09:57 florian
  771. * secondin bugfix (m68k and i386)
  772. * overflow checking bugfix (m68k and i386) -- pretty useless in
  773. secondadd, since everything is done using 32-bit
  774. * loading pointer to routines hopefully fixed (m68k)
  775. * flags problem with calls to RTL internal routines fixed (still strcmp
  776. to fix) (m68k)
  777. * #ELSE was still incorrect (didn't take care of the previous level)
  778. * problem with filenames in the command line solved
  779. * problem with mangledname solved
  780. * linking name problem solved (was case insensitive)
  781. * double id problem and potential crash solved
  782. * stop after first error
  783. * and=>test problem removed
  784. * correct read for all float types
  785. * 2 sigsegv fixes and a cosmetic fix for Internal Error
  786. * push/pop is now correct optimized (=> mov (%esp),reg)
  787. Revision 1.1.1.1 1998/03/25 11:18:15 root
  788. * Restored version
  789. Revision 1.24 1998/03/21 23:59:40 florian
  790. * indexed properties fixed
  791. * ppu i/o of properties fixed
  792. * field can be also used for write access
  793. * overriding of properties
  794. Revision 1.23 1998/03/20 23:31:35 florian
  795. * bug0113 fixed
  796. * problem with interdepened units fixed ("options.pas problem")
  797. * two small extensions for future AMD 3D support
  798. Revision 1.22 1998/03/10 01:17:30 peter
  799. * all files have the same header
  800. * messages are fully implemented, EXTDEBUG uses Comment()
  801. + AG... files for the Assembler generation
  802. Revision 1.21 1998/03/06 01:09:01 peter
  803. * removed the conflicts that had occured
  804. Revision 1.20 1998/03/06 00:53:01 peter
  805. * replaced all old messages from errore.msg, only ExtDebug and some
  806. Comment() calls are left
  807. * fixed options.pas
  808. Revision 1.19 1998/03/05 22:40:56 florian
  809. + warning about missing constructor added
  810. Revision 1.18 1998/03/04 17:34:14 michael
  811. + Changed ifdef FPK to ifdef FPC
  812. Revision 1.17 1998/03/02 01:49:38 peter
  813. * renamed target_DOS to target_GO32V1
  814. + new verbose system, merged old errors and verbose units into one new
  815. verbose.pas, so errors.pas is obsolete
  816. Revision 1.16 1998/02/13 10:35:55 daniel
  817. * Made Motorola version compilable.
  818. * Fixed optimizer
  819. Revision 1.15 1998/02/12 17:19:33 florian
  820. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  821. also that aktswitches isn't a pointer)
  822. Revision 1.14 1998/02/12 11:50:52 daniel
  823. Yes! Finally! After three retries, my patch!
  824. Changes:
  825. Complete rewrite of psub.pas.
  826. Added support for DLL's.
  827. Compiler requires less memory.
  828. Platform units for each platform.
  829. Revision 1.13 1998/02/11 21:56:41 florian
  830. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  831. Revision 1.12 1998/02/07 23:05:08 florian
  832. * once more MMX
  833. Revision 1.11 1998/02/06 10:34:35 florian
  834. * bug0082 and bug0084 fixed
  835. Revision 1.10 1998/02/05 22:27:07 florian
  836. * small problems fixed: remake3 should now work
  837. Revision 1.9 1998/02/05 21:54:36 florian
  838. + more MMX
  839. Revision 1.8 1998/01/31 00:43:37 carl
  840. - removed in in is_subequal, because the code generator is buggy!
  841. (instead uses if...)
  842. Revision 1.7 1998/01/16 18:03:21 florian
  843. * small bug fixes, some stuff of delphi styled constructores added
  844. Revision 1.6 1998/01/11 19:24:35 carl
  845. + type checking routine (is_subequal) for case statements
  846. Revision 1.5 1998/01/09 23:08:38 florian
  847. + C++/Delphi styled //-comments
  848. * some bugs in Delphi object model fixed
  849. + override directive
  850. Revision 1.4 1998/01/09 16:08:24 florian
  851. * abstract methods call now abstracterrorproc if they are called
  852. a class with an abstract method can be create with a class reference else
  853. the compiler forbides this
  854. Revision 1.3 1998/01/07 00:17:12 michael
  855. Restored released version (plus fixes) as current
  856. Revision 1.2 1997/11/28 18:14:51 pierre
  857. working version with several bug fixes
  858. Revision 1.1.1.1 1997/11/27 08:33:03 michael
  859. FPC Compiler CVS start
  860. Pre-CVS log:
  861. CEC Carl-Eric Codere
  862. FK Florian Klaempfl
  863. PM Pierre Muller
  864. + feature added
  865. - removed
  866. * bug fixed or changed
  867. History:
  868. 22th september 1997
  869. + function dont_copy_const_param added (FK)
  870. 25th september 1997
  871. + is_open_array added (FK)
  872. + is_equal handles now also open arrays (FK)
  873. 2nd october 1997
  874. + added then boolean never_copy_const_param for use in typed write
  875. where we must push the reference anyway (PM)
  876. 3rd october 1997:
  877. + renamed ret_in_eax to ret_in_acc (for accumulator for port.) (CEC)
  878. - removed reference to i386 unit (CEC)
  879. 25th october 1997:
  880. * poassembler isn't important for compatiblity of proc vars (FK)
  881. 3rd november 1997:
  882. + added formaldef type to types where we dont_copy_const_param (PM)
  883. 20rd november 1997:
  884. + added is_fpu function (PM)
  885. }