htypechk.pas 46 KB

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