htypechk.pas 43 KB

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