htypechk.pas 46 KB

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