htypechk.pas 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  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,
  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. { nil is compatible with class instances }
  423. if (fromtreetype=niln) and (pobjectdef(def_to)^.is_class) then
  424. begin
  425. doconv:=tc_equal;
  426. b:=1;
  427. end;
  428. end;
  429. classrefdef :
  430. begin
  431. { class reference types }
  432. if (def_from^.deftype=classrefdef) then
  433. begin
  434. doconv:=tc_equal;
  435. if pobjectdef(pclassrefdef(def_from)^.pointertype.def)^.is_related(
  436. pobjectdef(pclassrefdef(def_to)^.pointertype.def)) then
  437. b:=1;
  438. end
  439. else
  440. { nil is compatible with class references }
  441. if (fromtreetype=niln) then
  442. begin
  443. doconv:=tc_equal;
  444. b:=1;
  445. end;
  446. end;
  447. filedef :
  448. begin
  449. { typed files are all equal to the abstract file type
  450. name TYPEDFILE in system.pp in is_equal in types.pas
  451. the problem is that it sholud be also compatible to FILE
  452. but this would leed to a problem for ASSIGN RESET and REWRITE
  453. when trying to find the good overloaded function !!
  454. so all file function are doubled in system.pp
  455. this is not very beautiful !!}
  456. if (def_from^.deftype=filedef) and
  457. (
  458. (
  459. (pfiledef(def_from)^.filetyp = ft_typed) and
  460. (pfiledef(def_to)^.filetyp = ft_typed) and
  461. (
  462. (pfiledef(def_from)^.typedfiletype.def = pdef(voiddef)) or
  463. (pfiledef(def_to)^.typedfiletype.def = pdef(voiddef))
  464. )
  465. ) or
  466. (
  467. (
  468. (pfiledef(def_from)^.filetyp = ft_untyped) and
  469. (pfiledef(def_to)^.filetyp = ft_typed)
  470. ) or
  471. (
  472. (pfiledef(def_from)^.filetyp = ft_typed) and
  473. (pfiledef(def_to)^.filetyp = ft_untyped)
  474. )
  475. )
  476. ) then
  477. begin
  478. doconv:=tc_equal;
  479. b:=1;
  480. end
  481. end;
  482. else
  483. begin
  484. { assignment overwritten ?? }
  485. if assignment_overloaded(def_from,def_to)<>nil then
  486. b:=2;
  487. end;
  488. end;
  489. isconvertable:=b;
  490. end;
  491. {****************************************************************************
  492. Register Calculation
  493. ****************************************************************************}
  494. { marks an lvalue as "unregable" }
  495. procedure make_not_regable(p : ptree);
  496. begin
  497. case p^.treetype of
  498. typeconvn :
  499. make_not_regable(p^.left);
  500. loadn :
  501. if p^.symtableentry^.typ=varsym then
  502. pvarsym(p^.symtableentry)^.varoptions:=pvarsym(p^.symtableentry)^.varoptions-[vo_regable,vo_fpuregable];
  503. end;
  504. end;
  505. procedure left_right_max(p : ptree);
  506. begin
  507. if assigned(p^.left) then
  508. begin
  509. if assigned(p^.right) then
  510. begin
  511. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  512. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  513. {$ifdef SUPPORT_MMX}
  514. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  515. {$endif SUPPORT_MMX}
  516. end
  517. else
  518. begin
  519. p^.registers32:=p^.left^.registers32;
  520. p^.registersfpu:=p^.left^.registersfpu;
  521. {$ifdef SUPPORT_MMX}
  522. p^.registersmmx:=p^.left^.registersmmx;
  523. {$endif SUPPORT_MMX}
  524. end;
  525. end;
  526. end;
  527. { calculates the needed registers for a binary operator }
  528. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  529. begin
  530. left_right_max(p);
  531. { Only when the difference between the left and right registers < the
  532. wanted registers allocate the amount of registers }
  533. if assigned(p^.left) then
  534. begin
  535. if assigned(p^.right) then
  536. begin
  537. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  538. inc(p^.registers32,r32);
  539. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  540. inc(p^.registersfpu,fpu);
  541. {$ifdef SUPPORT_MMX}
  542. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  543. inc(p^.registersmmx,mmx);
  544. {$endif SUPPORT_MMX}
  545. end
  546. else
  547. begin
  548. if (p^.left^.registers32<r32) then
  549. inc(p^.registers32,r32);
  550. if (p^.left^.registersfpu<fpu) then
  551. inc(p^.registersfpu,fpu);
  552. {$ifdef SUPPORT_MMX}
  553. if (p^.left^.registersmmx<mmx) then
  554. inc(p^.registersmmx,mmx);
  555. {$endif SUPPORT_MMX}
  556. end;
  557. end;
  558. { error CGMessage, if more than 8 floating point }
  559. { registers are needed }
  560. if p^.registersfpu>8 then
  561. CGMessage(cg_e_too_complex_expr);
  562. end;
  563. {****************************************************************************
  564. Subroutine Handling
  565. ****************************************************************************}
  566. { protected field handling
  567. protected field can not appear in
  568. var parameters of function !!
  569. this can only be done after we have determined the
  570. overloaded function
  571. this is the reason why it is not in the parser, PM }
  572. procedure test_protected_sym(sym : psym);
  573. begin
  574. if (sp_protected in sym^.symoptions) and
  575. ((sym^.owner^.symtabletype=unitsymtable) or
  576. ((sym^.owner^.symtabletype=objectsymtable) and
  577. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))
  578. ) then
  579. CGMessage(parser_e_cant_access_protected_member);
  580. end;
  581. procedure test_protected(p : ptree);
  582. begin
  583. case p^.treetype of
  584. loadn : test_protected_sym(p^.symtableentry);
  585. typeconvn : test_protected(p^.left);
  586. derefn : test_protected(p^.left);
  587. subscriptn : begin
  588. { test_protected(p^.left);
  589. Is a field of a protected var
  590. also protected ??? PM }
  591. test_protected_sym(p^.vs);
  592. end;
  593. end;
  594. end;
  595. function valid_for_formal_var(p : ptree) : boolean;
  596. var
  597. v : boolean;
  598. begin
  599. case p^.treetype of
  600. loadn : v:=(p^.symtableentry^.typ in [typedconstsym,varsym]);
  601. typeconvn : v:=valid_for_formal_var(p^.left);
  602. typen : v:=false;
  603. derefn,subscriptn,vecn,
  604. funcretn,selfn : v:=true;
  605. { procvars are callnodes first }
  606. calln : v:=assigned(p^.right) and not assigned(p^.left);
  607. { should this depend on mode ? }
  608. addrn : v:=true;
  609. { no other node accepted (PM) }
  610. else v:=false;
  611. end;
  612. valid_for_formal_var:=v;
  613. end;
  614. function valid_for_formal_const(p : ptree) : boolean;
  615. var
  616. v : boolean;
  617. begin
  618. { p must have been firstpass'd before }
  619. { accept about anything but not a statement ! }
  620. v:=true;
  621. if (p^.treetype in [calln,statementn]) then
  622. { if not assigned(p^.resulttype) or (p^.resulttype=pdef(voiddef)) then }
  623. v:=false;
  624. valid_for_formal_const:=v;
  625. end;
  626. function is_procsym_load(p:Ptree):boolean;
  627. begin
  628. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  629. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  630. and (p^.left^.symtableentry^.typ=procsym)) ;
  631. end;
  632. { change a proc call to a procload for assignment to a procvar }
  633. { this can only happen for proc/function without arguments }
  634. function is_procsym_call(p:Ptree):boolean;
  635. begin
  636. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  637. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  638. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  639. end;
  640. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  641. var
  642. passproc : pprocdef;
  643. convtyp : tconverttype;
  644. begin
  645. assignment_overloaded:=nil;
  646. if assigned(overloaded_operators[_assignment]) then
  647. passproc:=overloaded_operators[_assignment]^.definition
  648. else
  649. exit;
  650. while passproc<>nil do
  651. begin
  652. if is_equal(passproc^.rettype.def,to_def) and
  653. (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
  654. (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,ordconstn,false)=1)) then
  655. begin
  656. assignment_overloaded:=passproc;
  657. break;
  658. end;
  659. passproc:=passproc^.nextoverloaded;
  660. end;
  661. end;
  662. { local routines can't be assigned to procvars }
  663. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  664. begin
  665. if (from_def^.symtablelevel>1) and (to_def^.deftype=procvardef) then
  666. CGMessage(type_e_cannot_local_proc_to_procvar);
  667. end;
  668. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  669. var
  670. hp : ptree;
  671. gotpointer,
  672. gotderef : boolean;
  673. begin
  674. valid_for_assign:=false;
  675. gotderef:=false;
  676. gotpointer:=false;
  677. hp:=p;
  678. while assigned(hp) do
  679. begin
  680. if (not allowprop) and
  681. (hp^.isproperty) then
  682. begin
  683. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  684. exit;
  685. end;
  686. case hp^.treetype of
  687. derefn :
  688. begin
  689. gotderef:=true;
  690. hp:=hp^.left;
  691. end;
  692. typeconvn :
  693. begin
  694. if hp^.resulttype^.deftype=pointerdef then
  695. gotpointer:=true;
  696. { pointer -> array conversion is done then we need to see it
  697. as a deref, because a ^ is then not required anymore }
  698. if (hp^.resulttype^.deftype=arraydef) and
  699. (hp^.left^.resulttype^.deftype=pointerdef) then
  700. gotderef:=true;
  701. hp:=hp^.left;
  702. end;
  703. vecn,
  704. asn,
  705. subscriptn :
  706. hp:=hp^.left;
  707. subn,
  708. addn :
  709. begin
  710. { Allow add/sub operators on a pointer, or an integer
  711. and a pointer typecast and deref has been found }
  712. if (hp^.resulttype^.deftype=pointerdef) or
  713. (is_integer(hp^.resulttype) and gotpointer and gotderef) then
  714. valid_for_assign:=true
  715. else
  716. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  717. exit;
  718. end;
  719. addrn :
  720. begin
  721. if not(gotderef) and
  722. not(hp^.procvarload) then
  723. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_addr);
  724. exit;
  725. end;
  726. selfn,
  727. funcretn :
  728. begin
  729. valid_for_assign:=true;
  730. exit;
  731. end;
  732. calln :
  733. begin
  734. { only allow writing if it returns a pointer and we've
  735. found a deref }
  736. if ((hp^.resulttype^.deftype=pointerdef) and gotderef) or
  737. (hp^.isproperty and allowprop) then
  738. valid_for_assign:=true
  739. else
  740. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  741. exit;
  742. end;
  743. loadn :
  744. begin
  745. case hp^.symtableentry^.typ of
  746. absolutesym,
  747. varsym :
  748. begin
  749. if (pvarsym(hp^.symtableentry)^.varspez=vs_const) then
  750. begin
  751. { allow p^:= constructions with p is const parameter }
  752. if gotderef then
  753. valid_for_assign:=true
  754. else
  755. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_const);
  756. exit;
  757. end;
  758. { Are we at a with symtable, then we need to process the
  759. withrefnode also to check for maybe a const load }
  760. if (hp^.symtable^.symtabletype=withsymtable) then
  761. begin
  762. { continue with processing the withref node }
  763. hp:=ptree(pwithsymtable(hp^.symtable)^.withrefnode);
  764. end
  765. else
  766. begin
  767. { set the assigned flag for varsyms }
  768. if (pvarsym(hp^.symtableentry)^.varstate=vs_declared) then
  769. pvarsym(hp^.symtableentry)^.varstate:=vs_assigned;
  770. valid_for_assign:=true;
  771. exit;
  772. end;
  773. end;
  774. funcretsym,
  775. typedconstsym :
  776. begin
  777. valid_for_assign:=true;
  778. exit;
  779. end;
  780. end;
  781. end;
  782. else
  783. begin
  784. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  785. exit;
  786. end;
  787. end;
  788. end;
  789. end;
  790. end.
  791. {
  792. $Log$
  793. Revision 1.55 2000-01-07 01:14:27 peter
  794. * updated copyright to 2000
  795. Revision 1.54 1999/12/31 14:26:27 peter
  796. * fixed crash with empty array constructors
  797. Revision 1.53 1999/12/18 14:55:21 florian
  798. * very basic widestring support
  799. Revision 1.52 1999/12/16 19:12:04 peter
  800. * allow constant pointer^ also for assignment
  801. Revision 1.51 1999/12/09 09:35:54 peter
  802. * allow assigning to self
  803. Revision 1.50 1999/11/30 10:40:43 peter
  804. + ttype, tsymlist
  805. Revision 1.49 1999/11/18 15:34:45 pierre
  806. * Notes/Hints for local syms changed to
  807. Set_varstate function
  808. Revision 1.48 1999/11/09 14:47:03 peter
  809. * pointer->array is allowed for all pointer types in FPC, fixed assign
  810. check for it.
  811. Revision 1.47 1999/11/09 13:29:33 peter
  812. * valid_for_assign allow properties with calln
  813. Revision 1.46 1999/11/08 22:45:33 peter
  814. * allow typecasting to integer within pointer typecast+deref
  815. Revision 1.45 1999/11/06 14:34:21 peter
  816. * truncated log to 20 revs
  817. Revision 1.44 1999/11/04 23:11:21 peter
  818. * fixed pchar and deref detection for assigning
  819. Revision 1.43 1999/10/27 16:04:45 peter
  820. * valid_for_assign support for calln,asn
  821. Revision 1.42 1999/10/26 12:30:41 peter
  822. * const parameter is now checked
  823. * better and generic check if a node can be used for assigning
  824. * export fixes
  825. * procvar equal works now (it never had worked at least from 0.99.8)
  826. * defcoll changed to linkedlist with pparaitem so it can easily be
  827. walked both directions
  828. Revision 1.41 1999/10/14 14:57:52 florian
  829. - removed the hcodegen use in the new cg, use cgbase instead
  830. Revision 1.40 1999/09/26 21:30:15 peter
  831. + constant pointer support which can happend with typecasting like
  832. const p=pointer(1)
  833. * better procvar parsing in typed consts
  834. Revision 1.39 1999/09/17 17:14:04 peter
  835. * @procvar fixes for tp mode
  836. * @<id>:= gives now an error
  837. Revision 1.38 1999/08/17 13:26:07 peter
  838. * arrayconstructor -> arrayofconst fixed when arraycosntructor was not
  839. variant.
  840. Revision 1.37 1999/08/16 23:23:38 peter
  841. * arrayconstructor -> openarray type conversions for element types
  842. Revision 1.36 1999/08/06 12:49:36 jonas
  843. * vo_fpuregable is now also removed in make_not_regable
  844. Revision 1.35 1999/08/05 21:50:35 peter
  845. * removed warning
  846. Revision 1.34 1999/08/05 16:52:55 peter
  847. * V_Fatal=1, all other V_ are also increased
  848. * Check for local procedure when assigning procvar
  849. * fixed comment parsing because directives
  850. * oldtp mode directives better supported
  851. * added some messages to errore.msg
  852. Revision 1.33 1999/08/04 13:02:43 jonas
  853. * all tokens now start with an underscore
  854. * PowerPC compiles!!
  855. Revision 1.32 1999/08/03 22:02:53 peter
  856. * moved bitmask constants to sets
  857. * some other type/const renamings
  858. Revision 1.31 1999/07/16 10:04:32 peter
  859. * merged
  860. Revision 1.30 1999/06/28 16:02:30 peter
  861. * merged
  862. Revision 1.27.2.4 1999/07/16 09:52:18 peter
  863. * allow char(enum)
  864. Revision 1.27.2.3 1999/06/28 15:51:27 peter
  865. * tp7 fix
  866. Revision 1.27.2.2 1999/06/18 10:56:58 daniel
  867. - Enumerations no longer compatible with integer types
  868. Revision 1.27.2.1 1999/06/17 12:51:42 pierre
  869. * changed is_assignment_overloaded into
  870. function assignment_overloaded : pprocdef
  871. to allow overloading of assignment with only different result type
  872. Revision 1.27 1999/06/01 19:27:47 peter
  873. * better checks for procvar and methodpointer
  874. }