defutil.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 defutil;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,
  23. globals,
  24. symconst,symbase,symtype,symdef,
  25. cgbase,cpuinfo,cpubase;
  26. type
  27. tmmxtype = (mmxno,mmxu8bit,mmxs8bit,mmxu16bit,mmxs16bit,
  28. mmxu32bit,mmxs32bit,mmxfixed16,mmxsingle);
  29. {*****************************************************************************
  30. Basic type functions
  31. *****************************************************************************}
  32. {# Returns true, if definition defines an ordinal type }
  33. function is_ordinal(def : tdef) : boolean;
  34. {# Returns the minimal integer value of the type }
  35. function get_min_value(def : tdef) : TConstExprInt;
  36. {# Returns basetype of the specified integer range }
  37. function range_to_basetype(l,h:TConstExprInt):tbasetype;
  38. procedure range_to_type(l,h:TConstExprInt;var tt:ttype);
  39. procedure int_to_type(v:TConstExprInt;var tt:ttype);
  40. {# Returns true, if definition defines an integer type }
  41. function is_integer(def : tdef) : boolean;
  42. { true if p is a 32bit int i.e. dword or longint }
  43. function is_32bitint(def : tdef) : boolean;
  44. {# Returns true if definition is a boolean }
  45. function is_boolean(def : tdef) : boolean;
  46. {# Returns true if definition is a char
  47. This excludes the unicode char.
  48. }
  49. function is_char(def : tdef) : boolean;
  50. {# Returns true if definition is a widechar }
  51. function is_widechar(def : tdef) : boolean;
  52. {# Returns true if definition is a void}
  53. function is_void(def : tdef) : boolean;
  54. {# Returns true if definition is a smallset}
  55. function is_smallset(p : tdef) : boolean;
  56. {# Returns true, if def defines a signed data type
  57. (only for ordinal types)
  58. }
  59. function is_signed(def : tdef) : boolean;
  60. {# Returns true whether def_from's range is comprised in def_to's if both are
  61. orddefs, false otherwise }
  62. function is_in_limit(def_from,def_to : tdef) : boolean;
  63. function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;
  64. {*****************************************************************************
  65. Array helper functions
  66. *****************************************************************************}
  67. {# Returns true, if p points to a zero based (non special like open or
  68. dynamic array def).
  69. This is mainly used to see if the array
  70. is convertable to a pointer
  71. }
  72. function is_zero_based_array(p : tdef) : boolean;
  73. {# Returns true if p points to an open array definition }
  74. function is_open_array(p : tdef) : boolean;
  75. {# Returns true if p points to a dynamic array definition }
  76. function is_dynamic_array(p : tdef) : boolean;
  77. {# Returns true, if p points to an array of const definition }
  78. function is_array_constructor(p : tdef) : boolean;
  79. {# Returns true, if p points to a variant array }
  80. function is_variant_array(p : tdef) : boolean;
  81. {# Returns true, if p points to an array of const }
  82. function is_array_of_const(p : tdef) : boolean;
  83. {# Returns true, if p points any kind of special array
  84. That is if the array is an open array, a variant
  85. array, an array constants constructor, or an
  86. array of const.
  87. }
  88. function is_special_array(p : tdef) : boolean;
  89. {# Returns true if p is a char array def }
  90. function is_chararray(p : tdef) : boolean;
  91. {# Returns true if p is a wide char array def }
  92. function is_widechararray(p : tdef) : boolean;
  93. {*****************************************************************************
  94. String helper functions
  95. *****************************************************************************}
  96. {# Returns true if p points to an open string type }
  97. function is_open_string(p : tdef) : boolean;
  98. {# Returns true if p is an ansi string type }
  99. function is_ansistring(p : tdef) : boolean;
  100. {# Returns true if p is a long string type }
  101. function is_longstring(p : tdef) : boolean;
  102. {# returns true if p is a wide string type }
  103. function is_widestring(p : tdef) : boolean;
  104. {# Returns true if p is a short string type }
  105. function is_shortstring(p : tdef) : boolean;
  106. {# Returns true if p is a pchar def }
  107. function is_pchar(p : tdef) : boolean;
  108. {# Returns true if p is a pwidechar def }
  109. function is_pwidechar(p : tdef) : boolean;
  110. {# Returns true if p is a voidpointer def }
  111. function is_voidpointer(p : tdef) : boolean;
  112. {# Returns true, if definition is a float }
  113. function is_fpu(def : tdef) : boolean;
  114. {# Returns true, if def is a currency type }
  115. function is_currency(def : tdef) : boolean;
  116. {# Returns true, if def is a single type }
  117. function is_single(def : tdef) : boolean;
  118. {# Returns true, if def is a double type }
  119. function is_double(def : tdef) : boolean;
  120. {# Returns true, if def is an extended type }
  121. function is_extended(def : tdef) : boolean;
  122. {# Returns true, if def is a 64 bit integer type }
  123. function is_64bitint(def : tdef) : boolean;
  124. {# Returns true, if def is a 64 bit type }
  125. function is_64bit(def : tdef) : boolean;
  126. {# If @var(l) isn't in the range of def a range check error (if not explicit) is generated and
  127. the value is placed within the range
  128. }
  129. procedure testrange(def : tdef;var l : tconstexprint;explicit:boolean);
  130. {# Returns the range of def, where @var(l) is the low-range and @var(h) is
  131. the high-range.
  132. }
  133. procedure getrange(def : tdef;var l : TConstExprInt;var h : TConstExprInt);
  134. { some type helper routines for MMX support }
  135. function is_mmx_able_array(p : tdef) : boolean;
  136. {# returns the mmx type }
  137. function mmx_type(p : tdef) : tmmxtype;
  138. {# From a definition return the abstract code generator size enum. It is
  139. to note that the value returned can be @var(OS_NO) }
  140. function def_cgsize(def: tdef): tcgsize;
  141. implementation
  142. uses
  143. globtype,tokens,systems,verbose;
  144. { returns true, if def uses FPU }
  145. function is_fpu(def : tdef) : boolean;
  146. begin
  147. is_fpu:=(def.deftype=floatdef);
  148. end;
  149. { returns true, if def is a currency type }
  150. function is_currency(def : tdef) : boolean;
  151. begin
  152. case s64currencytype.def.deftype of
  153. orddef :
  154. result:=(def.deftype=orddef) and
  155. (torddef(s64currencytype.def).typ=torddef(def).typ);
  156. floatdef :
  157. result:=(def.deftype=floatdef) and
  158. (tfloatdef(s64currencytype.def).typ=tfloatdef(def).typ);
  159. else
  160. internalerror(200304222);
  161. end;
  162. end;
  163. { returns true, if def is a single type }
  164. function is_single(def : tdef) : boolean;
  165. begin
  166. result:=(def.deftype=floatdef) and
  167. (tfloatdef(def).typ=s32real);
  168. end;
  169. { returns true, if def is a double type }
  170. function is_double(def : tdef) : boolean;
  171. begin
  172. result:=(def.deftype=floatdef) and
  173. (tfloatdef(def).typ=s64real);
  174. end;
  175. function is_extended(def : tdef) : boolean;
  176. begin
  177. result:=(def.deftype=floatdef) and
  178. (tfloatdef(def).typ=s80real);
  179. end;
  180. function range_to_basetype(l,h:TConstExprInt):tbasetype;
  181. begin
  182. { prefer signed over unsigned }
  183. if (l>=-128) and (h<=127) then
  184. range_to_basetype:=s8bit
  185. else if (l>=0) and (h<=255) then
  186. range_to_basetype:=u8bit
  187. else if (l>=-32768) and (h<=32767) then
  188. range_to_basetype:=s16bit
  189. else if (l>=0) and (h<=65535) then
  190. range_to_basetype:=u16bit
  191. else if (l>=low(longint)) and (h<=high(longint)) then
  192. range_to_basetype:=s32bit
  193. else if (l>=low(cardinal)) and (h<=high(cardinal)) then
  194. range_to_basetype:=u32bit
  195. else
  196. range_to_basetype:=s64bit;
  197. end;
  198. procedure range_to_type(l,h:TConstExprInt;var tt:ttype);
  199. begin
  200. { prefer signed over unsigned }
  201. if (l>=-128) and (h<=127) then
  202. tt:=s8inttype
  203. else if (l>=0) and (h<=255) then
  204. tt:=u8inttype
  205. else if (l>=-32768) and (h<=32767) then
  206. tt:=s16inttype
  207. else if (l>=0) and (h<=65535) then
  208. tt:=u16inttype
  209. else if (l>=low(longint)) and (h<=high(longint)) then
  210. tt:=s32inttype
  211. else if (l>=low(cardinal)) and (h<=high(cardinal)) then
  212. tt:=u32inttype
  213. else
  214. tt:=s64inttype;
  215. end;
  216. procedure int_to_type(v:TConstExprInt;var tt:ttype);
  217. begin
  218. range_to_type(v,v,tt);
  219. end;
  220. { true if p is an ordinal }
  221. function is_ordinal(def : tdef) : boolean;
  222. var
  223. dt : tbasetype;
  224. begin
  225. case def.deftype of
  226. orddef :
  227. begin
  228. dt:=torddef(def).typ;
  229. is_ordinal:=dt in [uchar,uwidechar,
  230. u8bit,u16bit,u32bit,u64bit,
  231. s8bit,s16bit,s32bit,s64bit,
  232. bool8bit,bool16bit,bool32bit];
  233. end;
  234. enumdef :
  235. is_ordinal:=true;
  236. else
  237. is_ordinal:=false;
  238. end;
  239. end;
  240. { returns the min. value of the type }
  241. function get_min_value(def : tdef) : TConstExprInt;
  242. begin
  243. case def.deftype of
  244. orddef:
  245. get_min_value:=torddef(def).low;
  246. enumdef:
  247. get_min_value:=tenumdef(def).min;
  248. else
  249. get_min_value:=0;
  250. end;
  251. end;
  252. { true if p is an integer }
  253. function is_integer(def : tdef) : boolean;
  254. begin
  255. is_integer:=(def.deftype=orddef) and
  256. (torddef(def).typ in [u8bit,u16bit,u32bit,u64bit,
  257. s8bit,s16bit,s32bit,s64bit]);
  258. end;
  259. { true if p is a 32bit int i.e. dword or longint }
  260. function is_32bitint(def : tdef) : boolean;
  261. begin
  262. is_32bitint:=(def.deftype=orddef) and
  263. (torddef(def).typ in [u32bit,s32bit]);
  264. end;
  265. { true if p is a boolean }
  266. function is_boolean(def : tdef) : boolean;
  267. begin
  268. is_boolean:=(def.deftype=orddef) and
  269. (torddef(def).typ in [bool8bit,bool16bit,bool32bit]);
  270. end;
  271. { true if p is a void }
  272. function is_void(def : tdef) : boolean;
  273. begin
  274. is_void:=(def.deftype=orddef) and
  275. (torddef(def).typ=uvoid);
  276. end;
  277. { true if p is a char }
  278. function is_char(def : tdef) : boolean;
  279. begin
  280. is_char:=(def.deftype=orddef) and
  281. (torddef(def).typ=uchar);
  282. end;
  283. { true if p is a wchar }
  284. function is_widechar(def : tdef) : boolean;
  285. begin
  286. is_widechar:=(def.deftype=orddef) and
  287. (torddef(def).typ=uwidechar);
  288. end;
  289. { true if p is signed (integer) }
  290. function is_signed(def : tdef) : boolean;
  291. var
  292. dt : tbasetype;
  293. begin
  294. case def.deftype of
  295. orddef :
  296. begin
  297. dt:=torddef(def).typ;
  298. is_signed:=(dt in [s8bit,s16bit,s32bit,s64bit,scurrency]);
  299. end;
  300. enumdef :
  301. is_signed:=tenumdef(def).min < 0;
  302. arraydef :
  303. is_signed:=is_signed(tarraydef(def).rangetype.def);
  304. else
  305. is_signed:=false;
  306. end;
  307. end;
  308. function is_in_limit(def_from,def_to : tdef) : boolean;
  309. var
  310. fromqword, toqword: boolean;
  311. begin
  312. if (def_from.deftype <> orddef) or
  313. (def_to.deftype <> orddef) then
  314. begin
  315. is_in_limit := false;
  316. exit;
  317. end;
  318. fromqword := torddef(def_from).typ = u64bit;
  319. toqword := torddef(def_to).typ = u64bit;
  320. is_in_limit:=(toqword and is_signed(def_from)) or
  321. ((not fromqword) and
  322. (torddef(def_from).low>=torddef(def_to).low) and
  323. (torddef(def_from).high<=torddef(def_to).high));
  324. end;
  325. function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;
  326. begin
  327. if (def_from.deftype <> orddef) and
  328. (def_to.deftype <> orddef) then
  329. internalerror(200210062);
  330. if (torddef(def_to).typ = u64bit) then
  331. begin
  332. is_in_limit_value:=((TConstExprUInt(val_from)>=TConstExprUInt(torddef(def_to).low)) and
  333. (TConstExprUInt(val_from)<=TConstExprUInt(torddef(def_to).high)));
  334. end
  335. else
  336. begin;
  337. is_in_limit_value:=((val_from>=torddef(def_to).low) and
  338. (val_from<=torddef(def_to).high));
  339. end;
  340. end;
  341. { true, if p points to an open array def }
  342. function is_open_string(p : tdef) : boolean;
  343. begin
  344. is_open_string:=(p.deftype=stringdef) and
  345. (tstringdef(p).string_typ=st_shortstring) and
  346. (tstringdef(p).len=0);
  347. end;
  348. { true, if p points to a zero based array def }
  349. function is_zero_based_array(p : tdef) : boolean;
  350. begin
  351. is_zero_based_array:=(p.deftype=arraydef) and
  352. (tarraydef(p).lowrange=0) and
  353. not(is_special_array(p));
  354. end;
  355. { true if p points to a dynamic array def }
  356. function is_dynamic_array(p : tdef) : boolean;
  357. begin
  358. is_dynamic_array:=(p.deftype=arraydef) and
  359. tarraydef(p).IsDynamicArray;
  360. end;
  361. { true, if p points to an open array def }
  362. function is_open_array(p : tdef) : boolean;
  363. begin
  364. { check for s32inttype is needed, because for u32bit the high
  365. range is also -1 ! (PFV) }
  366. is_open_array:=(p.deftype=arraydef) and
  367. (tarraydef(p).rangetype.def=s32inttype.def) and
  368. (tarraydef(p).lowrange=0) and
  369. (tarraydef(p).highrange=-1) and
  370. not(tarraydef(p).IsConstructor) and
  371. not(tarraydef(p).IsVariant) and
  372. not(tarraydef(p).IsArrayOfConst) and
  373. not(tarraydef(p).IsDynamicArray);
  374. end;
  375. { true, if p points to an array of const def }
  376. function is_array_constructor(p : tdef) : boolean;
  377. begin
  378. is_array_constructor:=(p.deftype=arraydef) and
  379. (tarraydef(p).IsConstructor);
  380. end;
  381. { true, if p points to a variant array }
  382. function is_variant_array(p : tdef) : boolean;
  383. begin
  384. is_variant_array:=(p.deftype=arraydef) and
  385. (tarraydef(p).IsVariant);
  386. end;
  387. { true, if p points to an array of const }
  388. function is_array_of_const(p : tdef) : boolean;
  389. begin
  390. is_array_of_const:=(p.deftype=arraydef) and
  391. (tarraydef(p).IsArrayOfConst);
  392. end;
  393. { true, if p points to a special array }
  394. function is_special_array(p : tdef) : boolean;
  395. begin
  396. is_special_array:=(p.deftype=arraydef) and
  397. ((tarraydef(p).IsVariant) or
  398. (tarraydef(p).IsArrayOfConst) or
  399. (tarraydef(p).IsConstructor) or
  400. (tarraydef(p).IsDynamicArray) or
  401. is_open_array(p)
  402. );
  403. end;
  404. {$ifdef ansistring_bits}
  405. { true if p is an ansi string def }
  406. function is_ansistring(p : tdef) : boolean;
  407. begin
  408. is_ansistring:=(p.deftype=stringdef) and
  409. (tstringdef(p).string_typ in [st_ansistring16,st_ansistring32,st_ansistring64]);
  410. end;
  411. {$else}
  412. { true if p is an ansi string def }
  413. function is_ansistring(p : tdef) : boolean;
  414. begin
  415. is_ansistring:=(p.deftype=stringdef) and
  416. (tstringdef(p).string_typ=st_ansistring);
  417. end;
  418. {$endif}
  419. { true if p is an long string def }
  420. function is_longstring(p : tdef) : boolean;
  421. begin
  422. is_longstring:=(p.deftype=stringdef) and
  423. (tstringdef(p).string_typ=st_longstring);
  424. end;
  425. { true if p is an wide string def }
  426. function is_widestring(p : tdef) : boolean;
  427. begin
  428. is_widestring:=(p.deftype=stringdef) and
  429. (tstringdef(p).string_typ=st_widestring);
  430. end;
  431. { true if p is an short string def }
  432. function is_shortstring(p : tdef) : boolean;
  433. begin
  434. is_shortstring:=(p.deftype=stringdef) and
  435. (tstringdef(p).string_typ=st_shortstring);
  436. end;
  437. { true if p is a char array def }
  438. function is_chararray(p : tdef) : boolean;
  439. begin
  440. is_chararray:=(p.deftype=arraydef) and
  441. is_char(tarraydef(p).elementtype.def) and
  442. not(is_special_array(p));
  443. end;
  444. { true if p is a widechar array def }
  445. function is_widechararray(p : tdef) : boolean;
  446. begin
  447. is_widechararray:=(p.deftype=arraydef) and
  448. is_widechar(tarraydef(p).elementtype.def) and
  449. not(is_special_array(p));
  450. end;
  451. { true if p is a pchar def }
  452. function is_pchar(p : tdef) : boolean;
  453. begin
  454. is_pchar:=(p.deftype=pointerdef) and
  455. (is_char(tpointerdef(p).pointertype.def) or
  456. (is_zero_based_array(tpointerdef(p).pointertype.def) and
  457. is_chararray(tpointerdef(p).pointertype.def)));
  458. end;
  459. { true if p is a pchar def }
  460. function is_pwidechar(p : tdef) : boolean;
  461. begin
  462. is_pwidechar:=(p.deftype=pointerdef) and
  463. (is_widechar(tpointerdef(p).pointertype.def) or
  464. (is_zero_based_array(tpointerdef(p).pointertype.def) and
  465. is_widechararray(tpointerdef(p).pointertype.def)));
  466. end;
  467. { true if p is a voidpointer def }
  468. function is_voidpointer(p : tdef) : boolean;
  469. begin
  470. is_voidpointer:=(p.deftype=pointerdef) and
  471. (tpointerdef(p).pointertype.def.deftype=orddef) and
  472. (torddef(tpointerdef(p).pointertype.def).typ=uvoid);
  473. end;
  474. { true if p is a smallset def }
  475. function is_smallset(p : tdef) : boolean;
  476. begin
  477. is_smallset:=(p.deftype=setdef) and
  478. (tsetdef(p).settype=smallset);
  479. end;
  480. { true, if def is a 64 bit int type }
  481. function is_64bitint(def : tdef) : boolean;
  482. begin
  483. is_64bitint:=(def.deftype=orddef) and (torddef(def).typ in [u64bit,s64bit])
  484. end;
  485. { true, if def is a 64 bit type }
  486. function is_64bit(def : tdef) : boolean;
  487. begin
  488. is_64bit:=(def.deftype=orddef) and (torddef(def).typ in [u64bit,s64bit,scurrency])
  489. end;
  490. { if l isn't in the range of def a range check error (if not explicit) is generated and
  491. the value is placed within the range }
  492. procedure testrange(def : tdef;var l : tconstexprint;explicit:boolean);
  493. var
  494. lv,hv: TConstExprInt;
  495. error: boolean;
  496. begin
  497. error := false;
  498. { for 64 bit types we need only to check if it is less than }
  499. { zero, if def is a qword node }
  500. if is_64bitint(def) then
  501. begin
  502. if (l<0) and (torddef(def).typ=u64bit) then
  503. begin
  504. { don't zero the result, because it may come from hex notation
  505. like $ffffffffffffffff! (JM)
  506. l:=0; }
  507. if not explicit then
  508. begin
  509. if (cs_check_range in aktlocalswitches) then
  510. Message(parser_e_range_check_error)
  511. else
  512. Message(parser_w_range_check_error);
  513. end;
  514. error := true;
  515. end;
  516. end
  517. else
  518. begin
  519. getrange(def,lv,hv);
  520. if (def.deftype=orddef) and
  521. (torddef(def).typ=u32bit) then
  522. begin
  523. if (l < cardinal(lv)) or
  524. (l > cardinal(hv)) then
  525. begin
  526. if not explicit then
  527. begin
  528. if (cs_check_range in aktlocalswitches) then
  529. Message(parser_e_range_check_error)
  530. else
  531. Message(parser_w_range_check_error);
  532. end;
  533. error := true;
  534. end;
  535. end
  536. else if (l<lv) or (l>hv) then
  537. begin
  538. if not explicit then
  539. begin
  540. if ((def.deftype=enumdef) and
  541. { delphi allows range check errors in
  542. enumeration type casts FK }
  543. not(m_delphi in aktmodeswitches)) or
  544. (cs_check_range in aktlocalswitches) then
  545. Message(parser_e_range_check_error)
  546. else
  547. Message(parser_w_range_check_error);
  548. end;
  549. error := true;
  550. end;
  551. end;
  552. if error then
  553. begin
  554. { Fix the value to fit in the allocated space for this type of variable }
  555. case def.size of
  556. 1: l := l and $ff;
  557. 2: l := l and $ffff;
  558. { work around sign extension bug (to be fixed) (JM) }
  559. 4: l := l and (int64($fffffff) shl 4 + $f);
  560. end;
  561. { do sign extension if necessary (JM) }
  562. if is_signed(def) then
  563. begin
  564. case def.size of
  565. 1: l := shortint(l);
  566. 2: l := smallint(l);
  567. 4: l := longint(l);
  568. end;
  569. end;
  570. end;
  571. end;
  572. { return the range from def in l and h }
  573. procedure getrange(def : tdef;var l : TConstExprInt;var h : TConstExprInt);
  574. begin
  575. case def.deftype of
  576. orddef :
  577. begin
  578. l:=torddef(def).low;
  579. h:=torddef(def).high;
  580. end;
  581. enumdef :
  582. begin
  583. l:=tenumdef(def).min;
  584. h:=tenumdef(def).max;
  585. end;
  586. arraydef :
  587. begin
  588. l:=tarraydef(def).lowrange;
  589. h:=tarraydef(def).highrange;
  590. end;
  591. else
  592. internalerror(987);
  593. end;
  594. end;
  595. function mmx_type(p : tdef) : tmmxtype;
  596. begin
  597. mmx_type:=mmxno;
  598. if is_mmx_able_array(p) then
  599. begin
  600. if tarraydef(p).elementtype.def.deftype=floatdef then
  601. case tfloatdef(tarraydef(p).elementtype.def).typ of
  602. s32real:
  603. mmx_type:=mmxsingle;
  604. end
  605. else
  606. case torddef(tarraydef(p).elementtype.def).typ of
  607. u8bit:
  608. mmx_type:=mmxu8bit;
  609. s8bit:
  610. mmx_type:=mmxs8bit;
  611. u16bit:
  612. mmx_type:=mmxu16bit;
  613. s16bit:
  614. mmx_type:=mmxs16bit;
  615. u32bit:
  616. mmx_type:=mmxu32bit;
  617. s32bit:
  618. mmx_type:=mmxs32bit;
  619. end;
  620. end;
  621. end;
  622. function is_mmx_able_array(p : tdef) : boolean;
  623. begin
  624. {$ifdef SUPPORT_MMX}
  625. if (cs_mmx_saturation in aktlocalswitches) then
  626. begin
  627. is_mmx_able_array:=(p.deftype=arraydef) and
  628. not(is_special_array(p)) and
  629. (
  630. (
  631. (tarraydef(p).elementtype.def.deftype=orddef) and
  632. (
  633. (
  634. (tarraydef(p).lowrange=0) and
  635. (tarraydef(p).highrange=1) and
  636. (torddef(tarraydef(p).elementtype.def).typ in [u32bit,s32bit])
  637. )
  638. or
  639. (
  640. (tarraydef(p).lowrange=0) and
  641. (tarraydef(p).highrange=3) and
  642. (torddef(tarraydef(p).elementtype.def).typ in [u16bit,s16bit])
  643. )
  644. )
  645. )
  646. or
  647. (
  648. (
  649. (tarraydef(p).elementtype.def.deftype=floatdef) and
  650. (
  651. (tarraydef(p).lowrange=0) and
  652. (tarraydef(p).highrange=1) and
  653. (tfloatdef(tarraydef(p).elementtype.def).typ=s32real)
  654. )
  655. )
  656. )
  657. );
  658. end
  659. else
  660. begin
  661. is_mmx_able_array:=(p.deftype=arraydef) and
  662. (
  663. (
  664. (tarraydef(p).elementtype.def.deftype=orddef) and
  665. (
  666. (
  667. (tarraydef(p).lowrange=0) and
  668. (tarraydef(p).highrange=1) and
  669. (torddef(tarraydef(p).elementtype.def).typ in [u32bit,s32bit])
  670. )
  671. or
  672. (
  673. (tarraydef(p).lowrange=0) and
  674. (tarraydef(p).highrange=3) and
  675. (torddef(tarraydef(p).elementtype.def).typ in [u16bit,s16bit])
  676. )
  677. or
  678. (
  679. (tarraydef(p).lowrange=0) and
  680. (tarraydef(p).highrange=7) and
  681. (torddef(tarraydef(p).elementtype.def).typ in [u8bit,s8bit])
  682. )
  683. )
  684. )
  685. or
  686. (
  687. (tarraydef(p).elementtype.def.deftype=floatdef) and
  688. (
  689. (tarraydef(p).lowrange=0) and
  690. (tarraydef(p).highrange=1) and
  691. (tfloatdef(tarraydef(p).elementtype.def).typ=s32real)
  692. )
  693. )
  694. );
  695. end;
  696. {$else SUPPORT_MMX}
  697. is_mmx_able_array:=false;
  698. {$endif SUPPORT_MMX}
  699. end;
  700. function def_cgsize(def: tdef): tcgsize;
  701. begin
  702. case def.deftype of
  703. orddef,
  704. enumdef,
  705. setdef:
  706. begin
  707. result := int_cgsize(def.size);
  708. if is_signed(def) then
  709. result := tcgsize(ord(result)+(ord(OS_S8)-ord(OS_8)));
  710. end;
  711. classrefdef,
  712. pointerdef:
  713. result := OS_ADDR;
  714. procvardef:
  715. begin
  716. if tprocvardef(def).is_methodpointer and
  717. (not tprocvardef(def).is_addressonly) then
  718. result := OS_64
  719. else
  720. result := OS_ADDR;
  721. end;
  722. stringdef :
  723. begin
  724. if is_ansistring(def) or is_widestring(def) then
  725. result := OS_ADDR
  726. else
  727. result := OS_NO;
  728. end;
  729. objectdef :
  730. begin
  731. if is_class_or_interface(def) then
  732. result := OS_ADDR
  733. else
  734. result := OS_NO;
  735. end;
  736. floatdef:
  737. result := tfloat2tcgsize[tfloatdef(def).typ];
  738. recorddef :
  739. result:=int_cgsize(def.size);
  740. arraydef :
  741. begin
  742. if not is_special_array(def) then
  743. result := int_cgsize(def.size)
  744. else
  745. begin
  746. if is_dynamic_array(def) then
  747. result := OS_ADDR
  748. else
  749. result := OS_NO;
  750. end;
  751. end;
  752. else
  753. begin
  754. { undefined size }
  755. result:=OS_NO;
  756. end;
  757. end;
  758. end;
  759. end.
  760. {
  761. $Log$
  762. Revision 1.15 2004-05-28 21:13:23 peter
  763. * prefer signed constants over unsigned
  764. Revision 1.14 2004/05/01 22:05:01 florian
  765. + added lib support for Amiga/MorphOS syscalls
  766. Revision 1.13 2004/04/29 19:56:36 daniel
  767. * Prepare compiler infrastructure for multiple ansistring types
  768. Revision 1.12 2004/03/29 14:44:10 peter
  769. * fixes to previous constant integer commit
  770. Revision 1.11 2004/03/23 22:34:49 peter
  771. * constants ordinals now always have a type assigned
  772. * integer constants have the smallest type, unsigned prefered over
  773. signed
  774. Revision 1.10 2004/02/04 22:01:13 peter
  775. * first try to get cpupara working for x86_64
  776. Revision 1.9 2004/02/03 22:32:53 peter
  777. * renamed xNNbittype to xNNinttype
  778. * renamed registers32 to registersint
  779. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  780. Revision 1.8 2003/12/25 01:07:09 florian
  781. + $fputype directive support
  782. + single data type operations with sse unit
  783. * fixed more x86-64 stuff
  784. Revision 1.7 2003/11/10 18:05:16 florian
  785. + is_single added
  786. Revision 1.6 2003/10/01 20:34:48 peter
  787. * procinfo unit contains tprocinfo
  788. * cginfo renamed to cgbase
  789. * moved cgmessage to verbose
  790. * fixed ppc and sparc compiles
  791. Revision 1.5 2003/04/25 20:59:33 peter
  792. * removed funcretn,funcretsym, function result is now in varsym
  793. and aliases for result and function name are added using absolutesym
  794. * vs_hidden parameter for funcret passed in parameter
  795. * vs_hidden fixes
  796. * writenode changed to printnode and released from extdebug
  797. * -vp option added to generate a tree.log with the nodetree
  798. * nicer printnode for statements, callnode
  799. Revision 1.4 2003/04/23 20:16:04 peter
  800. + added currency support based on int64
  801. + is_64bit for use in cg units instead of is_64bitint
  802. * removed cgmessage from n386add, replace with internalerrors
  803. Revision 1.3 2003/03/17 19:05:08 peter
  804. * dynamic array is also a special array
  805. Revision 1.2 2002/12/23 20:58:03 peter
  806. * remove unused global var
  807. Revision 1.1 2002/11/25 17:43:17 peter
  808. * splitted defbase in defutil,symutil,defcmp
  809. * merged isconvertable and is_equal into compare_defs(_ext)
  810. * made operator search faster by walking the list only once
  811. Revision 1.26 2002/11/17 16:31:55 carl
  812. * memory optimization (3-4%) : cleanup of tai fields,
  813. cleanup of tdef and tsym fields.
  814. * make it work for m68k
  815. Revision 1.25 2002/11/16 18:00:53 peter
  816. * fix merged proc-procvar check
  817. Revision 1.24 2002/11/15 01:58:46 peter
  818. * merged changes from 1.0.7 up to 04-11
  819. - -V option for generating bug report tracing
  820. - more tracing for option parsing
  821. - errors for cdecl and high()
  822. - win32 import stabs
  823. - win32 records<=8 are returned in eax:edx (turned off by default)
  824. - heaptrc update
  825. - more info for temp management in .s file with EXTDEBUG
  826. Revision 1.23 2002/10/20 15:34:16 peter
  827. * removed df_unique flag. It breaks code. For a good type=type <id>
  828. a def copy is required
  829. Revision 1.22 2002/10/10 16:07:57 florian
  830. + several widestring/pwidechar related stuff added
  831. Revision 1.21 2002/10/09 21:01:41 florian
  832. * variants aren't compatible with nil
  833. Revision 1.20 2002/10/07 09:49:42 florian
  834. * overloaded :=-operator is now searched when looking for possible
  835. variant type conversions
  836. Revision 1.19 2002/10/06 21:02:17 peter
  837. * fixed limit checking for qword
  838. Revision 1.18 2002/10/06 15:08:59 peter
  839. * only check for forwarddefs the definitions that really belong to
  840. the current procsym
  841. Revision 1.17 2002/10/06 12:25:04 florian
  842. + proper support of type <id> = type <another id>;
  843. Revision 1.16 2002/10/05 12:43:24 carl
  844. * fixes for Delphi 6 compilation
  845. (warning : Some features do not work under Delphi)
  846. Revision 1.15 2002/10/05 00:50:01 peter
  847. * check parameters from left to right in equal_paras, so default
  848. parameters are checked at the end
  849. Revision 1.14 2002/09/30 07:00:44 florian
  850. * fixes to common code to get the alpha compiler compiled applied
  851. Revision 1.13 2002/09/22 14:02:34 carl
  852. * stack checking cannot be called before system unit is initialized
  853. * MC68020 define
  854. Revision 1.12 2002/09/16 14:11:12 peter
  855. * add argument to equal_paras() to support default values or not
  856. Revision 1.11 2002/09/15 17:54:46 peter
  857. * allow default parameters in equal_paras
  858. Revision 1.10 2002/09/08 11:10:17 carl
  859. * bugfix 2109 (bad imho, but only way)
  860. Revision 1.9 2002/09/07 15:25:02 peter
  861. * old logs removed and tabs fixed
  862. Revision 1.8 2002/09/07 09:16:55 carl
  863. * fix my stupid copy and paste bug
  864. Revision 1.7 2002/09/06 19:58:31 carl
  865. * start bugfix 1996
  866. * 64-bit typed constant now work correctly and fully (bugfix 2001)
  867. Revision 1.6 2002/08/20 10:31:26 daniel
  868. * Tcallnode.det_resulttype rewritten
  869. Revision 1.5 2002/08/12 20:39:17 florian
  870. * casting of classes to interface fixed when the interface was
  871. implemented by a parent class
  872. Revision 1.4 2002/08/12 14:17:56 florian
  873. * nil is now recognized as being compatible with a dynamic array
  874. Revision 1.3 2002/08/05 18:27:48 carl
  875. + more more more documentation
  876. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  877. Revision 1.2 2002/07/23 09:51:22 daniel
  878. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  879. are worth comitting.
  880. Revision 1.1 2002/07/20 11:57:53 florian
  881. * types.pas renamed to defbase.pas because D6 contains a types
  882. unit so this would conflicts if D6 programms are compiled
  883. + Willamette/SSE2 instructions to assembler added
  884. Revision 1.75 2002/07/11 14:41:32 florian
  885. * start of the new generic parameter handling
  886. Revision 1.74 2002/07/01 16:23:54 peter
  887. * cg64 patch
  888. * basics for currency
  889. * asnode updates for class and interface (not finished)
  890. Revision 1.73 2002/05/18 13:34:21 peter
  891. * readded missing revisions
  892. Revision 1.72 2002/05/16 19:46:47 carl
  893. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  894. + try to fix temp allocation (still in ifdef)
  895. + generic constructor calls
  896. + start of tassembler / tmodulebase class cleanup
  897. Revision 1.70 2002/05/12 16:53:16 peter
  898. * moved entry and exitcode to ncgutil and cgobj
  899. * foreach gets extra argument for passing local data to the
  900. iterator function
  901. * -CR checks also class typecasts at runtime by changing them
  902. into as
  903. * fixed compiler to cycle with the -CR option
  904. * fixed stabs with elf writer, finally the global variables can
  905. be watched
  906. * removed a lot of routines from cga unit and replaced them by
  907. calls to cgobj
  908. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  909. u32bit then the other is typecasted also to u32bit without giving
  910. a rangecheck warning/error.
  911. * fixed pascal calling method with reversing also the high tree in
  912. the parast, detected by tcalcst3 test
  913. Revision 1.69 2002/04/25 20:16:39 peter
  914. * moved more routines from cga/n386util
  915. Revision 1.68 2002/04/15 19:08:22 carl
  916. + target_info.size_of_pointer -> pointer_size
  917. + some cleanup of unused types/variables
  918. Revision 1.67 2002/04/07 13:40:29 carl
  919. + update documentation
  920. Revision 1.66 2002/04/02 17:11:32 peter
  921. * tlocation,treference update
  922. * LOC_CONSTANT added for better constant handling
  923. * secondadd splitted in multiple routines
  924. * location_force_reg added for loading a location to a register
  925. of a specified size
  926. * secondassignment parses now first the right and then the left node
  927. (this is compatible with Kylix). This saves a lot of push/pop especially
  928. with string operations
  929. * adapted some routines to use the new cg methods
  930. Revision 1.65 2002/04/01 20:57:14 jonas
  931. * fixed web bug 1907
  932. * fixed some other procvar related bugs (all related to accepting procvar
  933. constructs with either too many or too little parameters)
  934. (both merged, includes second typo fix of pexpr.pas)
  935. Revision 1.64 2002/01/24 18:25:53 peter
  936. * implicit result variable generation for assembler routines
  937. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  938. Revision 1.63 2002/01/24 12:33:53 jonas
  939. * adapted ranges of native types to int64 (e.g. high cardinal is no
  940. longer longint($ffffffff), but just $fffffff in psystem)
  941. * small additional fix in 64bit rangecheck code generation for 32 bit
  942. processors
  943. * adaption of ranges required the matching talgorithm used for selecting
  944. which overloaded procedure to call to be adapted. It should now always
  945. select the closest match for ordinal parameters.
  946. + inttostr(qword) in sysstr.inc/sysstrh.inc
  947. + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
  948. fixes were required to be able to add them)
  949. * is_in_limit() moved from ncal to types unit, should always be used
  950. instead of direct comparisons of low/high values of orddefs because
  951. qword is a special case
  952. }