types.pas 40 KB

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