htypechk.pas 33 KB

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