htypechk.pas 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. {$ifdef extdebug}
  25. count_ref : boolean = true;
  26. {$endif def extdebug}
  27. get_para_resulttype : boolean = false;
  28. allow_array_constructor : boolean = false;
  29. { Conversion }
  30. function isconvertable(def_from,def_to : pdef;
  31. var doconv : tconverttype;fromtreetype : ttreetyp;
  32. explicit : boolean) : byte;
  33. { Register Allocation }
  34. procedure make_not_regable(p : ptree);
  35. procedure left_right_max(p : ptree);
  36. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  37. { subroutine handling }
  38. procedure test_protected_sym(sym : psym);
  39. procedure test_protected(p : ptree);
  40. function valid_for_formal_var(p : ptree) : boolean;
  41. function valid_for_formal_const(p : ptree) : boolean;
  42. function is_procsym_load(p:Ptree):boolean;
  43. function is_procsym_call(p:Ptree):boolean;
  44. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  45. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  46. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  47. implementation
  48. uses
  49. globtype,systems,tokens,
  50. cobjects,verbose,globals,
  51. symconst,
  52. types,pass_1,cpubase,
  53. {$ifdef newcg}
  54. cgbase
  55. {$else}
  56. hcodegen
  57. {$endif}
  58. ;
  59. {****************************************************************************
  60. Convert
  61. ****************************************************************************}
  62. { Returns:
  63. 0 - Not convertable
  64. 1 - Convertable
  65. 2 - Convertable, but not first choice }
  66. function isconvertable(def_from,def_to : pdef;
  67. var doconv : tconverttype;fromtreetype : ttreetyp;
  68. explicit : boolean) : byte;
  69. { Tbasetype: uauto,uvoid,uchar,
  70. u8bit,u16bit,u32bit,
  71. s8bit,s16bit,s32,
  72. bool8bit,bool16bit,bool32bit,
  73. u64bit,s64bitint }
  74. type
  75. tbasedef=(bvoid,bchar,bint,bbool);
  76. const
  77. basedeftbl:array[tbasetype] of tbasedef =
  78. (bvoid,bvoid,bchar,
  79. bint,bint,bint,
  80. bint,bint,bint,
  81. bbool,bbool,bbool,bint,bint,bchar);
  82. basedefconverts : array[tbasedef,tbasedef] of tconverttype =
  83. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  84. (tc_not_possible,tc_equal,tc_not_possible,tc_not_possible),
  85. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_int_2_bool),
  86. (tc_not_possible,tc_not_possible,tc_bool_2_int,tc_bool_2_bool));
  87. var
  88. b : byte;
  89. hd1,hd2 : pdef;
  90. hct : tconverttype;
  91. begin
  92. { safety check }
  93. if not(assigned(def_from) and assigned(def_to)) then
  94. begin
  95. isconvertable:=0;
  96. exit;
  97. end;
  98. { tp7 procvar def support, in tp7 a procvar is always called, if the
  99. procvar is passed explicit a addrn would be there }
  100. if (m_tp_procvar in aktmodeswitches) and
  101. (def_from^.deftype=procvardef) and
  102. (fromtreetype=loadn) then
  103. begin
  104. def_from:=pprocvardef(def_from)^.rettype.def;
  105. end;
  106. { we walk the wanted (def_to) types and check then the def_from
  107. types if there is a conversion possible }
  108. b:=0;
  109. case def_to^.deftype of
  110. orddef :
  111. begin
  112. case def_from^.deftype of
  113. orddef :
  114. begin
  115. doconv:=basedefconverts[basedeftbl[porddef(def_from)^.typ],basedeftbl[porddef(def_to)^.typ]];
  116. b:=1;
  117. if (doconv=tc_not_possible) or
  118. ((doconv=tc_int_2_bool) and
  119. (not explicit) and
  120. (not is_boolean(def_from))) or
  121. ((doconv=tc_bool_2_int) and
  122. (not explicit) and
  123. (not is_boolean(def_to))) then
  124. b:=0;
  125. end;
  126. enumdef :
  127. begin
  128. { needed for char(enum) }
  129. if explicit then
  130. begin
  131. doconv:=tc_int_2_int;
  132. b:=1;
  133. end;
  134. end;
  135. end;
  136. end;
  137. stringdef :
  138. begin
  139. case def_from^.deftype of
  140. stringdef :
  141. begin
  142. doconv:=tc_string_2_string;
  143. b:=1;
  144. end;
  145. orddef :
  146. begin
  147. { char to string}
  148. if is_char(def_from) then
  149. begin
  150. doconv:=tc_char_2_string;
  151. b:=1;
  152. end;
  153. end;
  154. arraydef :
  155. begin
  156. { array of char to string, the length check is done by the firstpass of this node }
  157. if is_chararray(def_from) then
  158. begin
  159. doconv:=tc_chararray_2_string;
  160. if (not(cs_ansistrings in aktlocalswitches) and
  161. is_shortstring(def_to)) or
  162. ((cs_ansistrings in aktlocalswitches) and
  163. is_ansistring(def_to)) then
  164. b:=1
  165. else
  166. b:=2;
  167. end;
  168. end;
  169. pointerdef :
  170. begin
  171. { pchar can be assigned to short/ansistrings }
  172. if is_pchar(def_from) and not(m_tp in aktmodeswitches) then
  173. begin
  174. doconv:=tc_pchar_2_string;
  175. b:=1;
  176. end;
  177. end;
  178. end;
  179. end;
  180. floatdef :
  181. begin
  182. case def_from^.deftype of
  183. orddef :
  184. begin { ordinal to real }
  185. if is_integer(def_from) then
  186. begin
  187. if pfloatdef(def_to)^.typ=f32bit then
  188. doconv:=tc_int_2_fix
  189. else
  190. doconv:=tc_int_2_real;
  191. b:=1;
  192. end;
  193. end;
  194. floatdef :
  195. begin { 2 float types ? }
  196. if pfloatdef(def_from)^.typ=pfloatdef(def_to)^.typ then
  197. doconv:=tc_equal
  198. else
  199. begin
  200. if pfloatdef(def_from)^.typ=f32bit then
  201. doconv:=tc_fix_2_real
  202. else
  203. if pfloatdef(def_to)^.typ=f32bit then
  204. doconv:=tc_real_2_fix
  205. else
  206. doconv:=tc_real_2_real;
  207. end;
  208. b:=1;
  209. end;
  210. end;
  211. end;
  212. enumdef :
  213. begin
  214. if (def_from^.deftype=enumdef) then
  215. begin
  216. hd1:=def_from;
  217. while assigned(penumdef(hd1)^.basedef) do
  218. hd1:=penumdef(hd1)^.basedef;
  219. hd2:=def_to;
  220. while assigned(penumdef(hd2)^.basedef) do
  221. hd2:=penumdef(hd2)^.basedef;
  222. if (hd1=hd2) then
  223. begin
  224. b:=1;
  225. doconv:=tc_equal;
  226. end;
  227. end;
  228. end;
  229. arraydef :
  230. begin
  231. { open array is also compatible with a single element of its base type }
  232. if is_open_array(def_to) and
  233. is_equal(parraydef(def_to)^.elementtype.def,def_from) then
  234. begin
  235. doconv:=tc_equal;
  236. b:=1;
  237. end
  238. else
  239. begin
  240. case def_from^.deftype of
  241. arraydef :
  242. begin
  243. { array constructor -> open array }
  244. if is_open_array(def_to) and
  245. is_array_constructor(def_from) then
  246. begin
  247. if is_void(parraydef(def_from)^.elementtype.def) or
  248. is_equal(parraydef(def_to)^.elementtype.def,parraydef(def_from)^.elementtype.def) then
  249. begin
  250. doconv:=tc_equal;
  251. b:=1;
  252. end
  253. else
  254. if isconvertable(parraydef(def_from)^.elementtype.def,
  255. parraydef(def_to)^.elementtype.def,hct,nothingn,false)<>0 then
  256. begin
  257. doconv:=hct;
  258. b:=2;
  259. end;
  260. end;
  261. end;
  262. pointerdef :
  263. begin
  264. if is_zero_based_array(def_to) and
  265. is_equal(ppointerdef(def_from)^.pointertype.def,parraydef(def_to)^.elementtype.def) then
  266. begin
  267. doconv:=tc_pointer_2_array;
  268. b:=1;
  269. end;
  270. end;
  271. stringdef :
  272. begin
  273. { string to array of char}
  274. if (not(is_special_array(def_to)) or is_open_array(def_to)) and
  275. is_equal(parraydef(def_to)^.elementtype.def,cchardef) then
  276. begin
  277. doconv:=tc_string_2_chararray;
  278. b:=1;
  279. end;
  280. end;
  281. end;
  282. end;
  283. end;
  284. pointerdef :
  285. begin
  286. case def_from^.deftype of
  287. stringdef :
  288. begin
  289. { string constant to zero terminated string constant }
  290. if (fromtreetype=stringconstn) and
  291. is_pchar(def_to) then
  292. begin
  293. doconv:=tc_cstring_2_pchar;
  294. b:=1;
  295. end;
  296. end;
  297. orddef :
  298. begin
  299. { char constant to zero terminated string constant }
  300. if (fromtreetype=ordconstn) then
  301. begin
  302. if is_equal(def_from,cchardef) and
  303. is_pchar(def_to) then
  304. begin
  305. doconv:=tc_cchar_2_pchar;
  306. b:=1;
  307. end
  308. else
  309. if is_integer(def_from) then
  310. begin
  311. doconv:=tc_cord_2_pointer;
  312. b:=1;
  313. end;
  314. end;
  315. end;
  316. arraydef :
  317. begin
  318. { chararray to pointer }
  319. if is_zero_based_array(def_from) and
  320. is_equal(parraydef(def_from)^.elementtype.def,ppointerdef(def_to)^.pointertype.def) then
  321. begin
  322. doconv:=tc_array_2_pointer;
  323. b:=1;
  324. end;
  325. end;
  326. pointerdef :
  327. begin
  328. { child class pointer can be assigned to anchestor pointers }
  329. if (
  330. (ppointerdef(def_from)^.pointertype.def^.deftype=objectdef) and
  331. (ppointerdef(def_to)^.pointertype.def^.deftype=objectdef) and
  332. pobjectdef(ppointerdef(def_from)^.pointertype.def)^.is_related(
  333. pobjectdef(ppointerdef(def_to)^.pointertype.def))
  334. ) or
  335. { all pointers can be assigned to void-pointer }
  336. is_equal(ppointerdef(def_to)^.pointertype.def,voiddef) or
  337. { in my opnion, is this not clean pascal }
  338. { well, but it's handy to use, it isn't ? (FK) }
  339. is_equal(ppointerdef(def_from)^.pointertype.def,voiddef) then
  340. begin
  341. doconv:=tc_equal;
  342. b:=1;
  343. end;
  344. end;
  345. procvardef :
  346. begin
  347. { procedure variable can be assigned to an void pointer }
  348. { Not anymore. Use the @ operator now.}
  349. if not(m_tp_procvar in aktmodeswitches) and
  350. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  351. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  352. begin
  353. doconv:=tc_equal;
  354. b:=1;
  355. end;
  356. end;
  357. classrefdef,
  358. objectdef :
  359. begin
  360. { class types and class reference type
  361. can be assigned to void pointers }
  362. if (
  363. ((def_from^.deftype=objectdef) and pobjectdef(def_from)^.is_class) or
  364. (def_from^.deftype=classrefdef)
  365. ) and
  366. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  367. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  368. begin
  369. doconv:=tc_equal;
  370. b:=1;
  371. end;
  372. end;
  373. end;
  374. end;
  375. setdef :
  376. begin
  377. { automatic arrayconstructor -> set conversion }
  378. if is_array_constructor(def_from) then
  379. begin
  380. doconv:=tc_arrayconstructor_2_set;
  381. b:=1;
  382. end;
  383. end;
  384. procvardef :
  385. begin
  386. { proc -> procvar }
  387. if (def_from^.deftype=procdef) then
  388. begin
  389. doconv:=tc_proc_2_procvar;
  390. if proc_to_procvar_equal(pprocdef(def_from),pprocvardef(def_to)) then
  391. b:=1;
  392. end
  393. else
  394. { for example delphi allows the assignement from pointers }
  395. { to procedure variables }
  396. if (m_pointer_2_procedure in aktmodeswitches) and
  397. (def_from^.deftype=pointerdef) and
  398. (ppointerdef(def_from)^.pointertype.def^.deftype=orddef) and
  399. (porddef(ppointerdef(def_from)^.pointertype.def)^.typ=uvoid) then
  400. begin
  401. doconv:=tc_equal;
  402. b:=1;
  403. end
  404. else
  405. { nil is compatible with procvars }
  406. if (fromtreetype=niln) then
  407. begin
  408. doconv:=tc_equal;
  409. b:=1;
  410. end;
  411. end;
  412. objectdef :
  413. begin
  414. { object pascal objects }
  415. if (def_from^.deftype=objectdef) {and
  416. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  417. begin
  418. doconv:=tc_equal;
  419. if pobjectdef(def_from)^.is_related(pobjectdef(def_to)) then
  420. b:=1;
  421. end
  422. else
  423. { Class specific }
  424. if (pobjectdef(def_to)^.is_class) then
  425. begin
  426. { void pointer also for delphi mode }
  427. if (m_delphi in aktmodeswitches) and
  428. is_voidpointer(def_from) then
  429. begin
  430. doconv:=tc_equal;
  431. b:=1;
  432. end
  433. else
  434. { nil is compatible with class instances }
  435. if (fromtreetype=niln) and (pobjectdef(def_to)^.is_class) then
  436. begin
  437. doconv:=tc_equal;
  438. b:=1;
  439. end;
  440. end;
  441. end;
  442. classrefdef :
  443. begin
  444. { class reference types }
  445. if (def_from^.deftype=classrefdef) then
  446. begin
  447. doconv:=tc_equal;
  448. if pobjectdef(pclassrefdef(def_from)^.pointertype.def)^.is_related(
  449. pobjectdef(pclassrefdef(def_to)^.pointertype.def)) then
  450. b:=1;
  451. end
  452. else
  453. { nil is compatible with class references }
  454. if (fromtreetype=niln) then
  455. begin
  456. doconv:=tc_equal;
  457. b:=1;
  458. end;
  459. end;
  460. filedef :
  461. begin
  462. { typed files are all equal to the abstract file type
  463. name TYPEDFILE in system.pp in is_equal in types.pas
  464. the problem is that it sholud be also compatible to FILE
  465. but this would leed to a problem for ASSIGN RESET and REWRITE
  466. when trying to find the good overloaded function !!
  467. so all file function are doubled in system.pp
  468. this is not very beautiful !!}
  469. if (def_from^.deftype=filedef) and
  470. (
  471. (
  472. (pfiledef(def_from)^.filetyp = ft_typed) and
  473. (pfiledef(def_to)^.filetyp = ft_typed) and
  474. (
  475. (pfiledef(def_from)^.typedfiletype.def = pdef(voiddef)) or
  476. (pfiledef(def_to)^.typedfiletype.def = pdef(voiddef))
  477. )
  478. ) or
  479. (
  480. (
  481. (pfiledef(def_from)^.filetyp = ft_untyped) and
  482. (pfiledef(def_to)^.filetyp = ft_typed)
  483. ) or
  484. (
  485. (pfiledef(def_from)^.filetyp = ft_typed) and
  486. (pfiledef(def_to)^.filetyp = ft_untyped)
  487. )
  488. )
  489. ) then
  490. begin
  491. doconv:=tc_equal;
  492. b:=1;
  493. end
  494. end;
  495. else
  496. begin
  497. { assignment overwritten ?? }
  498. if assignment_overloaded(def_from,def_to)<>nil then
  499. b:=2;
  500. end;
  501. end;
  502. isconvertable:=b;
  503. end;
  504. {****************************************************************************
  505. Register Calculation
  506. ****************************************************************************}
  507. { marks an lvalue as "unregable" }
  508. procedure make_not_regable(p : ptree);
  509. begin
  510. case p^.treetype of
  511. typeconvn :
  512. make_not_regable(p^.left);
  513. loadn :
  514. if p^.symtableentry^.typ=varsym then
  515. pvarsym(p^.symtableentry)^.varoptions:=pvarsym(p^.symtableentry)^.varoptions-[vo_regable,vo_fpuregable];
  516. end;
  517. end;
  518. procedure left_right_max(p : ptree);
  519. begin
  520. if assigned(p^.left) then
  521. begin
  522. if assigned(p^.right) then
  523. begin
  524. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  525. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  526. {$ifdef SUPPORT_MMX}
  527. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  528. {$endif SUPPORT_MMX}
  529. end
  530. else
  531. begin
  532. p^.registers32:=p^.left^.registers32;
  533. p^.registersfpu:=p^.left^.registersfpu;
  534. {$ifdef SUPPORT_MMX}
  535. p^.registersmmx:=p^.left^.registersmmx;
  536. {$endif SUPPORT_MMX}
  537. end;
  538. end;
  539. end;
  540. { calculates the needed registers for a binary operator }
  541. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  542. begin
  543. left_right_max(p);
  544. { Only when the difference between the left and right registers < the
  545. wanted registers allocate the amount of registers }
  546. if assigned(p^.left) then
  547. begin
  548. if assigned(p^.right) then
  549. begin
  550. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  551. inc(p^.registers32,r32);
  552. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  553. inc(p^.registersfpu,fpu);
  554. {$ifdef SUPPORT_MMX}
  555. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  556. inc(p^.registersmmx,mmx);
  557. {$endif SUPPORT_MMX}
  558. { the following is a little bit guessing but I think }
  559. { it's the only way to solve same internalerrors: }
  560. { if the left and right node both uses registers }
  561. { and return a mem location, but the current node }
  562. { doesn't use an integer register we get probably }
  563. { trouble when restoring a node }
  564. if (p^.left^.registers32=p^.right^.registers32) and
  565. (p^.registers32=p^.left^.registers32) and
  566. (p^.registers32>0) and
  567. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM]) and
  568. (p^.right^.location.loc in [LOC_REFERENCE,LOC_MEM]) then
  569. inc(p^.registers32);
  570. end
  571. else
  572. begin
  573. if (p^.left^.registers32<r32) then
  574. inc(p^.registers32,r32);
  575. if (p^.left^.registersfpu<fpu) then
  576. inc(p^.registersfpu,fpu);
  577. {$ifdef SUPPORT_MMX}
  578. if (p^.left^.registersmmx<mmx) then
  579. inc(p^.registersmmx,mmx);
  580. {$endif SUPPORT_MMX}
  581. end;
  582. end;
  583. { error CGMessage, if more than 8 floating point }
  584. { registers are needed }
  585. if p^.registersfpu>8 then
  586. CGMessage(cg_e_too_complex_expr);
  587. end;
  588. {****************************************************************************
  589. Subroutine Handling
  590. ****************************************************************************}
  591. { protected field handling
  592. protected field can not appear in
  593. var parameters of function !!
  594. this can only be done after we have determined the
  595. overloaded function
  596. this is the reason why it is not in the parser, PM }
  597. procedure test_protected_sym(sym : psym);
  598. begin
  599. if (sp_protected in sym^.symoptions) and
  600. ((sym^.owner^.symtabletype=unitsymtable) or
  601. ((sym^.owner^.symtabletype=objectsymtable) and
  602. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))
  603. ) then
  604. CGMessage(parser_e_cant_access_protected_member);
  605. end;
  606. procedure test_protected(p : ptree);
  607. begin
  608. case p^.treetype of
  609. loadn : test_protected_sym(p^.symtableentry);
  610. typeconvn : test_protected(p^.left);
  611. derefn : test_protected(p^.left);
  612. subscriptn : begin
  613. { test_protected(p^.left);
  614. Is a field of a protected var
  615. also protected ??? PM }
  616. test_protected_sym(p^.vs);
  617. end;
  618. end;
  619. end;
  620. function valid_for_formal_var(p : ptree) : boolean;
  621. var
  622. v : boolean;
  623. begin
  624. case p^.treetype of
  625. loadn :
  626. v:=(p^.symtableentry^.typ in [typedconstsym,varsym]);
  627. typeconvn :
  628. v:=valid_for_formal_var(p^.left);
  629. derefn,
  630. subscriptn,
  631. vecn,
  632. funcretn,
  633. selfn :
  634. v:=true;
  635. calln : { procvars are callnodes first }
  636. v:=assigned(p^.right) and not assigned(p^.left);
  637. addrn,
  638. typen : { addrn is not allowed as this generate a constant value (PFV) }
  639. v:=false;
  640. { no other node accepted (PM) }
  641. else
  642. v:=false;
  643. end;
  644. valid_for_formal_var:=v;
  645. end;
  646. function valid_for_formal_const(p : ptree) : boolean;
  647. var
  648. v : boolean;
  649. begin
  650. { p must have been firstpass'd before }
  651. { accept about anything but not a statement ! }
  652. case p^.treetype of
  653. calln,
  654. statementn,
  655. addrn : { addrn is not allowed as this generate a constant value and not a reference (PFV) }
  656. v:=false;
  657. else
  658. v:=true;
  659. end;
  660. valid_for_formal_const:=v;
  661. end;
  662. function is_procsym_load(p:Ptree):boolean;
  663. begin
  664. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  665. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  666. and (p^.left^.symtableentry^.typ=procsym)) ;
  667. end;
  668. { change a proc call to a procload for assignment to a procvar }
  669. { this can only happen for proc/function without arguments }
  670. function is_procsym_call(p:Ptree):boolean;
  671. begin
  672. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  673. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  674. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  675. end;
  676. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  677. var
  678. passproc : pprocdef;
  679. convtyp : tconverttype;
  680. begin
  681. assignment_overloaded:=nil;
  682. if assigned(overloaded_operators[_assignment]) then
  683. passproc:=overloaded_operators[_assignment]^.definition
  684. else
  685. exit;
  686. while passproc<>nil do
  687. begin
  688. if is_equal(passproc^.rettype.def,to_def) and
  689. (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
  690. (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,ordconstn,false)=1)) then
  691. begin
  692. assignment_overloaded:=passproc;
  693. break;
  694. end;
  695. passproc:=passproc^.nextoverloaded;
  696. end;
  697. end;
  698. { local routines can't be assigned to procvars }
  699. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  700. begin
  701. if (from_def^.symtablelevel>1) and (to_def^.deftype=procvardef) then
  702. CGMessage(type_e_cannot_local_proc_to_procvar);
  703. end;
  704. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  705. var
  706. hp : ptree;
  707. gotsubscript,
  708. gotpointer,
  709. gotclass,
  710. gotderef : boolean;
  711. begin
  712. valid_for_assign:=false;
  713. gotsubscript:=false;
  714. gotderef:=false;
  715. gotclass:=false;
  716. gotpointer:=false;
  717. hp:=p;
  718. while assigned(hp) do
  719. begin
  720. { property allowed? calln has a property check itself }
  721. if (not allowprop) and
  722. (hp^.isproperty) and
  723. (hp^.treetype<>calln) then
  724. begin
  725. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  726. exit;
  727. end;
  728. case hp^.treetype of
  729. derefn :
  730. begin
  731. gotderef:=true;
  732. hp:=hp^.left;
  733. end;
  734. typeconvn :
  735. begin
  736. case hp^.resulttype^.deftype of
  737. pointerdef :
  738. gotpointer:=true;
  739. objectdef :
  740. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  741. classrefdef :
  742. gotclass:=true;
  743. arraydef :
  744. begin
  745. { pointer -> array conversion is done then we need to see it
  746. as a deref, because a ^ is then not required anymore }
  747. if (hp^.left^.resulttype^.deftype=pointerdef) then
  748. gotderef:=true;
  749. end;
  750. end;
  751. hp:=hp^.left;
  752. end;
  753. vecn,
  754. asn :
  755. hp:=hp^.left;
  756. subscriptn :
  757. begin
  758. gotsubscript:=true;
  759. hp:=hp^.left;
  760. end;
  761. subn,
  762. addn :
  763. begin
  764. { Allow add/sub operators on a pointer, or an integer
  765. and a pointer typecast and deref has been found }
  766. if (hp^.resulttype^.deftype=pointerdef) or
  767. (is_integer(hp^.resulttype) and gotpointer and gotderef) then
  768. valid_for_assign:=true
  769. else
  770. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  771. exit;
  772. end;
  773. addrn :
  774. begin
  775. if not(gotderef) and
  776. not(hp^.procvarload) then
  777. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_addr);
  778. exit;
  779. end;
  780. selfn,
  781. funcretn :
  782. begin
  783. valid_for_assign:=true;
  784. exit;
  785. end;
  786. calln :
  787. begin
  788. { check return type }
  789. case hp^.resulttype^.deftype of
  790. pointerdef :
  791. gotpointer:=true;
  792. objectdef :
  793. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  794. classrefdef :
  795. gotclass:=true;
  796. end;
  797. { 1. if it returns a pointer and we've found a deref,
  798. 2. if it returns a class and a subscription is found,
  799. 3. property is allowed }
  800. if (gotpointer and gotderef) or
  801. (gotclass and gotsubscript) or
  802. (hp^.isproperty and allowprop) then
  803. valid_for_assign:=true
  804. else
  805. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  806. exit;
  807. end;
  808. loadn :
  809. begin
  810. case hp^.symtableentry^.typ of
  811. absolutesym,
  812. varsym :
  813. begin
  814. if (pvarsym(hp^.symtableentry)^.varspez=vs_const) then
  815. begin
  816. { allow p^:= constructions with p is const parameter }
  817. if gotderef then
  818. valid_for_assign:=true
  819. else
  820. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_const);
  821. exit;
  822. end;
  823. { Are we at a with symtable, then we need to process the
  824. withrefnode also to check for maybe a const load }
  825. if (hp^.symtable^.symtabletype=withsymtable) then
  826. begin
  827. { continue with processing the withref node }
  828. hp:=ptree(pwithsymtable(hp^.symtable)^.withrefnode);
  829. end
  830. else
  831. begin
  832. { set the assigned flag for varsyms }
  833. if (pvarsym(hp^.symtableentry)^.varstate=vs_declared) then
  834. pvarsym(hp^.symtableentry)^.varstate:=vs_assigned;
  835. valid_for_assign:=true;
  836. exit;
  837. end;
  838. end;
  839. funcretsym,
  840. typedconstsym :
  841. begin
  842. valid_for_assign:=true;
  843. exit;
  844. end;
  845. end;
  846. end;
  847. else
  848. begin
  849. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  850. exit;
  851. end;
  852. end;
  853. end;
  854. end;
  855. end.
  856. {
  857. $Log$
  858. Revision 1.62 2000-05-30 18:38:45 florian
  859. * fixed assignments of subrange enumeration types
  860. Revision 1.61 2000/05/26 18:21:41 peter
  861. * give error for @ with formal const,var parameter. Because @ generates
  862. a constant value and not a reference
  863. Revision 1.60 2000/05/16 16:01:03 florian
  864. * fixed type conversion test for open arrays: the to and from fields where
  865. exchanged which leads under certain circumstances to problems when
  866. passing arrays of classes/class references as open array parameters
  867. Revision 1.59 2000/02/18 16:13:29 florian
  868. * optimized ansistring compare with ''
  869. * fixed 852
  870. Revision 1.58 2000/02/09 13:22:53 peter
  871. * log truncated
  872. Revision 1.57 2000/02/05 12:11:50 peter
  873. * property check for assigning fixed for calln
  874. Revision 1.56 2000/02/01 09:41:27 peter
  875. * allow class -> voidpointer for delphi mode
  876. Revision 1.55 2000/01/07 01:14:27 peter
  877. * updated copyright to 2000
  878. Revision 1.54 1999/12/31 14:26:27 peter
  879. * fixed crash with empty array constructors
  880. Revision 1.53 1999/12/18 14:55:21 florian
  881. * very basic widestring support
  882. Revision 1.52 1999/12/16 19:12:04 peter
  883. * allow constant pointer^ also for assignment
  884. Revision 1.51 1999/12/09 09:35:54 peter
  885. * allow assigning to self
  886. Revision 1.50 1999/11/30 10:40:43 peter
  887. + ttype, tsymlist
  888. Revision 1.49 1999/11/18 15:34:45 pierre
  889. * Notes/Hints for local syms changed to
  890. Set_varstate function
  891. Revision 1.48 1999/11/09 14:47:03 peter
  892. * pointer->array is allowed for all pointer types in FPC, fixed assign
  893. check for it.
  894. Revision 1.47 1999/11/09 13:29:33 peter
  895. * valid_for_assign allow properties with calln
  896. Revision 1.46 1999/11/08 22:45:33 peter
  897. * allow typecasting to integer within pointer typecast+deref
  898. Revision 1.45 1999/11/06 14:34:21 peter
  899. * truncated log to 20 revs
  900. Revision 1.44 1999/11/04 23:11:21 peter
  901. * fixed pchar and deref detection for assigning
  902. Revision 1.43 1999/10/27 16:04:45 peter
  903. * valid_for_assign support for calln,asn
  904. Revision 1.42 1999/10/26 12:30:41 peter
  905. * const parameter is now checked
  906. * better and generic check if a node can be used for assigning
  907. * export fixes
  908. * procvar equal works now (it never had worked at least from 0.99.8)
  909. * defcoll changed to linkedlist with pparaitem so it can easily be
  910. walked both directions
  911. Revision 1.41 1999/10/14 14:57:52 florian
  912. - removed the hcodegen use in the new cg, use cgbase instead
  913. Revision 1.40 1999/09/26 21:30:15 peter
  914. + constant pointer support which can happend with typecasting like
  915. const p=pointer(1)
  916. * better procvar parsing in typed consts
  917. Revision 1.39 1999/09/17 17:14:04 peter
  918. * @procvar fixes for tp mode
  919. * @<id>:= gives now an error
  920. Revision 1.38 1999/08/17 13:26:07 peter
  921. * arrayconstructor -> arrayofconst fixed when arraycosntructor was not
  922. variant.
  923. }