htypechk.pas 46 KB

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