defutil.pas 34 KB

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