htypechk.pas 29 KB

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