defutil.pas 38 KB

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