htypechk.pas 35 KB

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