htypechk.pas 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  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,arrayconstructn,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 (which can be part of array constructor)
  290. to zero terminated string constant }
  291. if (fromtreetype in [arrayconstructn,stringconstn]) and
  292. is_pchar(def_to) then
  293. begin
  294. doconv:=tc_cstring_2_pchar;
  295. b:=1;
  296. end;
  297. end;
  298. orddef :
  299. begin
  300. { char constant to zero terminated string constant }
  301. if (fromtreetype=ordconstn) then
  302. begin
  303. if is_equal(def_from,cchardef) and
  304. is_pchar(def_to) then
  305. begin
  306. doconv:=tc_cchar_2_pchar;
  307. b:=1;
  308. end
  309. else
  310. if is_integer(def_from) then
  311. begin
  312. doconv:=tc_cord_2_pointer;
  313. b:=1;
  314. end;
  315. end;
  316. end;
  317. arraydef :
  318. begin
  319. { chararray to pointer }
  320. if is_zero_based_array(def_from) and
  321. is_equal(parraydef(def_from)^.elementtype.def,ppointerdef(def_to)^.pointertype.def) then
  322. begin
  323. doconv:=tc_array_2_pointer;
  324. b:=1;
  325. end;
  326. end;
  327. pointerdef :
  328. begin
  329. { child class pointer can be assigned to anchestor pointers }
  330. if (
  331. (ppointerdef(def_from)^.pointertype.def^.deftype=objectdef) and
  332. (ppointerdef(def_to)^.pointertype.def^.deftype=objectdef) and
  333. pobjectdef(ppointerdef(def_from)^.pointertype.def)^.is_related(
  334. pobjectdef(ppointerdef(def_to)^.pointertype.def))
  335. ) or
  336. { all pointers can be assigned to void-pointer }
  337. is_equal(ppointerdef(def_to)^.pointertype.def,voiddef) or
  338. { in my opnion, is this not clean pascal }
  339. { well, but it's handy to use, it isn't ? (FK) }
  340. is_equal(ppointerdef(def_from)^.pointertype.def,voiddef) then
  341. begin
  342. doconv:=tc_equal;
  343. b:=1;
  344. end;
  345. end;
  346. procvardef :
  347. begin
  348. { procedure variable can be assigned to an void pointer }
  349. { Not anymore. Use the @ operator now.}
  350. if not(m_tp_procvar in aktmodeswitches) and
  351. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  352. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  353. begin
  354. doconv:=tc_equal;
  355. b:=1;
  356. end;
  357. end;
  358. classrefdef,
  359. objectdef :
  360. begin
  361. { class types and class reference type
  362. can be assigned to void pointers }
  363. if (
  364. ((def_from^.deftype=objectdef) and pobjectdef(def_from)^.is_class) or
  365. (def_from^.deftype=classrefdef)
  366. ) and
  367. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  368. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  369. begin
  370. doconv:=tc_equal;
  371. b:=1;
  372. end;
  373. end;
  374. end;
  375. end;
  376. setdef :
  377. begin
  378. { automatic arrayconstructor -> set conversion }
  379. if is_array_constructor(def_from) then
  380. begin
  381. doconv:=tc_arrayconstructor_2_set;
  382. b:=1;
  383. end;
  384. end;
  385. procvardef :
  386. begin
  387. { proc -> procvar }
  388. if (def_from^.deftype=procdef) then
  389. begin
  390. doconv:=tc_proc_2_procvar;
  391. if proc_to_procvar_equal(pprocdef(def_from),pprocvardef(def_to)) then
  392. b:=1;
  393. end
  394. else
  395. { for example delphi allows the assignement from pointers }
  396. { to procedure variables }
  397. if (m_pointer_2_procedure in aktmodeswitches) and
  398. (def_from^.deftype=pointerdef) and
  399. (ppointerdef(def_from)^.pointertype.def^.deftype=orddef) and
  400. (porddef(ppointerdef(def_from)^.pointertype.def)^.typ=uvoid) then
  401. begin
  402. doconv:=tc_equal;
  403. b:=1;
  404. end
  405. else
  406. { nil is compatible with procvars }
  407. if (fromtreetype=niln) then
  408. begin
  409. doconv:=tc_equal;
  410. b:=1;
  411. end;
  412. end;
  413. objectdef :
  414. begin
  415. { object pascal objects }
  416. if (def_from^.deftype=objectdef) {and
  417. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  418. begin
  419. doconv:=tc_equal;
  420. if pobjectdef(def_from)^.is_related(pobjectdef(def_to)) then
  421. b:=1;
  422. end
  423. else
  424. { Class specific }
  425. if (pobjectdef(def_to)^.is_class) then
  426. begin
  427. { void pointer also for delphi mode }
  428. if (m_delphi in aktmodeswitches) and
  429. is_voidpointer(def_from) then
  430. begin
  431. doconv:=tc_equal;
  432. b:=1;
  433. end
  434. else
  435. { nil is compatible with class instances }
  436. if (fromtreetype=niln) and (pobjectdef(def_to)^.is_class) then
  437. begin
  438. doconv:=tc_equal;
  439. b:=1;
  440. end;
  441. end;
  442. end;
  443. classrefdef :
  444. begin
  445. { class reference types }
  446. if (def_from^.deftype=classrefdef) then
  447. begin
  448. doconv:=tc_equal;
  449. if pobjectdef(pclassrefdef(def_from)^.pointertype.def)^.is_related(
  450. pobjectdef(pclassrefdef(def_to)^.pointertype.def)) then
  451. b:=1;
  452. end
  453. else
  454. { nil is compatible with class references }
  455. if (fromtreetype=niln) then
  456. begin
  457. doconv:=tc_equal;
  458. b:=1;
  459. end;
  460. end;
  461. filedef :
  462. begin
  463. { typed files are all equal to the abstract file type
  464. name TYPEDFILE in system.pp in is_equal in types.pas
  465. the problem is that it sholud be also compatible to FILE
  466. but this would leed to a problem for ASSIGN RESET and REWRITE
  467. when trying to find the good overloaded function !!
  468. so all file function are doubled in system.pp
  469. this is not very beautiful !!}
  470. if (def_from^.deftype=filedef) and
  471. (
  472. (
  473. (pfiledef(def_from)^.filetyp = ft_typed) and
  474. (pfiledef(def_to)^.filetyp = ft_typed) and
  475. (
  476. (pfiledef(def_from)^.typedfiletype.def = pdef(voiddef)) or
  477. (pfiledef(def_to)^.typedfiletype.def = pdef(voiddef))
  478. )
  479. ) or
  480. (
  481. (
  482. (pfiledef(def_from)^.filetyp = ft_untyped) and
  483. (pfiledef(def_to)^.filetyp = ft_typed)
  484. ) or
  485. (
  486. (pfiledef(def_from)^.filetyp = ft_typed) and
  487. (pfiledef(def_to)^.filetyp = ft_untyped)
  488. )
  489. )
  490. ) then
  491. begin
  492. doconv:=tc_equal;
  493. b:=1;
  494. end
  495. end;
  496. else
  497. begin
  498. { assignment overwritten ?? }
  499. if assignment_overloaded(def_from,def_to)<>nil then
  500. b:=2;
  501. end;
  502. end;
  503. isconvertable:=b;
  504. end;
  505. {****************************************************************************
  506. Register Calculation
  507. ****************************************************************************}
  508. { marks an lvalue as "unregable" }
  509. procedure make_not_regable(p : ptree);
  510. begin
  511. case p^.treetype of
  512. typeconvn :
  513. make_not_regable(p^.left);
  514. loadn :
  515. if p^.symtableentry^.typ=varsym then
  516. pvarsym(p^.symtableentry)^.varoptions:=pvarsym(p^.symtableentry)^.varoptions-[vo_regable,vo_fpuregable];
  517. end;
  518. end;
  519. procedure left_right_max(p : ptree);
  520. begin
  521. if assigned(p^.left) then
  522. begin
  523. if assigned(p^.right) then
  524. begin
  525. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  526. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  527. {$ifdef SUPPORT_MMX}
  528. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  529. {$endif SUPPORT_MMX}
  530. end
  531. else
  532. begin
  533. p^.registers32:=p^.left^.registers32;
  534. p^.registersfpu:=p^.left^.registersfpu;
  535. {$ifdef SUPPORT_MMX}
  536. p^.registersmmx:=p^.left^.registersmmx;
  537. {$endif SUPPORT_MMX}
  538. end;
  539. end;
  540. end;
  541. { calculates the needed registers for a binary operator }
  542. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  543. begin
  544. left_right_max(p);
  545. { Only when the difference between the left and right registers < the
  546. wanted registers allocate the amount of registers }
  547. if assigned(p^.left) then
  548. begin
  549. if assigned(p^.right) then
  550. begin
  551. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  552. inc(p^.registers32,r32);
  553. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  554. inc(p^.registersfpu,fpu);
  555. {$ifdef SUPPORT_MMX}
  556. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  557. inc(p^.registersmmx,mmx);
  558. {$endif SUPPORT_MMX}
  559. { the following is a little bit guessing but I think }
  560. { it's the only way to solve same internalerrors: }
  561. { if the left and right node both uses registers }
  562. { and return a mem location, but the current node }
  563. { doesn't use an integer register we get probably }
  564. { trouble when restoring a node }
  565. if (p^.left^.registers32=p^.right^.registers32) and
  566. (p^.registers32=p^.left^.registers32) and
  567. (p^.registers32>0) and
  568. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM]) and
  569. (p^.right^.location.loc in [LOC_REFERENCE,LOC_MEM]) then
  570. inc(p^.registers32);
  571. end
  572. else
  573. begin
  574. if (p^.left^.registers32<r32) then
  575. inc(p^.registers32,r32);
  576. if (p^.left^.registersfpu<fpu) then
  577. inc(p^.registersfpu,fpu);
  578. {$ifdef SUPPORT_MMX}
  579. if (p^.left^.registersmmx<mmx) then
  580. inc(p^.registersmmx,mmx);
  581. {$endif SUPPORT_MMX}
  582. end;
  583. end;
  584. { error CGMessage, if more than 8 floating point }
  585. { registers are needed }
  586. if p^.registersfpu>8 then
  587. CGMessage(cg_e_too_complex_expr);
  588. end;
  589. {****************************************************************************
  590. Subroutine Handling
  591. ****************************************************************************}
  592. { protected field handling
  593. protected field can not appear in
  594. var parameters of function !!
  595. this can only be done after we have determined the
  596. overloaded function
  597. this is the reason why it is not in the parser, PM }
  598. procedure test_protected_sym(sym : psym);
  599. begin
  600. if (sp_protected in sym^.symoptions) and
  601. ((sym^.owner^.symtabletype=unitsymtable) or
  602. ((sym^.owner^.symtabletype=objectsymtable) and
  603. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))
  604. ) then
  605. CGMessage(parser_e_cant_access_protected_member);
  606. end;
  607. procedure test_protected(p : ptree);
  608. begin
  609. case p^.treetype of
  610. loadn : test_protected_sym(p^.symtableentry);
  611. typeconvn : test_protected(p^.left);
  612. derefn : test_protected(p^.left);
  613. subscriptn : begin
  614. { test_protected(p^.left);
  615. Is a field of a protected var
  616. also protected ??? PM }
  617. test_protected_sym(p^.vs);
  618. end;
  619. end;
  620. end;
  621. function valid_for_formal_var(p : ptree) : boolean;
  622. var
  623. v : boolean;
  624. begin
  625. case p^.treetype of
  626. loadn :
  627. v:=(p^.symtableentry^.typ in [typedconstsym,varsym]);
  628. typeconvn :
  629. v:=valid_for_formal_var(p^.left);
  630. derefn,
  631. subscriptn,
  632. vecn,
  633. funcretn,
  634. selfn :
  635. v:=true;
  636. calln : { procvars are callnodes first }
  637. v:=assigned(p^.right) and not assigned(p^.left);
  638. addrn,
  639. typen : { addrn is not allowed as this generate a constant value (PFV) }
  640. v:=false;
  641. { no other node accepted (PM) }
  642. else
  643. v:=false;
  644. end;
  645. valid_for_formal_var:=v;
  646. end;
  647. function valid_for_formal_const(p : ptree) : boolean;
  648. var
  649. v : boolean;
  650. begin
  651. { p must have been firstpass'd before }
  652. { accept about anything but not a statement ! }
  653. case p^.treetype of
  654. calln,
  655. statementn,
  656. addrn : { addrn is not allowed as this generate a constant value and not a reference (PFV) }
  657. v:=false;
  658. else
  659. v:=true;
  660. end;
  661. valid_for_formal_const:=v;
  662. end;
  663. function is_procsym_load(p:Ptree):boolean;
  664. begin
  665. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  666. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  667. and (p^.left^.symtableentry^.typ=procsym)) ;
  668. end;
  669. { change a proc call to a procload for assignment to a procvar }
  670. { this can only happen for proc/function without arguments }
  671. function is_procsym_call(p:Ptree):boolean;
  672. begin
  673. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  674. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  675. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  676. end;
  677. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  678. var
  679. passproc : pprocdef;
  680. convtyp : tconverttype;
  681. begin
  682. assignment_overloaded:=nil;
  683. if assigned(overloaded_operators[_assignment]) then
  684. passproc:=overloaded_operators[_assignment]^.definition
  685. else
  686. exit;
  687. while passproc<>nil do
  688. begin
  689. if is_equal(passproc^.rettype.def,to_def) and
  690. (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
  691. (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,ordconstn,false)=1)) then
  692. begin
  693. assignment_overloaded:=passproc;
  694. break;
  695. end;
  696. passproc:=passproc^.nextoverloaded;
  697. end;
  698. end;
  699. { local routines can't be assigned to procvars }
  700. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  701. begin
  702. if (from_def^.symtablelevel>1) and (to_def^.deftype=procvardef) then
  703. CGMessage(type_e_cannot_local_proc_to_procvar);
  704. end;
  705. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  706. var
  707. hp : ptree;
  708. gotsubscript,
  709. gotpointer,
  710. gotclass,
  711. gotderef : boolean;
  712. begin
  713. valid_for_assign:=false;
  714. gotsubscript:=false;
  715. gotderef:=false;
  716. gotclass:=false;
  717. gotpointer:=false;
  718. hp:=p;
  719. while assigned(hp) do
  720. begin
  721. { property allowed? calln has a property check itself }
  722. if (not allowprop) and
  723. (hp^.isproperty) and
  724. (hp^.treetype<>calln) then
  725. begin
  726. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  727. exit;
  728. end;
  729. case hp^.treetype of
  730. derefn :
  731. begin
  732. gotderef:=true;
  733. hp:=hp^.left;
  734. end;
  735. typeconvn :
  736. begin
  737. case hp^.resulttype^.deftype of
  738. pointerdef :
  739. gotpointer:=true;
  740. objectdef :
  741. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  742. classrefdef :
  743. gotclass:=true;
  744. arraydef :
  745. begin
  746. { pointer -> array conversion is done then we need to see it
  747. as a deref, because a ^ is then not required anymore }
  748. if (hp^.left^.resulttype^.deftype=pointerdef) then
  749. gotderef:=true;
  750. end;
  751. end;
  752. hp:=hp^.left;
  753. end;
  754. vecn,
  755. asn :
  756. hp:=hp^.left;
  757. subscriptn :
  758. begin
  759. gotsubscript:=true;
  760. hp:=hp^.left;
  761. end;
  762. subn,
  763. addn :
  764. begin
  765. { Allow add/sub operators on a pointer, or an integer
  766. and a pointer typecast and deref has been found }
  767. if (hp^.resulttype^.deftype=pointerdef) or
  768. (is_integer(hp^.resulttype) and gotpointer and gotderef) then
  769. valid_for_assign:=true
  770. else
  771. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  772. exit;
  773. end;
  774. addrn :
  775. begin
  776. if not(gotderef) and
  777. not(hp^.procvarload) then
  778. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_addr);
  779. exit;
  780. end;
  781. selfn,
  782. funcretn :
  783. begin
  784. valid_for_assign:=true;
  785. exit;
  786. end;
  787. calln :
  788. begin
  789. { check return type }
  790. case hp^.resulttype^.deftype of
  791. pointerdef :
  792. gotpointer:=true;
  793. objectdef :
  794. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  795. classrefdef :
  796. gotclass:=true;
  797. end;
  798. { 1. if it returns a pointer and we've found a deref,
  799. 2. if it returns a class and a subscription is found,
  800. 3. property is allowed }
  801. if (gotpointer and gotderef) or
  802. (gotclass and gotsubscript) or
  803. (hp^.isproperty and allowprop) then
  804. valid_for_assign:=true
  805. else
  806. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  807. exit;
  808. end;
  809. loadn :
  810. begin
  811. case hp^.symtableentry^.typ of
  812. absolutesym,
  813. varsym :
  814. begin
  815. if (pvarsym(hp^.symtableentry)^.varspez=vs_const) then
  816. begin
  817. { allow p^:= constructions with p is const parameter }
  818. if gotderef then
  819. valid_for_assign:=true
  820. else
  821. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_const);
  822. exit;
  823. end;
  824. { Are we at a with symtable, then we need to process the
  825. withrefnode also to check for maybe a const load }
  826. if (hp^.symtable^.symtabletype=withsymtable) then
  827. begin
  828. { continue with processing the withref node }
  829. hp:=ptree(pwithsymtable(hp^.symtable)^.withrefnode);
  830. end
  831. else
  832. begin
  833. { set the assigned flag for varsyms }
  834. if (pvarsym(hp^.symtableentry)^.varstate=vs_declared) then
  835. pvarsym(hp^.symtableentry)^.varstate:=vs_assigned;
  836. valid_for_assign:=true;
  837. exit;
  838. end;
  839. end;
  840. funcretsym,
  841. typedconstsym :
  842. begin
  843. valid_for_assign:=true;
  844. exit;
  845. end;
  846. end;
  847. end;
  848. else
  849. begin
  850. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  851. exit;
  852. end;
  853. end;
  854. end;
  855. end;
  856. end.
  857. {
  858. $Log$
  859. Revision 1.64 2000-06-01 19:13:02 peter
  860. * fixed long line for tp7
  861. Revision 1.63 2000/06/01 11:00:52 peter
  862. * fixed string->pchar conversion for array constructors
  863. Revision 1.62 2000/05/30 18:38:45 florian
  864. * fixed assignments of subrange enumeration types
  865. Revision 1.61 2000/05/26 18:21:41 peter
  866. * give error for @ with formal const,var parameter. Because @ generates
  867. a constant value and not a reference
  868. Revision 1.60 2000/05/16 16:01:03 florian
  869. * fixed type conversion test for open arrays: the to and from fields where
  870. exchanged which leads under certain circumstances to problems when
  871. passing arrays of classes/class references as open array parameters
  872. Revision 1.59 2000/02/18 16:13:29 florian
  873. * optimized ansistring compare with ''
  874. * fixed 852
  875. Revision 1.58 2000/02/09 13:22:53 peter
  876. * log truncated
  877. Revision 1.57 2000/02/05 12:11:50 peter
  878. * property check for assigning fixed for calln
  879. Revision 1.56 2000/02/01 09:41:27 peter
  880. * allow class -> voidpointer for delphi mode
  881. Revision 1.55 2000/01/07 01:14:27 peter
  882. * updated copyright to 2000
  883. Revision 1.54 1999/12/31 14:26:27 peter
  884. * fixed crash with empty array constructors
  885. Revision 1.53 1999/12/18 14:55:21 florian
  886. * very basic widestring support
  887. Revision 1.52 1999/12/16 19:12:04 peter
  888. * allow constant pointer^ also for assignment
  889. Revision 1.51 1999/12/09 09:35:54 peter
  890. * allow assigning to self
  891. Revision 1.50 1999/11/30 10:40:43 peter
  892. + ttype, tsymlist
  893. Revision 1.49 1999/11/18 15:34:45 pierre
  894. * Notes/Hints for local syms changed to
  895. Set_varstate function
  896. Revision 1.48 1999/11/09 14:47:03 peter
  897. * pointer->array is allowed for all pointer types in FPC, fixed assign
  898. check for it.
  899. Revision 1.47 1999/11/09 13:29:33 peter
  900. * valid_for_assign allow properties with calln
  901. Revision 1.46 1999/11/08 22:45:33 peter
  902. * allow typecasting to integer within pointer typecast+deref
  903. Revision 1.45 1999/11/06 14:34:21 peter
  904. * truncated log to 20 revs
  905. Revision 1.44 1999/11/04 23:11:21 peter
  906. * fixed pchar and deref detection for assigning
  907. Revision 1.43 1999/10/27 16:04:45 peter
  908. * valid_for_assign support for calln,asn
  909. Revision 1.42 1999/10/26 12:30:41 peter
  910. * const parameter is now checked
  911. * better and generic check if a node can be used for assigning
  912. * export fixes
  913. * procvar equal works now (it never had worked at least from 0.99.8)
  914. * defcoll changed to linkedlist with pparaitem so it can easily be
  915. walked both directions
  916. Revision 1.41 1999/10/14 14:57:52 florian
  917. - removed the hcodegen use in the new cg, use cgbase instead
  918. Revision 1.40 1999/09/26 21:30:15 peter
  919. + constant pointer support which can happend with typecasting like
  920. const p=pointer(1)
  921. * better procvar parsing in typed consts
  922. Revision 1.39 1999/09/17 17:14:04 peter
  923. * @procvar fixes for tp mode
  924. * @<id>:= gives now an error
  925. Revision 1.38 1999/08/17 13:26:07 peter
  926. * arrayconstructor -> arrayofconst fixed when arraycosntructor was not
  927. variant.
  928. }