htypechk.pas 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 by Florian Klaempfl
  4. This unit exports some help routines for the type checking
  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 htypechk;
  19. interface
  20. uses
  21. tree,symtable;
  22. const
  23. { firstcallparan without varspez we don't count the ref }
  24. count_ref : boolean = true;
  25. allow_array_constructor : boolean = false;
  26. { Conversion }
  27. function isconvertable(def_from,def_to : pdef;
  28. var doconv : tconverttype;fromtreetype : ttreetyp;
  29. explicit : boolean) : boolean;
  30. { Register Allocation }
  31. procedure make_not_regable(p : ptree);
  32. procedure left_right_max(p : ptree);
  33. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  34. { subroutine handling }
  35. procedure test_protected_sym(sym : psym);
  36. procedure test_protected(p : ptree);
  37. function is_procsym_load(p:Ptree):boolean;
  38. function is_procsym_call(p:Ptree):boolean;
  39. function is_assignment_overloaded(from_def,to_def : pdef) : boolean;
  40. implementation
  41. uses
  42. globtype,systems,tokens,
  43. cobjects,verbose,globals,
  44. aasm,types,
  45. hcodegen;
  46. {****************************************************************************
  47. Convert
  48. ****************************************************************************}
  49. function isconvertable(def_from,def_to : pdef;
  50. var doconv : tconverttype;fromtreetype : ttreetyp;
  51. explicit : boolean) : boolean;
  52. {$ifndef OLDCNV}
  53. { Tbasetype: uauto,uvoid,uchar,
  54. u8bit,u16bit,u32bit,
  55. s8bit,s16bit,s32,
  56. bool8bit,bool16bit,bool32bit,
  57. u64bit,s64bitint }
  58. type
  59. tbasedef=(bvoid,bchar,bint,bbool);
  60. const
  61. basedeftbl:array[tbasetype] of tbasedef =
  62. (bvoid,bvoid,bchar,
  63. bint,bint,bint,
  64. bint,bint,bint,
  65. bbool,bbool,bbool,bint,bint);
  66. basedefconverts : array[tbasedef,tbasedef] of tconverttype =
  67. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  68. (tc_not_possible,tc_equal,tc_not_possible,tc_not_possible),
  69. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_int_2_bool),
  70. (tc_not_possible,tc_not_possible,tc_bool_2_int,tc_int_2_bool));
  71. {$else}
  72. const
  73. basedefconverts : array[tbasetype,tbasetype] of tconverttype =
  74. {uauto}
  75. ((tc_not_possible,tc_not_possible,tc_not_possible,
  76. tc_not_possible,tc_not_possible,tc_not_possible,
  77. tc_not_possible,tc_not_possible,tc_not_possible,
  78. tc_not_possible,tc_not_possible,tc_not_possible),
  79. {uvoid}
  80. (tc_not_possible,tc_not_possible,tc_not_possible,
  81. tc_not_possible,tc_not_possible,tc_not_possible,
  82. tc_not_possible,tc_not_possible,tc_not_possible,
  83. tc_not_possible,tc_not_possible,tc_not_possible),
  84. {uchar}
  85. (tc_not_possible,tc_not_possible,tc_only_rangechecks32bit,
  86. tc_not_possible,tc_not_possible,tc_not_possible,
  87. tc_not_possible,tc_not_possible,tc_not_possible,
  88. tc_not_possible,tc_not_possible,tc_not_possible),
  89. {u8bit}
  90. (tc_not_possible,tc_not_possible,tc_not_possible,
  91. tc_only_rangechecks32bit,tc_u8bit_2_u16bit,tc_u8bit_2_u32bit,
  92. tc_only_rangechecks32bit,tc_u8bit_2_s16bit,tc_u8bit_2_s32bit,
  93. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  94. {u16bit}
  95. (tc_not_possible,tc_not_possible,tc_not_possible,
  96. tc_u16bit_2_u8bit,tc_only_rangechecks32bit,tc_u16bit_2_u32bit,
  97. tc_u16bit_2_s8bit,tc_only_rangechecks32bit,tc_u16bit_2_s32bit,
  98. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  99. {u32bit}
  100. (tc_not_possible,tc_not_possible,tc_not_possible,
  101. tc_u32bit_2_u8bit,tc_u32bit_2_u16bit,tc_only_rangechecks32bit,
  102. tc_u32bit_2_s8bit,tc_u32bit_2_s16bit,tc_only_rangechecks32bit,
  103. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  104. {s8bit}
  105. (tc_not_possible,tc_not_possible,tc_not_possible,
  106. tc_only_rangechecks32bit,tc_s8bit_2_u16bit,tc_s8bit_2_u32bit,
  107. tc_only_rangechecks32bit,tc_s8bit_2_s16bit,tc_s8bit_2_s32bit,
  108. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  109. {s16bit}
  110. (tc_not_possible,tc_not_possible,tc_not_possible,
  111. tc_s16bit_2_u8bit,tc_only_rangechecks32bit,tc_s16bit_2_u32bit,
  112. tc_s16bit_2_s8bit,tc_only_rangechecks32bit,tc_s16bit_2_s32bit,
  113. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  114. {s32bit}
  115. (tc_not_possible,tc_not_possible,tc_not_possible,
  116. tc_s32bit_2_u8bit,tc_s32bit_2_u16bit,tc_only_rangechecks32bit,
  117. tc_s32bit_2_s8bit,tc_s32bit_2_s16bit,tc_only_rangechecks32bit,
  118. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  119. {bool8bit}
  120. (tc_not_possible,tc_not_possible,tc_not_possible,
  121. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  122. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  123. tc_only_rangechecks32bit,tc_int_2_bool,tc_int_2_bool),
  124. {bool16bit}
  125. (tc_not_possible,tc_not_possible,tc_not_possible,
  126. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  127. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  128. tc_int_2_bool,tc_only_rangechecks32bit,tc_int_2_bool),
  129. {bool32bit}
  130. (tc_not_possible,tc_not_possible,tc_not_possible,
  131. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  132. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  133. tc_int_2_bool,tc_int_2_bool,tc_only_rangechecks32bit));
  134. {$endif}
  135. var
  136. b : boolean;
  137. hd1,hd2 : pdef;
  138. begin
  139. { safety check }
  140. if not(assigned(def_from) and assigned(def_to)) then
  141. begin
  142. isconvertable:=false;
  143. exit;
  144. end;
  145. b:=false;
  146. { we walk the wanted (def_to) types and check then the def_from
  147. types if there is a conversion possible }
  148. case def_to^.deftype of
  149. orddef :
  150. begin
  151. case def_from^.deftype of
  152. orddef :
  153. begin
  154. {$ifndef OLDCNV}
  155. doconv:=basedefconverts[basedeftbl[porddef(def_from)^.typ],basedeftbl[porddef(def_to)^.typ]];
  156. b:=true;
  157. if (doconv=tc_not_possible) or
  158. ((doconv=tc_int_2_bool) and
  159. (not explicit) and
  160. (not is_boolean(def_from))) then
  161. b:=false;
  162. {$else}
  163. doconv:=basedefconverts[porddef(def_from)^.typ,porddef(def_to)^.typ];
  164. b:=true;
  165. if (doconv=tc_not_possible) or
  166. ((doconv=tc_int_2_bool) and
  167. (not explicit) and
  168. (not is_boolean(def_from))) then
  169. b:=false;
  170. {$endif}
  171. end;
  172. {$ifndef OLDCNV}
  173. enumdef :
  174. begin
  175. doconv:=tc_int_2_int;
  176. b:=true;
  177. end;
  178. {$endif}
  179. end;
  180. end;
  181. stringdef :
  182. begin
  183. case def_from^.deftype of
  184. stringdef : begin
  185. doconv:=tc_string_2_string;
  186. b:=true;
  187. end;
  188. orddef : begin
  189. { char to string}
  190. if is_char(def_from) then
  191. begin
  192. doconv:=tc_char_2_string;
  193. b:=true;
  194. end;
  195. end;
  196. arraydef : begin
  197. { string to array of char, the length check is done by the firstpass of this node }
  198. if is_equal(parraydef(def_from)^.definition,cchardef) then
  199. begin
  200. doconv:=tc_chararray_2_string;
  201. b:=true;
  202. end;
  203. end;
  204. pointerdef : begin
  205. { pchar can be assigned to short/ansistrings }
  206. if is_pchar(def_from) and not(m_tp in aktmodeswitches) then
  207. begin
  208. doconv:=tc_pchar_2_string;
  209. b:=true;
  210. end;
  211. end;
  212. end;
  213. end;
  214. floatdef :
  215. begin
  216. case def_from^.deftype of
  217. orddef : begin { ordinal to real }
  218. if pfloatdef(def_to)^.typ=f32bit then
  219. doconv:=tc_int_2_fix
  220. else
  221. doconv:=tc_int_2_real;
  222. b:=true;
  223. end;
  224. floatdef : begin { 2 float types ? }
  225. if pfloatdef(def_from)^.typ=pfloatdef(def_to)^.typ then
  226. doconv:=tc_equal
  227. else
  228. begin
  229. if pfloatdef(def_from)^.typ=f32bit then
  230. doconv:=tc_fix_2_real
  231. else
  232. if pfloatdef(def_to)^.typ=f32bit then
  233. doconv:=tc_real_2_fix
  234. else
  235. doconv:=tc_real_2_real;
  236. { comp isn't a floating type }
  237. {$ifdef i386}
  238. if (pfloatdef(def_to)^.typ=s64bit) and
  239. (pfloatdef(def_from)^.typ<>s64bit) and
  240. not (explicit) then
  241. CGMessage(type_w_convert_real_2_comp);
  242. {$endif}
  243. end;
  244. b:=true;
  245. end;
  246. end;
  247. end;
  248. enumdef :
  249. begin
  250. if (def_from^.deftype=enumdef) then
  251. begin
  252. if assigned(penumdef(def_from)^.basedef) then
  253. hd1:=penumdef(def_from)^.basedef
  254. else
  255. hd1:=def_from;
  256. if assigned(penumdef(def_to)^.basedef) then
  257. hd2:=penumdef(def_to)^.basedef
  258. else
  259. hd2:=def_to;
  260. b:=(hd1=hd2);
  261. end;
  262. end;
  263. arraydef :
  264. begin
  265. { open array is also compatible with a single element of its base type }
  266. if is_open_array(def_to) and
  267. is_equal(parraydef(def_to)^.definition,def_from) then
  268. begin
  269. doconv:=tc_equal;
  270. b:=true;
  271. end
  272. else
  273. begin
  274. case def_from^.deftype of
  275. pointerdef : begin
  276. if (parraydef(def_to)^.lowrange=0) and
  277. is_equal(ppointerdef(def_from)^.definition,parraydef(def_to)^.definition) then
  278. begin
  279. doconv:=tc_pointer_2_array;
  280. b:=true;
  281. end;
  282. end;
  283. stringdef : begin
  284. { array of char to string }
  285. if is_equal(parraydef(def_to)^.definition,cchardef) then
  286. begin
  287. doconv:=tc_string_2_chararray;
  288. b:=true;
  289. end;
  290. end;
  291. end;
  292. end;
  293. end;
  294. pointerdef :
  295. begin
  296. case def_from^.deftype of
  297. stringdef : begin
  298. { string constant to zero terminated string constant }
  299. if (fromtreetype=stringconstn) and
  300. is_pchar(def_to) then
  301. begin
  302. doconv:=tc_cstring_2_pchar;
  303. b:=true;
  304. end;
  305. end;
  306. orddef : begin
  307. { char constant to zero terminated string constant }
  308. if (fromtreetype=ordconstn) and is_equal(def_from,cchardef) and
  309. is_pchar(def_to) then
  310. begin
  311. doconv:=tc_cchar_2_pchar;
  312. b:=true;
  313. end;
  314. end;
  315. arraydef : begin
  316. { chararray to pointer }
  317. if (parraydef(def_from)^.lowrange=0) and
  318. is_equal(parraydef(def_from)^.definition,ppointerdef(def_to)^.definition) then
  319. begin
  320. doconv:=tc_array_2_pointer;
  321. b:=true;
  322. end;
  323. end;
  324. pointerdef : begin
  325. { child class pointer can be assigned to anchestor pointers }
  326. if (
  327. (ppointerdef(def_from)^.definition^.deftype=objectdef) and
  328. (ppointerdef(def_to)^.definition^.deftype=objectdef) and
  329. pobjectdef(ppointerdef(def_from)^.definition)^.isrelated(
  330. pobjectdef(ppointerdef(def_to)^.definition))
  331. ) or
  332. { all pointers can be assigned to void-pointer }
  333. is_equal(ppointerdef(def_to)^.definition,voiddef) or
  334. { in my opnion, is this not clean pascal }
  335. { well, but it's handy to use, it isn't ? (FK) }
  336. is_equal(ppointerdef(def_from)^.definition,voiddef) then
  337. begin
  338. doconv:=tc_equal;
  339. b:=true;
  340. end;
  341. end;
  342. procvardef : begin
  343. { procedure variable can be assigned to an void pointer }
  344. { Not anymore. Use the @ operator now.}
  345. if not(m_tp_procvar in aktmodeswitches) and
  346. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  347. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  348. begin
  349. doconv:=tc_equal;
  350. b:=true;
  351. end;
  352. end;
  353. classrefdef,
  354. objectdef : begin
  355. { class types and class reference type
  356. can be assigned to void pointers }
  357. if (
  358. ((def_from^.deftype=objectdef) and pobjectdef(def_from)^.isclass) or
  359. (def_from^.deftype=classrefdef)
  360. ) and
  361. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  362. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  363. begin
  364. doconv:=tc_equal;
  365. b:=true;
  366. end;
  367. end;
  368. end;
  369. end;
  370. setdef :
  371. begin
  372. { automatic arrayconstructor -> set conversion }
  373. if (def_from^.deftype=arraydef) and (parraydef(def_from)^.IsConstructor) then
  374. begin
  375. doconv:=tc_arrayconstructor_2_set;
  376. b:=true;
  377. end;
  378. end;
  379. procvardef :
  380. begin
  381. { proc -> procvar }
  382. if (def_from^.deftype=procdef) then
  383. begin
  384. def_from^.deftype:=procvardef;
  385. doconv:=tc_proc_2_procvar;
  386. b:=is_equal(def_from,def_to);
  387. def_from^.deftype:=procdef;
  388. end
  389. else
  390. { for example delphi allows the assignement from pointers }
  391. { to procedure variables }
  392. if (m_pointer_2_procedure in aktmodeswitches) and
  393. (def_from^.deftype=pointerdef) and
  394. (ppointerdef(def_from)^.definition^.deftype=orddef) and
  395. (porddef(ppointerdef(def_from)^.definition)^.typ=uvoid) then
  396. begin
  397. doconv:=tc_equal;
  398. b:=true;
  399. end
  400. else
  401. { nil is compatible with procvars }
  402. if (fromtreetype=niln) then
  403. begin
  404. doconv:=tc_equal;
  405. b:=true;
  406. end;
  407. end;
  408. objectdef :
  409. begin
  410. { object pascal objects }
  411. if (def_from^.deftype=objectdef) {and
  412. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  413. begin
  414. doconv:=tc_equal;
  415. b:=pobjectdef(def_from)^.isrelated(pobjectdef(def_to));
  416. end
  417. else
  418. { nil is compatible with class instances }
  419. if (fromtreetype=niln) and (pobjectdef(def_to)^.isclass) then
  420. begin
  421. doconv:=tc_equal;
  422. b:=true;
  423. end;
  424. end;
  425. classrefdef :
  426. begin
  427. { class reference types }
  428. if (def_from^.deftype=classrefdef) then
  429. begin
  430. doconv:=tc_equal;
  431. b:=pobjectdef(pclassrefdef(def_from)^.definition)^.isrelated(
  432. pobjectdef(pclassrefdef(def_to)^.definition));
  433. end
  434. else
  435. { nil is compatible with class references }
  436. if (fromtreetype=niln) then
  437. begin
  438. doconv:=tc_equal;
  439. b:=true;
  440. end;
  441. end;
  442. filedef :
  443. begin
  444. { typed files are all equal to the abstract file type
  445. name TYPEDFILE in system.pp in is_equal in types.pas
  446. the problem is that it sholud be also compatible to FILE
  447. but this would leed to a problem for ASSIGN RESET and REWRITE
  448. when trying to find the good overloaded function !!
  449. so all file function are doubled in system.pp
  450. this is not very beautiful !!}
  451. if (def_from^.deftype=filedef) and
  452. (
  453. (
  454. (pfiledef(def_from)^.filetype = ft_typed) and
  455. (pfiledef(def_to)^.filetype = ft_typed) and
  456. (
  457. (pfiledef(def_from)^.typed_as = pdef(voiddef)) or
  458. (pfiledef(def_to)^.typed_as = pdef(voiddef))
  459. )
  460. ) or
  461. (
  462. (
  463. (pfiledef(def_from)^.filetype = ft_untyped) and
  464. (pfiledef(def_to)^.filetype = ft_typed)
  465. ) or
  466. (
  467. (pfiledef(def_from)^.filetype = ft_typed) and
  468. (pfiledef(def_to)^.filetype = ft_untyped)
  469. )
  470. )
  471. ) then
  472. begin
  473. doconv:=tc_equal;
  474. b:=true;
  475. end
  476. end;
  477. else
  478. begin
  479. { assignment overwritten ?? }
  480. if is_assignment_overloaded(def_from,def_to) then
  481. b:=true;
  482. end;
  483. end;
  484. { nil is compatible with ansi- and wide strings }
  485. { no, that isn't true, (FK)
  486. if (fromtreetype=niln) and (def_to^.deftype=stringdef)
  487. and (pstringdef(def_to)^.string_typ in [st_ansistring,st_widestring]) then
  488. begin
  489. doconv:=tc_equal;
  490. b:=true;
  491. end
  492. else
  493. }
  494. { ansi- and wide strings can be assigned to void pointers }
  495. { no, (FK)
  496. if (def_from^.deftype=stringdef) and
  497. (pstringdef(def_from)^.string_typ in [st_ansistring,st_widestring]) and
  498. (def_to^.deftype=pointerdef) and
  499. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  500. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  501. begin
  502. doconv:=tc_equal;
  503. b:=true;
  504. end
  505. else
  506. }
  507. { ansistrings can be assigned to pchar
  508. this needs an explicit type cast (FK)
  509. if is_ansistring(def_from) and
  510. (def_to^.deftype=pointerdef) and
  511. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  512. (porddef(ppointerdef(def_to)^.definition)^.typ=uchar) then
  513. begin
  514. doconv:=tc_ansistring_2_pchar;
  515. b:=true;
  516. end
  517. else
  518. }
  519. isconvertable:=b;
  520. end;
  521. {****************************************************************************
  522. Register Calculation
  523. ****************************************************************************}
  524. { marks an lvalue as "unregable" }
  525. procedure make_not_regable(p : ptree);
  526. begin
  527. case p^.treetype of
  528. typeconvn :
  529. make_not_regable(p^.left);
  530. loadn :
  531. if p^.symtableentry^.typ=varsym then
  532. pvarsym(p^.symtableentry)^.var_options :=
  533. pvarsym(p^.symtableentry)^.var_options and not vo_regable;
  534. end;
  535. end;
  536. procedure left_right_max(p : ptree);
  537. begin
  538. if assigned(p^.left) then
  539. begin
  540. if assigned(p^.right) then
  541. begin
  542. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  543. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  544. {$ifdef SUPPORT_MMX}
  545. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  546. {$endif SUPPORT_MMX}
  547. end
  548. else
  549. begin
  550. p^.registers32:=p^.left^.registers32;
  551. p^.registersfpu:=p^.left^.registersfpu;
  552. {$ifdef SUPPORT_MMX}
  553. p^.registersmmx:=p^.left^.registersmmx;
  554. {$endif SUPPORT_MMX}
  555. end;
  556. end;
  557. end;
  558. { calculates the needed registers for a binary operator }
  559. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  560. begin
  561. left_right_max(p);
  562. { Only when the difference between the left and right registers < the
  563. wanted registers allocate the amount of registers }
  564. if assigned(p^.left) then
  565. begin
  566. if assigned(p^.right) then
  567. begin
  568. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  569. inc(p^.registers32,r32);
  570. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  571. inc(p^.registersfpu,fpu);
  572. {$ifdef SUPPORT_MMX}
  573. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  574. inc(p^.registersmmx,mmx);
  575. {$endif SUPPORT_MMX}
  576. end
  577. else
  578. begin
  579. if (p^.left^.registers32<r32) then
  580. inc(p^.registers32,r32);
  581. if (p^.left^.registersfpu<fpu) then
  582. inc(p^.registersfpu,fpu);
  583. {$ifdef SUPPORT_MMX}
  584. if (p^.left^.registersmmx<mmx) then
  585. inc(p^.registersmmx,mmx);
  586. {$endif SUPPORT_MMX}
  587. end;
  588. end;
  589. { error CGMessage, if more than 8 floating point }
  590. { registers are needed }
  591. if p^.registersfpu>8 then
  592. CGMessage(cg_e_too_complex_expr);
  593. end;
  594. {****************************************************************************
  595. Subroutine Handling
  596. ****************************************************************************}
  597. { protected field handling
  598. protected field can not appear in
  599. var parameters of function !!
  600. this can only be done after we have determined the
  601. overloaded function
  602. this is the reason why it is not in the parser, PM }
  603. procedure test_protected_sym(sym : psym);
  604. begin
  605. if ((sym^.properties and sp_protected)<>0) and
  606. ((sym^.owner^.symtabletype=unitsymtable) or
  607. ((sym^.owner^.symtabletype=objectsymtable) and
  608. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))) then
  609. CGMessage(parser_e_cant_access_protected_member);
  610. end;
  611. procedure test_protected(p : ptree);
  612. begin
  613. case p^.treetype of
  614. loadn : test_protected_sym(p^.symtableentry);
  615. typeconvn : test_protected(p^.left);
  616. derefn : test_protected(p^.left);
  617. subscriptn : begin
  618. { test_protected(p^.left);
  619. Is a field of a protected var
  620. also protected ??? PM }
  621. test_protected_sym(p^.vs);
  622. end;
  623. end;
  624. end;
  625. function is_procsym_load(p:Ptree):boolean;
  626. begin
  627. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  628. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  629. and (p^.left^.symtableentry^.typ=procsym)) ;
  630. end;
  631. { change a proc call to a procload for assignment to a procvar }
  632. { this can only happen for proc/function without arguments }
  633. function is_procsym_call(p:Ptree):boolean;
  634. begin
  635. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  636. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  637. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  638. end;
  639. function is_assignment_overloaded(from_def,to_def : pdef) : boolean;
  640. var
  641. passproc : pprocdef;
  642. convtyp : tconverttype;
  643. begin
  644. is_assignment_overloaded:=false;
  645. if assigned(overloaded_operators[assignment]) then
  646. passproc:=overloaded_operators[assignment]^.definition
  647. else
  648. exit;
  649. while passproc<>nil do
  650. begin
  651. if is_equal(passproc^.retdef,to_def) and
  652. isconvertable(from_def,passproc^.para1^.data,convtyp,
  653. ordconstn { nur Dummy},false ) then
  654. begin
  655. is_assignment_overloaded:=true;
  656. break;
  657. end;
  658. passproc:=passproc^.nextoverloaded;
  659. end;
  660. end;
  661. end.
  662. {
  663. $Log$
  664. Revision 1.13 1998-12-15 17:11:37 peter
  665. * string:=pchar not allowed in tp mode
  666. Revision 1.12 1998/12/11 00:03:18 peter
  667. + globtype,tokens,version unit splitted from globals
  668. Revision 1.11 1998/12/10 09:47:21 florian
  669. + basic operations with int64/qord (compiler with -dint64)
  670. + rtti of enumerations extended: names are now written
  671. Revision 1.10 1998/11/29 12:40:23 peter
  672. * newcnv -> not oldcnv
  673. Revision 1.9 1998/11/26 13:10:42 peter
  674. * new int - int conversion -dNEWCNV
  675. * some function renamings
  676. Revision 1.8 1998/11/17 00:36:42 peter
  677. * more ansistring fixes
  678. Revision 1.7 1998/10/14 13:33:24 peter
  679. * fixed small typo
  680. Revision 1.6 1998/10/14 12:53:38 peter
  681. * fixed small tp7 things
  682. * boolean:=longbool and longbool fixed
  683. Revision 1.5 1998/10/12 09:49:58 florian
  684. + support of <procedure var type>:=<pointer> in delphi mode added
  685. Revision 1.4 1998/09/30 16:42:52 peter
  686. * fixed bool-bool cnv
  687. Revision 1.3 1998/09/24 23:49:05 peter
  688. + aktmodeswitches
  689. Revision 1.2 1998/09/24 09:02:14 peter
  690. * rewritten isconvertable to use case
  691. * array of .. and single variable are compatible
  692. Revision 1.1 1998/09/23 20:42:22 peter
  693. * splitted pass_1
  694. }