htypechk.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  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. { nil is compatible with procvars }
  343. if (fromtreetype=niln) then
  344. begin
  345. doconv:=tc_equal;
  346. b:=true;
  347. end;
  348. end;
  349. objectdef : begin
  350. { object pascal objects }
  351. if (def_from^.deftype=objectdef) {and
  352. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  353. begin
  354. doconv:=tc_equal;
  355. b:=pobjectdef(def_from)^.isrelated(pobjectdef(def_to));
  356. end
  357. else
  358. { nil is compatible with class instances }
  359. if (fromtreetype=niln) and (pobjectdef(def_to)^.isclass) then
  360. begin
  361. doconv:=tc_equal;
  362. b:=true;
  363. end;
  364. end;
  365. classrefdef : begin
  366. { class reference types }
  367. if (def_from^.deftype=classrefdef) then
  368. begin
  369. doconv:=tc_equal;
  370. b:=pobjectdef(pclassrefdef(def_from)^.definition)^.isrelated(
  371. pobjectdef(pclassrefdef(def_to)^.definition));
  372. end
  373. else
  374. { nil is compatible with class references }
  375. if (fromtreetype=niln) then
  376. begin
  377. doconv:=tc_equal;
  378. b:=true;
  379. end;
  380. end;
  381. filedef : begin
  382. { typed files are all equal to the abstract file type
  383. name TYPEDFILE in system.pp in is_equal in types.pas
  384. the problem is that it sholud be also compatible to FILE
  385. but this would leed to a problem for ASSIGN RESET and REWRITE
  386. when trying to find the good overloaded function !!
  387. so all file function are doubled in system.pp
  388. this is not very beautiful !!}
  389. if (def_from^.deftype=filedef) and
  390. (
  391. (
  392. (pfiledef(def_from)^.filetype = ft_typed) and
  393. (pfiledef(def_to)^.filetype = ft_typed) and
  394. (
  395. (pfiledef(def_from)^.typed_as = pdef(voiddef)) or
  396. (pfiledef(def_to)^.typed_as = pdef(voiddef))
  397. )
  398. ) or
  399. (
  400. (
  401. (pfiledef(def_from)^.filetype = ft_untyped) and
  402. (pfiledef(def_to)^.filetype = ft_typed)
  403. ) or
  404. (
  405. (pfiledef(def_from)^.filetype = ft_typed) and
  406. (pfiledef(def_to)^.filetype = ft_untyped)
  407. )
  408. )
  409. ) then
  410. begin
  411. doconv:=tc_equal;
  412. b:=true;
  413. end
  414. end;
  415. else
  416. begin
  417. { assignment overwritten ?? }
  418. if is_assignment_overloaded(def_from,def_to) then
  419. b:=true;
  420. end;
  421. end;
  422. { nil is compatible with ansi- and wide strings }
  423. { no, that isn't true, (FK)
  424. if (fromtreetype=niln) and (def_to^.deftype=stringdef)
  425. and (pstringdef(def_to)^.string_typ in [st_ansistring,st_widestring]) then
  426. begin
  427. doconv:=tc_equal;
  428. b:=true;
  429. end
  430. else
  431. }
  432. { ansi- and wide strings can be assigned to void pointers }
  433. { no, (FK)
  434. if (def_from^.deftype=stringdef) and
  435. (pstringdef(def_from)^.string_typ in [st_ansistring,st_widestring]) and
  436. (def_to^.deftype=pointerdef) and
  437. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  438. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  439. begin
  440. doconv:=tc_equal;
  441. b:=true;
  442. end
  443. else
  444. }
  445. { ansistrings can be assigned to pchar
  446. this needs an explicit type cast (FK)
  447. if is_ansistring(def_from) and
  448. (def_to^.deftype=pointerdef) and
  449. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  450. (porddef(ppointerdef(def_to)^.definition)^.typ=uchar) then
  451. begin
  452. doconv:=tc_ansistring_2_pchar;
  453. b:=true;
  454. end
  455. else
  456. }
  457. isconvertable:=b;
  458. end;
  459. {****************************************************************************
  460. Register Calculation
  461. ****************************************************************************}
  462. { marks an lvalue as "unregable" }
  463. procedure make_not_regable(p : ptree);
  464. begin
  465. case p^.treetype of
  466. typeconvn :
  467. make_not_regable(p^.left);
  468. loadn :
  469. if p^.symtableentry^.typ=varsym then
  470. pvarsym(p^.symtableentry)^.var_options :=
  471. pvarsym(p^.symtableentry)^.var_options and not vo_regable;
  472. end;
  473. end;
  474. procedure left_right_max(p : ptree);
  475. begin
  476. if assigned(p^.left) then
  477. begin
  478. if assigned(p^.right) then
  479. begin
  480. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  481. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  482. {$ifdef SUPPORT_MMX}
  483. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  484. {$endif SUPPORT_MMX}
  485. end
  486. else
  487. begin
  488. p^.registers32:=p^.left^.registers32;
  489. p^.registersfpu:=p^.left^.registersfpu;
  490. {$ifdef SUPPORT_MMX}
  491. p^.registersmmx:=p^.left^.registersmmx;
  492. {$endif SUPPORT_MMX}
  493. end;
  494. end;
  495. end;
  496. { calculates the needed registers for a binary operator }
  497. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  498. begin
  499. left_right_max(p);
  500. { Only when the difference between the left and right registers < the
  501. wanted registers allocate the amount of registers }
  502. if assigned(p^.left) then
  503. begin
  504. if assigned(p^.right) then
  505. begin
  506. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  507. inc(p^.registers32,r32);
  508. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  509. inc(p^.registersfpu,fpu);
  510. {$ifdef SUPPORT_MMX}
  511. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  512. inc(p^.registersmmx,mmx);
  513. {$endif SUPPORT_MMX}
  514. end
  515. else
  516. begin
  517. if (p^.left^.registers32<r32) then
  518. inc(p^.registers32,r32);
  519. if (p^.left^.registersfpu<fpu) then
  520. inc(p^.registersfpu,fpu);
  521. {$ifdef SUPPORT_MMX}
  522. if (p^.left^.registersmmx<mmx) then
  523. inc(p^.registersmmx,mmx);
  524. {$endif SUPPORT_MMX}
  525. end;
  526. end;
  527. { error CGMessage, if more than 8 floating point }
  528. { registers are needed }
  529. if p^.registersfpu>8 then
  530. CGMessage(cg_e_too_complex_expr);
  531. end;
  532. {****************************************************************************
  533. Subroutine Handling
  534. ****************************************************************************}
  535. { protected field handling
  536. protected field can not appear in
  537. var parameters of function !!
  538. this can only be done after we have determined the
  539. overloaded function
  540. this is the reason why it is not in the parser, PM }
  541. procedure test_protected_sym(sym : psym);
  542. begin
  543. if ((sym^.properties and sp_protected)<>0) and
  544. ((sym^.owner^.symtabletype=unitsymtable) or
  545. ((sym^.owner^.symtabletype=objectsymtable) and
  546. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))) then
  547. CGMessage(parser_e_cant_access_protected_member);
  548. end;
  549. procedure test_protected(p : ptree);
  550. begin
  551. case p^.treetype of
  552. loadn : test_protected_sym(p^.symtableentry);
  553. typeconvn : test_protected(p^.left);
  554. derefn : test_protected(p^.left);
  555. subscriptn : begin
  556. { test_protected(p^.left);
  557. Is a field of a protected var
  558. also protected ??? PM }
  559. test_protected_sym(p^.vs);
  560. end;
  561. end;
  562. end;
  563. function is_procsym_load(p:Ptree):boolean;
  564. begin
  565. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  566. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  567. and (p^.left^.symtableentry^.typ=procsym)) ;
  568. end;
  569. { change a proc call to a procload for assignment to a procvar }
  570. { this can only happen for proc/function without arguments }
  571. function is_procsym_call(p:Ptree):boolean;
  572. begin
  573. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  574. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  575. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  576. end;
  577. function is_assignment_overloaded(from_def,to_def : pdef) : boolean;
  578. var
  579. passproc : pprocdef;
  580. convtyp : tconverttype;
  581. begin
  582. is_assignment_overloaded:=false;
  583. if assigned(overloaded_operators[assignment]) then
  584. passproc:=overloaded_operators[assignment]^.definition
  585. else
  586. exit;
  587. while passproc<>nil do
  588. begin
  589. if is_equal(passproc^.retdef,to_def) and
  590. isconvertable(from_def,passproc^.para1^.data,convtyp,
  591. ordconstn { nur Dummy},false ) then
  592. begin
  593. is_assignment_overloaded:=true;
  594. break;
  595. end;
  596. passproc:=passproc^.nextoverloaded;
  597. end;
  598. end;
  599. end.
  600. {
  601. $Log$
  602. Revision 1.4 1998-09-30 16:42:52 peter
  603. * fixed bool-bool cnv
  604. Revision 1.3 1998/09/24 23:49:05 peter
  605. + aktmodeswitches
  606. Revision 1.2 1998/09/24 09:02:14 peter
  607. * rewritten isconvertable to use case
  608. * array of .. and single variable are compatible
  609. Revision 1.1 1998/09/23 20:42:22 peter
  610. * splitted pass_1
  611. }