types.pas 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  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,symtable;
  22. type
  23. tmmxtype = (mmxno,mmxu8bit,mmxs8bit,mmxu16bit,mmxs16bit,
  24. mmxu32bit,mmxs32bit,mmxfixed16,mmxsingle);
  25. const
  26. { true if we must never copy this parameter }
  27. never_copy_const_param : boolean = false;
  28. {*****************************************************************************
  29. Basic type functions
  30. *****************************************************************************}
  31. { returns true, if def defines an ordinal type }
  32. function is_ordinal(def : pdef) : boolean;
  33. { returns the min. value of the type }
  34. function get_min_value(def : pdef) : longint;
  35. { returns true, if def defines an ordinal type }
  36. function is_integer(def : pdef) : boolean;
  37. { true if p is a boolean }
  38. function is_boolean(def : pdef) : boolean;
  39. { true if p is a char }
  40. function is_char(def : pdef) : boolean;
  41. { true if p is a smallset def }
  42. function is_smallset(p : pdef) : boolean;
  43. { returns true, if def defines a signed data type (only for ordinal types) }
  44. function is_signed(def : pdef) : boolean;
  45. {*****************************************************************************
  46. Array helper functions
  47. *****************************************************************************}
  48. { true, if p points to a zero based (non special like open or
  49. dynamic array def, mainly this is used to see if the array
  50. is convertable to a pointer }
  51. function is_zero_based_array(p : pdef) : boolean;
  52. { true if p points to an open array def }
  53. function is_open_array(p : pdef) : boolean;
  54. { true, if p points to an array of const def }
  55. function is_array_constructor(p : pdef) : boolean;
  56. { true, if p points to a variant array }
  57. function is_variant_array(p : pdef) : boolean;
  58. { true, if p points to an array of const }
  59. function is_array_of_const(p : pdef) : boolean;
  60. { true, if p points any kind of special array }
  61. function is_special_array(p : pdef) : boolean;
  62. { true if p is a char array def }
  63. function is_chararray(p : pdef) : boolean;
  64. {*****************************************************************************
  65. String helper functions
  66. *****************************************************************************}
  67. { true if p points to an open string def }
  68. function is_open_string(p : pdef) : boolean;
  69. { true if p is an ansi string def }
  70. function is_ansistring(p : pdef) : boolean;
  71. { true if p is a long string def }
  72. function is_longstring(p : pdef) : boolean;
  73. { true if p is a wide string def }
  74. function is_widestring(p : pdef) : boolean;
  75. { true if p is a short string def }
  76. function is_shortstring(p : pdef) : boolean;
  77. { true if p is a pchar def }
  78. function is_pchar(p : pdef) : boolean;
  79. { returns true, if def uses FPU }
  80. function is_fpu(def : pdef) : boolean;
  81. { true if the return value is in EAX }
  82. function ret_in_acc(def : pdef) : boolean;
  83. { true if uses a parameter as return value }
  84. function ret_in_param(def : pdef) : boolean;
  85. { true, if def is a 64 bit int type }
  86. function is_64bitint(def : pdef) : boolean;
  87. function push_high_param(def : pdef) : boolean;
  88. { true if a parameter is too large to copy and only the address is pushed }
  89. function push_addr_param(def : pdef) : boolean;
  90. { true, if def1 and def2 are semantical the same }
  91. function is_equal(def1,def2 : pdef) : boolean;
  92. { checks for type compatibility (subgroups of type) }
  93. { used for case statements... probably missing stuff }
  94. { to use on other types }
  95. function is_subequal(def1, def2: pdef): boolean;
  96. { same as is_equal, but with error message if failed }
  97. function CheckTypes(def1,def2 : pdef) : boolean;
  98. { true, if two parameter lists are equal }
  99. { if value_equal_const is true, call by value }
  100. { and call by const parameter are assumed as }
  101. { equal }
  102. function equal_paras(def1,def2 : pdefcoll;value_equal_const : boolean) : boolean;
  103. { true if a function can be assigned to a procvar }
  104. function proc_to_procvar_equal(def1:pprocdef;def2:pprocvardef) : boolean;
  105. { if l isn't in the range of def a range check error is generated and
  106. the value is placed within the range }
  107. procedure testrange(def : pdef;var l : longint);
  108. { returns the range of def }
  109. procedure getrange(def : pdef;var l : longint;var h : longint);
  110. { some type helper routines for MMX support }
  111. function is_mmx_able_array(p : pdef) : boolean;
  112. { returns the mmx type }
  113. function mmx_type(p : pdef) : tmmxtype;
  114. implementation
  115. uses
  116. strings,
  117. globtype,globals,verbose;
  118. function equal_paras(def1,def2 : pdefcoll;value_equal_const : boolean) : boolean;
  119. begin
  120. while (assigned(def1)) and (assigned(def2)) do
  121. begin
  122. if value_equal_const then
  123. begin
  124. if not(is_equal(def1^.data,def2^.data)) or
  125. ((def1^.paratyp<>def2^.paratyp) and
  126. ((def1^.paratyp=vs_var) or
  127. (def1^.paratyp=vs_var)
  128. )
  129. ) then
  130. begin
  131. equal_paras:=false;
  132. exit;
  133. end;
  134. end
  135. else
  136. begin
  137. if not(is_equal(def1^.data,def2^.data)) or
  138. (def1^.paratyp<>def2^.paratyp) then
  139. begin
  140. equal_paras:=false;
  141. exit;
  142. end;
  143. end;
  144. def1:=def1^.next;
  145. def2:=def2^.next;
  146. end;
  147. if (def1=nil) and (def2=nil) then
  148. equal_paras:=true
  149. else
  150. equal_paras:=false;
  151. end;
  152. { true if a function can be assigned to a procvar }
  153. function proc_to_procvar_equal(def1:pprocdef;def2:pprocvardef) : boolean;
  154. var
  155. ismethod : boolean;
  156. begin
  157. proc_to_procvar_equal:=false;
  158. { check for method pointer }
  159. ismethod:=(def1^.owner^.symtabletype=objectsymtable) and
  160. (pobjectdef(def1^.owner^.defowner)^.isclass);
  161. if (ismethod and not ((def2^.options and pomethodpointer)<>0)) or
  162. (not(ismethod) and ((def2^.options and pomethodpointer)<>0)) then
  163. begin
  164. Message(type_e_no_method_and_procedure_not_compatible);
  165. exit;
  166. end;
  167. { check the other things }
  168. if is_equal(def1^.retdef,def2^.retdef) and
  169. equal_paras(def1^.para1,def2^.para1,false) and
  170. ((def1^.options and po_compatibility_options)=
  171. (def2^.options and po_compatibility_options)) then
  172. proc_to_procvar_equal:=true
  173. else
  174. proc_to_procvar_equal:=false;
  175. end;
  176. { returns true, if def uses FPU }
  177. function is_fpu(def : pdef) : boolean;
  178. begin
  179. is_fpu:=(def^.deftype=floatdef) and (pfloatdef(def)^.typ<>f32bit);
  180. end;
  181. { true if p is an ordinal }
  182. function is_ordinal(def : pdef) : boolean;
  183. var
  184. dt : tbasetype;
  185. begin
  186. case def^.deftype of
  187. orddef : begin
  188. dt:=porddef(def)^.typ;
  189. is_ordinal:=dt in [uchar,u8bit,u16bit,u32bit,u64bit,s8bit,s16bit,s32bit,
  190. s64bitint,bool8bit,bool16bit,bool32bit];
  191. end;
  192. enumdef : is_ordinal:=true;
  193. else
  194. is_ordinal:=false;
  195. end;
  196. end;
  197. { returns the min. value of the type }
  198. function get_min_value(def : pdef) : longint;
  199. begin
  200. case def^.deftype of
  201. orddef:
  202. get_min_value:=porddef(def)^.low;
  203. enumdef:
  204. get_min_value:=penumdef(def)^.min;
  205. else
  206. get_min_value:=0;
  207. end;
  208. end;
  209. { true if p is an integer }
  210. function is_integer(def : pdef) : boolean;
  211. begin
  212. is_integer:=(def^.deftype=orddef) and
  213. (porddef(def)^.typ in [uauto,u8bit,u16bit,u32bit,s8bit,s16bit,s32bit]);
  214. end;
  215. { true if p is a boolean }
  216. function is_boolean(def : pdef) : boolean;
  217. begin
  218. is_boolean:=(def^.deftype=orddef) and
  219. (porddef(def)^.typ in [bool8bit,bool16bit,bool32bit]);
  220. end;
  221. { true if p is a char }
  222. function is_char(def : pdef) : boolean;
  223. begin
  224. is_char:=(def^.deftype=orddef) and
  225. (porddef(def)^.typ=uchar);
  226. end;
  227. { true if p is signed (integer) }
  228. function is_signed(def : pdef) : boolean;
  229. var
  230. dt : tbasetype;
  231. begin
  232. case def^.deftype of
  233. orddef : begin
  234. dt:=porddef(def)^.typ;
  235. is_signed:=(dt in [s8bit,s16bit,s32bit]);
  236. end;
  237. enumdef : is_signed:=false;
  238. else
  239. is_signed:=false;
  240. end;
  241. end;
  242. { true, if p points to an open array def }
  243. function is_open_string(p : pdef) : boolean;
  244. begin
  245. is_open_string:=(p^.deftype=stringdef) and
  246. (pstringdef(p)^.string_typ=st_shortstring) and
  247. (pstringdef(p)^.len=0);
  248. end;
  249. { true, if p points to a zero based array def }
  250. function is_zero_based_array(p : pdef) : boolean;
  251. begin
  252. is_zero_based_array:=(p^.deftype=arraydef) and
  253. (parraydef(p)^.lowrange=0) and
  254. not(is_special_array(p));
  255. end;
  256. { true, if p points to an open array def }
  257. function is_open_array(p : pdef) : boolean;
  258. begin
  259. is_open_array:=(p^.deftype=arraydef) and
  260. (parraydef(p)^.lowrange=0) and
  261. (parraydef(p)^.highrange=-1) and
  262. not(parraydef(p)^.IsConstructor) and
  263. not(parraydef(p)^.IsVariant) and
  264. not(parraydef(p)^.IsArrayOfConst);
  265. end;
  266. { true, if p points to an array of const def }
  267. function is_array_constructor(p : pdef) : boolean;
  268. begin
  269. is_array_constructor:=(p^.deftype=arraydef) and
  270. (parraydef(p)^.IsConstructor);
  271. end;
  272. { true, if p points to a variant array }
  273. function is_variant_array(p : pdef) : boolean;
  274. begin
  275. is_variant_array:=(p^.deftype=arraydef) and
  276. (parraydef(p)^.IsVariant);
  277. end;
  278. { true, if p points to an array of const }
  279. function is_array_of_const(p : pdef) : boolean;
  280. begin
  281. is_array_of_const:=(p^.deftype=arraydef) and
  282. (parraydef(p)^.IsArrayOfConst);
  283. end;
  284. { true, if p points to a special array }
  285. function is_special_array(p : pdef) : boolean;
  286. begin
  287. is_special_array:=(p^.deftype=arraydef) and
  288. ((parraydef(p)^.IsVariant) or
  289. (parraydef(p)^.IsArrayOfConst) or
  290. (parraydef(p)^.IsConstructor) or
  291. is_open_array(p)
  292. );
  293. end;
  294. { true if p is an ansi string def }
  295. function is_ansistring(p : pdef) : boolean;
  296. begin
  297. is_ansistring:=(p^.deftype=stringdef) and
  298. (pstringdef(p)^.string_typ=st_ansistring);
  299. end;
  300. { true if p is an long string def }
  301. function is_longstring(p : pdef) : boolean;
  302. begin
  303. is_longstring:=(p^.deftype=stringdef) and
  304. (pstringdef(p)^.string_typ=st_longstring);
  305. end;
  306. { true if p is an wide string def }
  307. function is_widestring(p : pdef) : boolean;
  308. begin
  309. is_widestring:=(p^.deftype=stringdef) and
  310. (pstringdef(p)^.string_typ=st_widestring);
  311. end;
  312. { true if p is an short string def }
  313. function is_shortstring(p : pdef) : boolean;
  314. begin
  315. is_shortstring:=(p^.deftype=stringdef) and
  316. (pstringdef(p)^.string_typ=st_shortstring);
  317. end;
  318. { true if p is a char array def }
  319. function is_chararray(p : pdef) : boolean;
  320. begin
  321. is_chararray:=(p^.deftype=arraydef) and
  322. is_equal(parraydef(p)^.definition,cchardef) and
  323. not(is_special_array(p));
  324. end;
  325. { true if p is a pchar def }
  326. function is_pchar(p : pdef) : boolean;
  327. begin
  328. is_pchar:=(p^.deftype=pointerdef) and
  329. is_equal(Ppointerdef(p)^.definition,cchardef);
  330. end;
  331. { true if p is a smallset def }
  332. function is_smallset(p : pdef) : boolean;
  333. begin
  334. is_smallset:=(p^.deftype=setdef) and
  335. (psetdef(p)^.settype=smallset);
  336. end;
  337. { true if the return value is in accumulator (EAX for i386), D0 for 68k }
  338. function ret_in_acc(def : pdef) : boolean;
  339. begin
  340. ret_in_acc:=(def^.deftype in [orddef,pointerdef,enumdef,classrefdef]) or
  341. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_ansistring,st_widestring])) or
  342. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)=0)) or
  343. ((def^.deftype=objectdef) and pobjectdef(def)^.isclass) or
  344. ((def^.deftype=setdef) and (psetdef(def)^.settype=smallset)) or
  345. ((def^.deftype=floatdef) and (pfloatdef(def)^.typ=f32bit));
  346. end;
  347. { true, if def is a 64 bit int type }
  348. function is_64bitint(def : pdef) : boolean;
  349. begin
  350. is_64bitint:=(def^.deftype=orddef) and (porddef(def)^.typ in [u64bit,s64bitint])
  351. end;
  352. { true if uses a parameter as return value }
  353. function ret_in_param(def : pdef) : boolean;
  354. begin
  355. ret_in_param:=(def^.deftype in [arraydef,recorddef]) or
  356. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
  357. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)<>0)) or
  358. ((def^.deftype=objectdef) and not(pobjectdef(def)^.isclass)) or
  359. ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
  360. end;
  361. function push_high_param(def : pdef) : boolean;
  362. begin
  363. push_high_param:=is_open_array(def) or is_open_string(def) or
  364. is_array_of_const(def);
  365. end;
  366. { true if a parameter is too large to copy and only the address is pushed }
  367. function push_addr_param(def : pdef) : boolean;
  368. begin
  369. push_addr_param:=never_copy_const_param or
  370. (def^.deftype = formaldef) or
  371. { copy directly small records or arrays unless array of const ! PM }
  372. ((def^.deftype in [arraydef,recorddef]) and
  373. ((def^.size>4) or
  374. ((def^.deftype=arraydef) and
  375. (parraydef(def)^.IsConstructor or
  376. parraydef(def)^.isArrayOfConst or
  377. is_open_array(def)
  378. )
  379. )
  380. )
  381. ) or
  382. ((def^.deftype=objectdef) and not(pobjectdef(def)^.isclass)) or
  383. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
  384. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)<>0)) or
  385. ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
  386. end;
  387. { test if l is in the range of def, outputs error if out of range }
  388. procedure testrange(def : pdef;var l : longint);
  389. var
  390. lv,hv: longint;
  391. begin
  392. getrange(def,lv,hv);
  393. if (def^.deftype=orddef) and
  394. (porddef(def)^.typ=u32bit) then
  395. begin
  396. if lv<=hv then
  397. begin
  398. if (l<lv) or (l>hv) then
  399. begin
  400. if (cs_check_range in aktlocalswitches) then
  401. Message(parser_e_range_check_error)
  402. else
  403. Message(parser_w_range_check_error);
  404. end;
  405. end
  406. else
  407. { this happens with the wrap around problem }
  408. { if lv is positive and hv is over $7ffffff }
  409. { so it seems negative }
  410. begin
  411. if ((l>=0) and (l<lv)) or
  412. ((l<0) and (l>hv)) then
  413. begin
  414. if (cs_check_range in aktlocalswitches) then
  415. Message(parser_e_range_check_error)
  416. else
  417. Message(parser_w_range_check_error);
  418. end;
  419. end;
  420. end
  421. else if (l<lv) or (l>hv) then
  422. begin
  423. if (def^.deftype=enumdef) or
  424. (cs_check_range in aktlocalswitches) then
  425. Message(parser_e_range_check_error)
  426. else
  427. Message(parser_w_range_check_error);
  428. { Fix the value to be in range }
  429. l:=lv+(l mod (hv-lv+1));
  430. end;
  431. end;
  432. { return the range from def in l and h }
  433. procedure getrange(def : pdef;var l : longint;var h : longint);
  434. begin
  435. case def^.deftype of
  436. orddef :
  437. begin
  438. l:=porddef(def)^.low;
  439. h:=porddef(def)^.high;
  440. end;
  441. enumdef :
  442. begin
  443. l:=penumdef(def)^.min;
  444. h:=penumdef(def)^.max;
  445. end;
  446. arraydef :
  447. begin
  448. l:=parraydef(def)^.lowrange;
  449. h:=parraydef(def)^.highrange;
  450. end;
  451. else
  452. internalerror(987);
  453. end;
  454. end;
  455. function mmx_type(p : pdef) : tmmxtype;
  456. begin
  457. mmx_type:=mmxno;
  458. if is_mmx_able_array(p) then
  459. begin
  460. if parraydef(p)^.definition^.deftype=floatdef then
  461. case pfloatdef(parraydef(p)^.definition)^.typ of
  462. s32real:
  463. mmx_type:=mmxsingle;
  464. f16bit:
  465. mmx_type:=mmxfixed16
  466. end
  467. else
  468. case porddef(parraydef(p)^.definition)^.typ of
  469. u8bit:
  470. mmx_type:=mmxu8bit;
  471. s8bit:
  472. mmx_type:=mmxs8bit;
  473. u16bit:
  474. mmx_type:=mmxu16bit;
  475. s16bit:
  476. mmx_type:=mmxs16bit;
  477. u32bit:
  478. mmx_type:=mmxu32bit;
  479. s32bit:
  480. mmx_type:=mmxs32bit;
  481. end;
  482. end;
  483. end;
  484. function is_mmx_able_array(p : pdef) : boolean;
  485. begin
  486. {$ifdef SUPPORT_MMX}
  487. if (cs_mmx_saturation in aktlocalswitches) then
  488. begin
  489. is_mmx_able_array:=(p^.deftype=arraydef) and
  490. not(is_special_array(p)) and
  491. (
  492. (
  493. (parraydef(p)^.definition^.deftype=orddef) and
  494. (
  495. (
  496. (parraydef(p)^.lowrange=0) and
  497. (parraydef(p)^.highrange=1) and
  498. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  499. )
  500. or
  501. (
  502. (parraydef(p)^.lowrange=0) and
  503. (parraydef(p)^.highrange=3) and
  504. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  505. )
  506. )
  507. )
  508. or
  509. (
  510. (
  511. (parraydef(p)^.definition^.deftype=floatdef) and
  512. (
  513. (parraydef(p)^.lowrange=0) and
  514. (parraydef(p)^.highrange=3) and
  515. (pfloatdef(parraydef(p)^.definition)^.typ=f16bit)
  516. ) or
  517. (
  518. (parraydef(p)^.lowrange=0) and
  519. (parraydef(p)^.highrange=1) and
  520. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  521. )
  522. )
  523. )
  524. );
  525. end
  526. else
  527. begin
  528. is_mmx_able_array:=(p^.deftype=arraydef) and
  529. (
  530. (
  531. (parraydef(p)^.definition^.deftype=orddef) and
  532. (
  533. (
  534. (parraydef(p)^.lowrange=0) and
  535. (parraydef(p)^.highrange=1) and
  536. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  537. )
  538. or
  539. (
  540. (parraydef(p)^.lowrange=0) and
  541. (parraydef(p)^.highrange=3) and
  542. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  543. )
  544. or
  545. (
  546. (parraydef(p)^.lowrange=0) and
  547. (parraydef(p)^.highrange=7) and
  548. (porddef(parraydef(p)^.definition)^.typ in [u8bit,s8bit])
  549. )
  550. )
  551. )
  552. or
  553. (
  554. (parraydef(p)^.definition^.deftype=floatdef) and
  555. (
  556. (
  557. (parraydef(p)^.lowrange=0) and
  558. (parraydef(p)^.highrange=3) and
  559. (pfloatdef(parraydef(p)^.definition)^.typ=f32bit)
  560. )
  561. or
  562. (
  563. (parraydef(p)^.lowrange=0) and
  564. (parraydef(p)^.highrange=1) and
  565. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  566. )
  567. )
  568. )
  569. );
  570. end;
  571. {$else SUPPORT_MMX}
  572. is_mmx_able_array:=false;
  573. {$endif SUPPORT_MMX}
  574. end;
  575. function is_equal(def1,def2 : pdef) : boolean;
  576. var
  577. b : boolean;
  578. hd : pdef;
  579. hp1,hp2 : pdefcoll;
  580. begin
  581. { both types must exists }
  582. if not (assigned(def1) and assigned(def2)) then
  583. begin
  584. is_equal:=false;
  585. exit;
  586. end;
  587. { be sure, that if there is a stringdef, that this is def1 }
  588. if def2^.deftype=stringdef then
  589. begin
  590. hd:=def1;
  591. def1:=def2;
  592. def2:=hd;
  593. end;
  594. b:=false;
  595. { both point to the same definition ? }
  596. if def1=def2 then
  597. b:=true
  598. else
  599. { pointer with an equal definition are equal }
  600. if (def1^.deftype=pointerdef) and (def2^.deftype=pointerdef) then
  601. begin
  602. { here a problem detected in tabsolutesym }
  603. { the types can be forward type !! }
  604. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  605. b:=(def1^.sym=def2^.sym)
  606. else
  607. b:=ppointerdef(def1)^.definition=ppointerdef(def2)^.definition;
  608. end
  609. else
  610. { ordinals are equal only when the ordinal type is equal }
  611. if (def1^.deftype=orddef) and (def2^.deftype=orddef) then
  612. begin
  613. case porddef(def1)^.typ of
  614. u8bit,u16bit,u32bit,
  615. s8bit,s16bit,s32bit:
  616. b:=((porddef(def1)^.typ=porddef(def2)^.typ) and
  617. (porddef(def1)^.low=porddef(def2)^.low) and
  618. (porddef(def1)^.high=porddef(def2)^.high));
  619. uvoid,uchar,
  620. bool8bit,bool16bit,bool32bit:
  621. b:=(porddef(def1)^.typ=porddef(def2)^.typ);
  622. end;
  623. end
  624. else
  625. if (def1^.deftype=floatdef) and (def2^.deftype=floatdef) then
  626. b:=pfloatdef(def1)^.typ=pfloatdef(def2)^.typ
  627. else
  628. { strings with the same length are equal }
  629. if (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  630. (pstringdef(def1)^.string_typ=pstringdef(def2)^.string_typ) then
  631. begin
  632. b:=not(is_shortstring(def1)) or
  633. (pstringdef(def1)^.len=pstringdef(def2)^.len);
  634. end
  635. else
  636. if (def1^.deftype=formaldef) and (def2^.deftype=formaldef) then
  637. b:=true
  638. { file types with the same file element type are equal }
  639. { this is a problem for assign !! }
  640. { changed to allow if one is untyped }
  641. { all typed files are equal to the special }
  642. { typed file that has voiddef as elemnt type }
  643. { but must NOT match for text file !!! }
  644. else
  645. if (def1^.deftype=filedef) and (def2^.deftype=filedef) then
  646. b:=(pfiledef(def1)^.filetype=pfiledef(def2)^.filetype) and
  647. ((
  648. ((pfiledef(def1)^.typed_as=nil) and
  649. (pfiledef(def2)^.typed_as=nil)) or
  650. (
  651. (pfiledef(def1)^.typed_as<>nil) and
  652. (pfiledef(def2)^.typed_as<>nil) and
  653. is_equal(pfiledef(def1)^.typed_as,pfiledef(def2)^.typed_as)
  654. ) or
  655. ( (pfiledef(def1)^.typed_as=pdef(voiddef)) or
  656. (pfiledef(def2)^.typed_as=pdef(voiddef))
  657. )))
  658. { sets with the same element type are equal }
  659. else
  660. if (def1^.deftype=setdef) and (def2^.deftype=setdef) then
  661. begin
  662. if assigned(psetdef(def1)^.setof) and
  663. assigned(psetdef(def2)^.setof) then
  664. b:=(psetdef(def1)^.setof^.deftype=psetdef(def2)^.setof^.deftype)
  665. else
  666. b:=true;
  667. end
  668. else
  669. if (def1^.deftype=procvardef) and (def2^.deftype=procvardef) then
  670. begin
  671. { poassembler isn't important for compatibility }
  672. { if a method is assigned to a methodpointer }
  673. { is checked before }
  674. b:=((pprocvardef(def1)^.options and po_compatibility_options)=
  675. (pprocvardef(def2)^.options and po_compatibility_options)) and
  676. is_equal(pprocvardef(def1)^.retdef,pprocvardef(def2)^.retdef);
  677. { now evalute the parameters }
  678. if b then
  679. begin
  680. hp1:=pprocvardef(def1)^.para1;
  681. hp2:=pprocvardef(def1)^.para1;
  682. while assigned(hp1) and assigned(hp2) do
  683. begin
  684. if not(is_equal(hp1^.data,hp2^.data)) or
  685. not(hp1^.paratyp=hp2^.paratyp) then
  686. begin
  687. b:=false;
  688. break;
  689. end;
  690. hp1:=hp1^.next;
  691. hp2:=hp2^.next;
  692. end;
  693. b:=(hp1=nil) and (hp2=nil);
  694. end;
  695. end
  696. else
  697. if (def1^.deftype=arraydef) and (def2^.deftype=arraydef) and
  698. (is_open_array(def1) or is_open_array(def2) or
  699. is_array_of_const(def1) or is_array_of_const(def2)) then
  700. begin
  701. if parraydef(def1)^.IsArrayOfConst or parraydef(def2)^.IsArrayOfConst then
  702. b:=true
  703. else
  704. b:=is_equal(parraydef(def1)^.definition,parraydef(def2)^.definition);
  705. end
  706. else
  707. if (def1^.deftype=classrefdef) and (def2^.deftype=classrefdef) then
  708. begin
  709. { similar to pointerdef: }
  710. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  711. b:=(def1^.sym=def2^.sym)
  712. else
  713. b:=is_equal(pclassrefdef(def1)^.definition,pclassrefdef(def2)^.definition);
  714. end;
  715. is_equal:=b;
  716. end;
  717. function is_subequal(def1, def2: pdef): boolean;
  718. Begin
  719. if assigned(def1) and assigned(def2) then
  720. Begin
  721. is_subequal := FALSE;
  722. if (def1^.deftype = orddef) and (def2^.deftype = orddef) then
  723. Begin
  724. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  725. { range checking for case statements is done with testrange }
  726. case porddef(def1)^.typ of
  727. u8bit,u16bit,u32bit,
  728. s8bit,s16bit,s32bit :
  729. is_subequal:=(porddef(def2)^.typ in [s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  730. bool8bit,bool16bit,bool32bit :
  731. is_subequal:=(porddef(def2)^.typ in [bool8bit,bool16bit,bool32bit]);
  732. uchar :
  733. is_subequal:=(porddef(def2)^.typ=uchar);
  734. end;
  735. end
  736. else
  737. Begin
  738. { I assume that both enumerations are equal when the first }
  739. { pointers are equal. }
  740. if (def1^.deftype = enumdef) and (def2^.deftype =enumdef) then
  741. Begin
  742. if penumdef(def1)^.firstenum = penumdef(def2)^.firstenum then
  743. is_subequal := TRUE;
  744. end;
  745. end;
  746. end; { endif assigned ... }
  747. end;
  748. function CheckTypes(def1,def2 : pdef) : boolean;
  749. var
  750. s1,s2 : string;
  751. begin
  752. if not is_equal(def1,def2) then
  753. begin
  754. { Crash prevention }
  755. if (not assigned(def1)) or (not assigned(def2)) then
  756. Message(type_e_mismatch)
  757. else
  758. begin
  759. s1:=def1^.typename;
  760. s2:=def2^.typename;
  761. if (s1<>'<unknown type>') and (s2<>'<unknown type>') then
  762. Message2(type_e_not_equal_types,def1^.typename,def2^.typename)
  763. else
  764. Message(type_e_mismatch);
  765. end;
  766. CheckTypes:=false;
  767. end
  768. else
  769. CheckTypes:=true;
  770. end;
  771. end.
  772. {
  773. $Log$
  774. Revision 1.69 1999-06-02 10:11:55 florian
  775. * make cycle fixed i.e. compilation with 0.99.10
  776. * some fixes for qword
  777. * start of register calling conventions
  778. Revision 1.68 1999/06/01 19:27:58 peter
  779. * better checks for procvar and methodpointer
  780. Revision 1.67 1999/05/31 22:54:19 peter
  781. * when range check error is found then fix the value to be within the
  782. range
  783. Revision 1.66 1999/05/28 11:00:51 peter
  784. * removed ungettempoftype
  785. Revision 1.65 1999/05/23 18:42:23 florian
  786. * better error recovering in typed constants
  787. * some problems with arrays of const fixed, some problems
  788. due my previous
  789. - the location type of array constructor is now LOC_MEM
  790. - the pushing of high fixed
  791. - parameter copying fixed
  792. - zero temp. allocation removed
  793. * small problem in the assembler writers fixed:
  794. ref to nil wasn't written correctly
  795. Revision 1.64 1999/05/19 20:55:08 florian
  796. * fix of my previous commit
  797. Revision 1.63 1999/05/19 20:40:15 florian
  798. * fixed a couple of array related bugs:
  799. - var a : array[0..1] of char; p : pchar; p:=a+123; works now
  800. - open arrays with an odd size doesn't work: movsb wasn't generated
  801. - introduced some new array type helper routines (is_special_array) etc.
  802. - made the array type checking in isconvertable more strict, often
  803. open array can be used where is wasn't allowed etc...
  804. Revision 1.62 1999/05/19 16:48:29 florian
  805. * tdef.typename: returns a now a proper type name for the most types
  806. Revision 1.61 1999/05/19 10:31:56 florian
  807. * two bugs reported by Romio (bugs 13) are fixed:
  808. - empty array constructors are now handled correctly (e.g. for sysutils.format)
  809. - comparsion of ansistrings was sometimes coded wrong
  810. Revision 1.60 1999/05/18 14:16:01 peter
  811. * containsself fixes
  812. * checktypes()
  813. Revision 1.59 1999/05/18 09:52:24 peter
  814. * procedure of object and addrn fixes
  815. Revision 1.58 1999/04/19 09:29:51 pierre
  816. + ungettempoftype(pdef) boolean function
  817. returns true (can call ungetiftemp )
  818. unless the temp should be "unget" with temptoremove
  819. (currently ansistring or widestring !)
  820. Revision 1.57 1999/04/14 09:15:08 peter
  821. * first things to store the symbol/def number in the ppu
  822. Revision 1.56 1999/03/24 23:17:42 peter
  823. * fixed bugs 212,222,225,227,229,231,233
  824. Revision 1.55 1999/03/09 11:45:42 pierre
  825. * small arrays and records (size <=4) are copied directly
  826. Revision 1.54 1999/03/02 22:52:20 peter
  827. * fixed char array, which can start with all possible values
  828. Revision 1.53 1999/02/25 21:02:57 peter
  829. * ag386bin updates
  830. + coff writer
  831. Revision 1.52 1999/02/24 09:51:44 florian
  832. * wrong warning fixed, if a non-virtual method was hidden by a virtual
  833. method (repoerted by Matthias Koeppe)
  834. Revision 1.51 1999/02/22 23:33:31 florian
  835. + message directive for integers added
  836. Revision 1.50 1999/02/22 20:13:42 florian
  837. + first implementation of message keyword
  838. Revision 1.49 1999/02/16 00:45:30 peter
  839. * fixed crashes by forgotten strpnew() for init_symbol
  840. Revision 1.48 1999/02/09 23:03:08 florian
  841. * check for duplicate field names in inherited classes/objects
  842. * bug with self from the mailing list solved (the problem
  843. was that classes were sometimes pushed wrong)
  844. Revision 1.47 1999/01/27 00:14:01 florian
  845. * "procedure of object"-stuff fixed
  846. Revision 1.46 1999/01/21 22:10:54 peter
  847. * fixed array of const
  848. * generic platform independent high() support
  849. Revision 1.45 1999/01/20 12:34:22 peter
  850. * fixed typed file read/write
  851. Revision 1.44 1999/01/15 11:33:03 pierre
  852. * bug in mmx code removed
  853. Revision 1.43 1998/12/30 13:41:20 peter
  854. * released valuepara
  855. Revision 1.42 1998/12/11 00:04:03 peter
  856. + globtype,tokens,version unit splitted from globals
  857. Revision 1.41 1998/12/10 09:47:33 florian
  858. + basic operations with int64/qord (compiler with -dint64)
  859. + rtti of enumerations extended: names are now written
  860. Revision 1.40 1998/12/04 10:18:14 florian
  861. * some stuff for procedures of object added
  862. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  863. Revision 1.39 1998/11/27 14:50:55 peter
  864. + open strings, $P switch support
  865. Revision 1.38 1998/11/18 15:44:24 peter
  866. * VALUEPARA for tp7 compatible value parameters
  867. Revision 1.37 1998/11/13 10:15:50 peter
  868. * fixed ptr() with constants
  869. Revision 1.36 1998/11/10 10:09:21 peter
  870. * va_list -> array of const
  871. Revision 1.35 1998/10/19 08:55:13 pierre
  872. * wrong stabs info corrected once again !!
  873. + variable vmt offset with vmt field only if required
  874. implemented now !!!
  875. Revision 1.34 1998/10/12 09:50:06 florian
  876. + support of <procedure var type>:=<pointer> in delphi mode added
  877. Revision 1.33 1998/10/06 20:43:30 peter
  878. * fixed set of bugs. like set of false..true set of #1..#255 and
  879. set of #1..true which was allowed
  880. Revision 1.32 1998/10/05 21:33:35 peter
  881. * fixed 161,165,166,167,168
  882. Revision 1.31 1998/09/23 09:58:56 peter
  883. * first working array of const things
  884. Revision 1.30 1998/09/22 15:40:58 peter
  885. * some extra ifdef GDB
  886. Revision 1.29 1998/09/16 12:37:31 michael
  887. Added FPC_ prefix to abstracterror
  888. Revision 1.28 1998/09/09 16:44:23 florian
  889. * I hope, the case bug is fixed now
  890. Revision 1.27 1998/09/07 17:37:07 florian
  891. * first fixes for published properties
  892. Revision 1.26 1998/09/04 12:24:31 florian
  893. * bug0159 fixed
  894. Revision 1.25 1998/09/04 09:06:36 florian
  895. * bug0132 fixed
  896. Revision 1.24 1998/09/04 08:36:49 peter
  897. * fixed boolean:=integer which is not explicit
  898. Revision 1.23 1998/09/01 17:39:55 peter
  899. + internal constant functions
  900. Revision 1.22 1998/09/01 12:53:28 peter
  901. + aktpackenum
  902. Revision 1.21 1998/08/19 00:42:45 peter
  903. + subrange types for enums
  904. + checking for bounds type with ranges
  905. Revision 1.20 1998/08/18 14:17:14 pierre
  906. * bug about assigning the return value of a function to
  907. a procvar fixed : warning
  908. assigning a proc to a procvar need @ in FPC mode !!
  909. * missing file/line info restored
  910. Revision 1.19 1998/08/18 09:24:48 pierre
  911. * small warning position bug fixed
  912. * support_mmx switches splitting was missing
  913. * rhide error and warning output corrected
  914. Revision 1.18 1998/08/14 18:18:49 peter
  915. + dynamic set contruction
  916. * smallsets are now working (always longint size)
  917. Revision 1.17 1998/08/05 16:00:17 florian
  918. * some fixes for ansi strings
  919. Revision 1.16 1998/07/20 23:35:50 michael
  920. Const ansistrings are not copied.
  921. Revision 1.15 1998/07/18 22:54:32 florian
  922. * some ansi/wide/longstring support fixed:
  923. o parameter passing
  924. o returning as result from functions
  925. Revision 1.14 1998/06/12 14:50:50 peter
  926. * removed the tree dependency to types.pas
  927. * long_fil.pas support (not fully tested yet)
  928. Revision 1.13 1998/06/03 22:49:07 peter
  929. + wordbool,longbool
  930. * rename bis,von -> high,low
  931. * moved some systemunit loading/creating to psystem.pas
  932. Revision 1.12 1998/05/12 10:47:00 peter
  933. * moved printstatus to verb_def
  934. + V_Normal which is between V_Error and V_Warning and doesn't have a
  935. prefix like error: warning: and is included in V_Default
  936. * fixed some messages
  937. * first time parameter scan is only for -v and -T
  938. - removed old style messages
  939. Revision 1.11 1998/05/01 16:38:46 florian
  940. * handling of private and protected fixed
  941. + change_keywords_to_tp implemented to remove
  942. keywords which aren't supported by tp
  943. * break and continue are now symbols of the system unit
  944. + widestring, longstring and ansistring type released
  945. Revision 1.10 1998/04/29 10:34:08 pierre
  946. + added some code for ansistring (not complete nor working yet)
  947. * corrected operator overloading
  948. * corrected nasm output
  949. + started inline procedures
  950. + added starstarn : use ** for exponentiation (^ gave problems)
  951. + started UseTokenInfo cond to get accurate positions
  952. Revision 1.9 1998/04/21 10:16:49 peter
  953. * patches from strasbourg
  954. * objects is not used anymore in the fpc compiled version
  955. Revision 1.8 1998/04/12 22:39:44 florian
  956. * problem with read access to properties solved
  957. * correct handling of hidding methods via virtual (COM)
  958. * correct result type of constructor calls (COM), the resulttype
  959. depends now on the type of the class reference
  960. Revision 1.7 1998/04/10 21:36:56 florian
  961. + some stuff to support method pointers (procedure of object) added
  962. (declaration, parameter handling)
  963. Revision 1.6 1998/04/10 15:39:49 florian
  964. * more fixes to get classes.pas compiled
  965. Revision 1.5 1998/04/09 23:02:16 florian
  966. * small problems solved to get remake3 work
  967. Revision 1.4 1998/04/08 16:58:09 pierre
  968. * several bugfixes
  969. ADD ADC and AND are also sign extended
  970. nasm output OK (program still crashes at end
  971. and creates wrong assembler files !!)
  972. procsym types sym in tdef removed !!
  973. Revision 1.3 1998/04/08 11:34:22 peter
  974. * nasm works (linux only tested)
  975. }