htypechk.pas 27 KB

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