htypechk.pas 29 KB

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