htypechk.pas 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153
  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. cutils,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. { because of packenum they can have different sizes! (JM) }
  272. doconv:=tc_int_2_int;
  273. end;
  274. end;
  275. end;
  276. arraydef :
  277. begin
  278. { open array is also compatible with a single element of its base type }
  279. if is_open_array(def_to) and
  280. is_equal(parraydef(def_to)^.elementtype.def,def_from) then
  281. begin
  282. doconv:=tc_equal;
  283. b:=1;
  284. end
  285. else
  286. begin
  287. case def_from^.deftype of
  288. arraydef :
  289. begin
  290. { array constructor -> open array }
  291. if is_open_array(def_to) and
  292. is_array_constructor(def_from) then
  293. begin
  294. if is_void(parraydef(def_from)^.elementtype.def) or
  295. is_equal(parraydef(def_to)^.elementtype.def,parraydef(def_from)^.elementtype.def) then
  296. begin
  297. doconv:=tc_equal;
  298. b:=1;
  299. end
  300. else
  301. if isconvertable(parraydef(def_from)^.elementtype.def,
  302. parraydef(def_to)^.elementtype.def,hct,arrayconstructn,false)<>0 then
  303. begin
  304. doconv:=hct;
  305. b:=2;
  306. end;
  307. end;
  308. end;
  309. pointerdef :
  310. begin
  311. if is_zero_based_array(def_to) and
  312. is_equal(ppointerdef(def_from)^.pointertype.def,parraydef(def_to)^.elementtype.def) then
  313. begin
  314. doconv:=tc_pointer_2_array;
  315. b:=1;
  316. end;
  317. end;
  318. stringdef :
  319. begin
  320. { string to array of char}
  321. if (not(is_special_array(def_to)) or is_open_array(def_to)) and
  322. is_equal(parraydef(def_to)^.elementtype.def,cchardef) then
  323. begin
  324. doconv:=tc_string_2_chararray;
  325. b:=1;
  326. end;
  327. end;
  328. end;
  329. end;
  330. end;
  331. pointerdef :
  332. begin
  333. case def_from^.deftype of
  334. stringdef :
  335. begin
  336. { string constant (which can be part of array constructor)
  337. to zero terminated string constant }
  338. if (fromtreetype in [arrayconstructn,stringconstn]) and
  339. is_pchar(def_to) then
  340. begin
  341. doconv:=tc_cstring_2_pchar;
  342. b:=1;
  343. end;
  344. end;
  345. orddef :
  346. begin
  347. { char constant to zero terminated string constant }
  348. if (fromtreetype=ordconstn) then
  349. begin
  350. if is_equal(def_from,cchardef) and
  351. is_pchar(def_to) then
  352. begin
  353. doconv:=tc_cchar_2_pchar;
  354. b:=1;
  355. end
  356. else
  357. if is_integer(def_from) then
  358. begin
  359. doconv:=tc_cord_2_pointer;
  360. b:=1;
  361. end;
  362. end;
  363. end;
  364. arraydef :
  365. begin
  366. { chararray to pointer }
  367. if is_zero_based_array(def_from) and
  368. is_equal(parraydef(def_from)^.elementtype.def,ppointerdef(def_to)^.pointertype.def) then
  369. begin
  370. doconv:=tc_array_2_pointer;
  371. b:=1;
  372. end;
  373. end;
  374. pointerdef :
  375. begin
  376. { child class pointer can be assigned to anchestor pointers }
  377. if (
  378. (ppointerdef(def_from)^.pointertype.def^.deftype=objectdef) and
  379. (ppointerdef(def_to)^.pointertype.def^.deftype=objectdef) and
  380. pobjectdef(ppointerdef(def_from)^.pointertype.def)^.is_related(
  381. pobjectdef(ppointerdef(def_to)^.pointertype.def))
  382. ) or
  383. { all pointers can be assigned to void-pointer }
  384. is_equal(ppointerdef(def_to)^.pointertype.def,voiddef) or
  385. { in my opnion, is this not clean pascal }
  386. { well, but it's handy to use, it isn't ? (FK) }
  387. is_equal(ppointerdef(def_from)^.pointertype.def,voiddef) then
  388. begin
  389. doconv:=tc_equal;
  390. b:=1;
  391. end;
  392. end;
  393. procvardef :
  394. begin
  395. { procedure variable can be assigned to an void pointer }
  396. { Not anymore. Use the @ operator now.}
  397. if not(m_tp_procvar in aktmodeswitches) and
  398. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  399. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  400. begin
  401. doconv:=tc_equal;
  402. b:=1;
  403. end;
  404. end;
  405. classrefdef,
  406. objectdef :
  407. begin
  408. { class types and class reference type
  409. can be assigned to void pointers }
  410. if (
  411. ((def_from^.deftype=objectdef) and pobjectdef(def_from)^.is_class) or
  412. (def_from^.deftype=classrefdef)
  413. ) and
  414. (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
  415. (porddef(ppointerdef(def_to)^.pointertype.def)^.typ=uvoid) then
  416. begin
  417. doconv:=tc_equal;
  418. b:=1;
  419. end;
  420. end;
  421. end;
  422. end;
  423. setdef :
  424. begin
  425. { automatic arrayconstructor -> set conversion }
  426. if is_array_constructor(def_from) then
  427. begin
  428. doconv:=tc_arrayconstructor_2_set;
  429. b:=1;
  430. end;
  431. end;
  432. procvardef :
  433. begin
  434. { proc -> procvar }
  435. if (def_from^.deftype=procdef) then
  436. begin
  437. doconv:=tc_proc_2_procvar;
  438. if proc_to_procvar_equal(pprocdef(def_from),pprocvardef(def_to)) then
  439. b:=1;
  440. end
  441. else
  442. { for example delphi allows the assignement from pointers }
  443. { to procedure variables }
  444. if (m_pointer_2_procedure in aktmodeswitches) and
  445. (def_from^.deftype=pointerdef) and
  446. (ppointerdef(def_from)^.pointertype.def^.deftype=orddef) and
  447. (porddef(ppointerdef(def_from)^.pointertype.def)^.typ=uvoid) then
  448. begin
  449. doconv:=tc_equal;
  450. b:=1;
  451. end
  452. else
  453. { nil is compatible with procvars }
  454. if (fromtreetype=niln) then
  455. begin
  456. doconv:=tc_equal;
  457. b:=1;
  458. end;
  459. end;
  460. objectdef :
  461. begin
  462. { object pascal objects }
  463. if (def_from^.deftype=objectdef) {and
  464. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  465. begin
  466. doconv:=tc_equal;
  467. if pobjectdef(def_from)^.is_related(pobjectdef(def_to)) then
  468. b:=1;
  469. end
  470. else
  471. { Class specific }
  472. if (pobjectdef(def_to)^.is_class) then
  473. begin
  474. { void pointer also for delphi mode }
  475. if (m_delphi in aktmodeswitches) and
  476. is_voidpointer(def_from) then
  477. begin
  478. doconv:=tc_equal;
  479. b:=1;
  480. end
  481. else
  482. { nil is compatible with class instances }
  483. if (fromtreetype=niln) and (pobjectdef(def_to)^.is_class) then
  484. begin
  485. doconv:=tc_equal;
  486. b:=1;
  487. end;
  488. end;
  489. end;
  490. classrefdef :
  491. begin
  492. { class reference types }
  493. if (def_from^.deftype=classrefdef) then
  494. begin
  495. doconv:=tc_equal;
  496. if pobjectdef(pclassrefdef(def_from)^.pointertype.def)^.is_related(
  497. pobjectdef(pclassrefdef(def_to)^.pointertype.def)) then
  498. b:=1;
  499. end
  500. else
  501. { nil is compatible with class references }
  502. if (fromtreetype=niln) then
  503. begin
  504. doconv:=tc_equal;
  505. b:=1;
  506. end;
  507. end;
  508. filedef :
  509. begin
  510. { typed files are all equal to the abstract file type
  511. name TYPEDFILE in system.pp in is_equal in types.pas
  512. the problem is that it sholud be also compatible to FILE
  513. but this would leed to a problem for ASSIGN RESET and REWRITE
  514. when trying to find the good overloaded function !!
  515. so all file function are doubled in system.pp
  516. this is not very beautiful !!}
  517. if (def_from^.deftype=filedef) and
  518. (
  519. (
  520. (pfiledef(def_from)^.filetyp = ft_typed) and
  521. (pfiledef(def_to)^.filetyp = ft_typed) and
  522. (
  523. (pfiledef(def_from)^.typedfiletype.def = pdef(voiddef)) or
  524. (pfiledef(def_to)^.typedfiletype.def = pdef(voiddef))
  525. )
  526. ) or
  527. (
  528. (
  529. (pfiledef(def_from)^.filetyp = ft_untyped) and
  530. (pfiledef(def_to)^.filetyp = ft_typed)
  531. ) or
  532. (
  533. (pfiledef(def_from)^.filetyp = ft_typed) and
  534. (pfiledef(def_to)^.filetyp = ft_untyped)
  535. )
  536. )
  537. ) then
  538. begin
  539. doconv:=tc_equal;
  540. b:=1;
  541. end
  542. end;
  543. else
  544. begin
  545. { assignment overwritten ?? }
  546. if assignment_overloaded(def_from,def_to)<>nil then
  547. b:=2;
  548. end;
  549. end;
  550. isconvertable:=b;
  551. end;
  552. { ld is the left type definition
  553. rd the right type definition
  554. dd the result type definition or voiddef if unkown }
  555. function isbinaryoperatoroverloadable(ld, rd, dd : pdef;
  556. treetyp : ttreetyp) : boolean;
  557. begin
  558. isbinaryoperatoroverloadable:=
  559. (treetyp=starstarn) or
  560. (ld^.deftype=recorddef) or
  561. (rd^.deftype=recorddef) or
  562. ((rd^.deftype=pointerdef) and
  563. not(is_pchar(rd) and
  564. (is_chararray(ld) or
  565. (ld^.deftype=stringdef) or
  566. (treetyp=addn))) and
  567. (not(ld^.deftype in [pointerdef,objectdef,classrefdef,procvardef]) or
  568. not (treetyp in [equaln,unequaln,gtn,gten,ltn,lten,subn])
  569. ) and
  570. (not is_integer(ld) or not (treetyp in [addn,subn]))
  571. ) or
  572. ((ld^.deftype=pointerdef) and
  573. not(is_pchar(ld) and
  574. (is_chararray(rd) or
  575. (rd^.deftype=stringdef) or
  576. (treetyp=addn))) and
  577. (not(rd^.deftype in [stringdef,pointerdef,objectdef,classrefdef,procvardef]) and
  578. ((not is_integer(rd) and (rd^.deftype<>objectdef)
  579. and (rd^.deftype<>classrefdef)) or
  580. not (treetyp in [equaln,unequaln,gtn,gten,ltn,lten,addn,subn])
  581. )
  582. )
  583. ) or
  584. { array def, but not mmx or chararray+[char,string,chararray] }
  585. ((ld^.deftype=arraydef) and
  586. not((cs_mmx in aktlocalswitches) and
  587. is_mmx_able_array(ld)) and
  588. not(is_chararray(ld) and
  589. (is_char(rd) or
  590. is_pchar(rd) or
  591. (rd^.deftype=stringdef) or
  592. is_chararray(rd)))
  593. ) or
  594. ((rd^.deftype=arraydef) and
  595. not((cs_mmx in aktlocalswitches) and
  596. is_mmx_able_array(rd)) and
  597. not(is_chararray(rd) and
  598. (is_char(ld) or
  599. is_pchar(ld) or
  600. (ld^.deftype=stringdef) or
  601. is_chararray(ld)))
  602. ) or
  603. { <> and = are defined for classes }
  604. ((ld^.deftype=objectdef) and
  605. (not(pobjectdef(ld)^.is_class) or
  606. not(treetyp in [equaln,unequaln])
  607. )
  608. ) or
  609. ((rd^.deftype=objectdef) and
  610. (not(pobjectdef(rd)^.is_class) or
  611. not(treetyp in [equaln,unequaln])
  612. )
  613. or
  614. { allow other operators that + on strings }
  615. (
  616. (is_char(rd) or
  617. is_pchar(rd) or
  618. (rd^.deftype=stringdef) or
  619. is_chararray(rd) or
  620. is_char(ld) or
  621. is_pchar(ld) or
  622. (ld^.deftype=stringdef) or
  623. is_chararray(ld)
  624. ) and
  625. not(treetyp in [addn,equaln,unequaln,gtn,gten,ltn,lten]) and
  626. not(is_pchar(ld) and
  627. (is_integer(rd) or (rd^.deftype=pointerdef)) and
  628. (treetyp=subn)
  629. )
  630. )
  631. );
  632. end;
  633. function isunaryoperatoroverloadable(rd,dd : pdef;
  634. treetyp : ttreetyp) : boolean;
  635. begin
  636. isunaryoperatoroverloadable:=false;
  637. { what assignment overloading should be allowed ?? }
  638. if (treetyp=assignn) then
  639. begin
  640. isunaryoperatoroverloadable:=true;
  641. { this already get tbs0261 to fail
  642. isunaryoperatoroverloadable:=not is_equal(rd,dd); PM }
  643. end
  644. { should we force that rd and dd are equal ?? }
  645. else if (treetyp=subn { unaryminusn }) then
  646. begin
  647. isunaryoperatoroverloadable:=
  648. not is_integer(rd) and not (rd^.deftype=floatdef)
  649. {$ifdef SUPPORT_MMX}
  650. and not ((cs_mmx in aktlocalswitches) and
  651. is_mmx_able_array(rd))
  652. {$endif SUPPORT_MMX}
  653. ;
  654. end
  655. else if (treetyp=notn) then
  656. begin
  657. isunaryoperatoroverloadable:=not is_integer(rd) and not is_boolean(rd)
  658. {$ifdef SUPPORT_MMX}
  659. and not ((cs_mmx in aktlocalswitches) and
  660. is_mmx_able_array(rd))
  661. {$endif SUPPORT_MMX}
  662. ;
  663. end;
  664. end;
  665. function isoperatoracceptable(pf : pprocdef; optoken : ttoken) : boolean;
  666. var
  667. ld,rd,dd : pdef;
  668. i : longint;
  669. begin
  670. case pf^.parast^.symindex^.count of
  671. 2 : begin
  672. isoperatoracceptable:=false;
  673. for i:=1 to tok2nodes do
  674. if tok2node[i].tok=optoken then
  675. begin
  676. ld:=pvarsym(pf^.parast^.symindex^.first)^.vartype.def;
  677. rd:=pvarsym(pf^.parast^.symindex^.first^.indexnext)^.vartype.def;
  678. dd:=pf^.rettype.def;
  679. isoperatoracceptable:=
  680. tok2node[i].op_overloading_supported and
  681. isbinaryoperatoroverloadable(ld,rd,dd,tok2node[i].nod);
  682. break;
  683. end;
  684. end;
  685. 1 : begin
  686. rd:=pvarsym(pf^.parast^.symindex^.first)^.vartype.def;
  687. dd:=pf^.rettype.def;
  688. for i:=1 to tok2nodes do
  689. if tok2node[i].tok=optoken then
  690. begin
  691. isoperatoracceptable:=
  692. tok2node[i].op_overloading_supported and
  693. isunaryoperatoroverloadable(rd,dd,tok2node[i].nod);
  694. break;
  695. end;
  696. end;
  697. else
  698. isoperatoracceptable:=false;
  699. end;
  700. end;
  701. {****************************************************************************
  702. Register Calculation
  703. ****************************************************************************}
  704. { marks an lvalue as "unregable" }
  705. procedure make_not_regable(p : ptree);
  706. begin
  707. case p^.treetype of
  708. typeconvn :
  709. make_not_regable(p^.left);
  710. loadn :
  711. if p^.symtableentry^.typ=varsym then
  712. pvarsym(p^.symtableentry)^.varoptions:=pvarsym(p^.symtableentry)^.varoptions-[vo_regable,vo_fpuregable];
  713. end;
  714. end;
  715. procedure left_right_max(p : ptree);
  716. begin
  717. if assigned(p^.left) then
  718. begin
  719. if assigned(p^.right) then
  720. begin
  721. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  722. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  723. {$ifdef SUPPORT_MMX}
  724. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  725. {$endif SUPPORT_MMX}
  726. end
  727. else
  728. begin
  729. p^.registers32:=p^.left^.registers32;
  730. p^.registersfpu:=p^.left^.registersfpu;
  731. {$ifdef SUPPORT_MMX}
  732. p^.registersmmx:=p^.left^.registersmmx;
  733. {$endif SUPPORT_MMX}
  734. end;
  735. end;
  736. end;
  737. { calculates the needed registers for a binary operator }
  738. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  739. begin
  740. left_right_max(p);
  741. { Only when the difference between the left and right registers < the
  742. wanted registers allocate the amount of registers }
  743. if assigned(p^.left) then
  744. begin
  745. if assigned(p^.right) then
  746. begin
  747. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  748. inc(p^.registers32,r32);
  749. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  750. inc(p^.registersfpu,fpu);
  751. {$ifdef SUPPORT_MMX}
  752. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  753. inc(p^.registersmmx,mmx);
  754. {$endif SUPPORT_MMX}
  755. { the following is a little bit guessing but I think }
  756. { it's the only way to solve same internalerrors: }
  757. { if the left and right node both uses registers }
  758. { and return a mem location, but the current node }
  759. { doesn't use an integer register we get probably }
  760. { trouble when restoring a node }
  761. if (p^.left^.registers32=p^.right^.registers32) and
  762. (p^.registers32=p^.left^.registers32) and
  763. (p^.registers32>0) and
  764. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM]) and
  765. (p^.right^.location.loc in [LOC_REFERENCE,LOC_MEM]) then
  766. inc(p^.registers32);
  767. end
  768. else
  769. begin
  770. if (p^.left^.registers32<r32) then
  771. inc(p^.registers32,r32);
  772. if (p^.left^.registersfpu<fpu) then
  773. inc(p^.registersfpu,fpu);
  774. {$ifdef SUPPORT_MMX}
  775. if (p^.left^.registersmmx<mmx) then
  776. inc(p^.registersmmx,mmx);
  777. {$endif SUPPORT_MMX}
  778. end;
  779. end;
  780. { error CGMessage, if more than 8 floating point }
  781. { registers are needed }
  782. if p^.registersfpu>8 then
  783. CGMessage(cg_e_too_complex_expr);
  784. end;
  785. {****************************************************************************
  786. Subroutine Handling
  787. ****************************************************************************}
  788. { protected field handling
  789. protected field can not appear in
  790. var parameters of function !!
  791. this can only be done after we have determined the
  792. overloaded function
  793. this is the reason why it is not in the parser, PM }
  794. procedure test_protected_sym(sym : psym);
  795. begin
  796. if (sp_protected in sym^.symoptions) and
  797. ((sym^.owner^.symtabletype=unitsymtable) or
  798. ((sym^.owner^.symtabletype=objectsymtable) and
  799. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))
  800. ) then
  801. CGMessage(parser_e_cant_access_protected_member);
  802. end;
  803. procedure test_protected(p : ptree);
  804. begin
  805. case p^.treetype of
  806. loadn : test_protected_sym(p^.symtableentry);
  807. typeconvn : test_protected(p^.left);
  808. derefn : test_protected(p^.left);
  809. subscriptn : begin
  810. { test_protected(p^.left);
  811. Is a field of a protected var
  812. also protected ??? PM }
  813. test_protected_sym(p^.vs);
  814. end;
  815. end;
  816. end;
  817. function valid_for_formal_var(p : ptree) : boolean;
  818. var
  819. v : boolean;
  820. begin
  821. case p^.treetype of
  822. loadn :
  823. v:=(p^.symtableentry^.typ in [typedconstsym,varsym]);
  824. typeconvn :
  825. v:=valid_for_formal_var(p^.left);
  826. derefn,
  827. subscriptn,
  828. vecn,
  829. funcretn,
  830. selfn :
  831. v:=true;
  832. calln : { procvars are callnodes first }
  833. v:=assigned(p^.right) and not assigned(p^.left);
  834. addrn :
  835. begin
  836. { addrn is not allowed as this generate a constant value,
  837. but a tp procvar are allowed (PFV) }
  838. if p^.procvarload then
  839. v:=true
  840. else
  841. v:=false;
  842. end;
  843. else
  844. v:=false;
  845. end;
  846. valid_for_formal_var:=v;
  847. end;
  848. function valid_for_formal_const(p : ptree) : boolean;
  849. var
  850. v : boolean;
  851. begin
  852. { p must have been firstpass'd before }
  853. { accept about anything but not a statement ! }
  854. case p^.treetype of
  855. calln,
  856. statementn,
  857. addrn :
  858. begin
  859. { addrn is not allowed as this generate a constant value,
  860. but a tp procvar are allowed (PFV) }
  861. if p^.procvarload then
  862. v:=true
  863. else
  864. v:=false;
  865. end;
  866. else
  867. v:=true;
  868. end;
  869. valid_for_formal_const:=v;
  870. end;
  871. function is_procsym_load(p:Ptree):boolean;
  872. begin
  873. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  874. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  875. and (p^.left^.symtableentry^.typ=procsym)) ;
  876. end;
  877. { change a proc call to a procload for assignment to a procvar }
  878. { this can only happen for proc/function without arguments }
  879. function is_procsym_call(p:Ptree):boolean;
  880. begin
  881. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  882. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  883. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  884. end;
  885. function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
  886. var
  887. passproc : pprocdef;
  888. convtyp : tconverttype;
  889. begin
  890. assignment_overloaded:=nil;
  891. if assigned(overloaded_operators[_assignment]) then
  892. passproc:=overloaded_operators[_assignment]^.definition
  893. else
  894. exit;
  895. while passproc<>nil do
  896. begin
  897. if is_equal(passproc^.rettype.def,to_def) and
  898. (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
  899. (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,ordconstn,false)=1)) then
  900. begin
  901. assignment_overloaded:=passproc;
  902. break;
  903. end;
  904. passproc:=passproc^.nextoverloaded;
  905. end;
  906. end;
  907. { local routines can't be assigned to procvars }
  908. procedure test_local_to_procvar(from_def:pprocvardef;to_def:pdef);
  909. begin
  910. if (from_def^.symtablelevel>1) and (to_def^.deftype=procvardef) then
  911. CGMessage(type_e_cannot_local_proc_to_procvar);
  912. end;
  913. function valid_for_assign(p:ptree;allowprop:boolean):boolean;
  914. var
  915. hp : ptree;
  916. gotwith,
  917. gotsubscript,
  918. gotpointer,
  919. gotclass,
  920. gotderef : boolean;
  921. begin
  922. valid_for_assign:=false;
  923. gotsubscript:=false;
  924. gotderef:=false;
  925. gotclass:=false;
  926. gotpointer:=false;
  927. gotwith:=false;
  928. hp:=p;
  929. while assigned(hp) do
  930. begin
  931. { property allowed? calln has a property check itself }
  932. if (not allowprop) and
  933. (hp^.isproperty) and
  934. (hp^.treetype<>calln) then
  935. begin
  936. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  937. exit;
  938. end;
  939. case hp^.treetype of
  940. derefn :
  941. begin
  942. gotderef:=true;
  943. hp:=hp^.left;
  944. end;
  945. typeconvn :
  946. begin
  947. case hp^.resulttype^.deftype of
  948. pointerdef :
  949. gotpointer:=true;
  950. objectdef :
  951. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  952. classrefdef :
  953. gotclass:=true;
  954. arraydef :
  955. begin
  956. { pointer -> array conversion is done then we need to see it
  957. as a deref, because a ^ is then not required anymore }
  958. if (hp^.left^.resulttype^.deftype=pointerdef) then
  959. gotderef:=true;
  960. end;
  961. end;
  962. hp:=hp^.left;
  963. end;
  964. vecn,
  965. asn :
  966. hp:=hp^.left;
  967. subscriptn :
  968. begin
  969. gotsubscript:=true;
  970. hp:=hp^.left;
  971. end;
  972. subn,
  973. addn :
  974. begin
  975. { Allow add/sub operators on a pointer, or an integer
  976. and a pointer typecast and deref has been found }
  977. if (hp^.resulttype^.deftype=pointerdef) or
  978. (is_integer(hp^.resulttype) and gotpointer and gotderef) then
  979. valid_for_assign:=true
  980. else
  981. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  982. exit;
  983. end;
  984. addrn :
  985. begin
  986. if not(gotderef) and
  987. not(hp^.procvarload) then
  988. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_addr);
  989. exit;
  990. end;
  991. selfn,
  992. funcretn :
  993. begin
  994. valid_for_assign:=true;
  995. exit;
  996. end;
  997. calln :
  998. begin
  999. { check return type }
  1000. case hp^.resulttype^.deftype of
  1001. pointerdef :
  1002. gotpointer:=true;
  1003. objectdef :
  1004. gotclass:=pobjectdef(hp^.resulttype)^.is_class;
  1005. recorddef, { handle record like class it needs a subscription }
  1006. classrefdef :
  1007. gotclass:=true;
  1008. end;
  1009. { 1. if it returns a pointer and we've found a deref,
  1010. 2. if it returns a class or record and a subscription or with is found,
  1011. 3. property is allowed }
  1012. if (gotpointer and gotderef) or
  1013. (gotclass and (gotsubscript or gotwith)) or
  1014. (hp^.isproperty and allowprop) then
  1015. valid_for_assign:=true
  1016. else
  1017. CGMessagePos(hp^.fileinfo,type_e_argument_cant_be_assigned);
  1018. exit;
  1019. end;
  1020. loadn :
  1021. begin
  1022. case hp^.symtableentry^.typ of
  1023. absolutesym,
  1024. varsym :
  1025. begin
  1026. if (pvarsym(hp^.symtableentry)^.varspez=vs_const) then
  1027. begin
  1028. { allow p^:= constructions with p is const parameter }
  1029. if gotderef then
  1030. valid_for_assign:=true
  1031. else
  1032. CGMessagePos(hp^.fileinfo,type_e_no_assign_to_const);
  1033. exit;
  1034. end;
  1035. { Are we at a with symtable, then we need to process the
  1036. withrefnode also to check for maybe a const load }
  1037. if (hp^.symtable^.symtabletype=withsymtable) then
  1038. begin
  1039. { continue with processing the withref node }
  1040. hp:=ptree(pwithsymtable(hp^.symtable)^.withrefnode);
  1041. gotwith:=true;
  1042. end
  1043. else
  1044. begin
  1045. { set the assigned flag for varsyms }
  1046. if (pvarsym(hp^.symtableentry)^.varstate=vs_declared) then
  1047. pvarsym(hp^.symtableentry)^.varstate:=vs_assigned;
  1048. valid_for_assign:=true;
  1049. exit;
  1050. end;
  1051. end;
  1052. funcretsym,
  1053. typedconstsym :
  1054. begin
  1055. valid_for_assign:=true;
  1056. exit;
  1057. end;
  1058. end;
  1059. end;
  1060. else
  1061. begin
  1062. CGMessagePos(hp^.fileinfo,type_e_variable_id_expected);
  1063. exit;
  1064. end;
  1065. end;
  1066. end;
  1067. end;
  1068. end.
  1069. {
  1070. $Log$
  1071. Revision 1.5 2000-08-27 16:11:51 peter
  1072. * moved some util functions from globals,cobjects to cutils
  1073. * splitted files into finput,fmodule
  1074. Revision 1.4 2000/08/16 18:33:53 peter
  1075. * splitted namedobjectitem.next into indexnext and listnext so it
  1076. can be used in both lists
  1077. * don't allow "word = word" type definitions (merged)
  1078. Revision 1.3 2000/08/07 11:31:04 jonas
  1079. * fixed bug in type conversions between enum subranges (it didn't take
  1080. the packenum directive into account)
  1081. + define PACKENUMFIXED symbol in options.pas
  1082. (merged from fixes branch)
  1083. Revision 1.2 2000/07/13 11:32:41 michael
  1084. + removed logs
  1085. }