types.pas 41 KB

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