htypechk.pas 46 KB

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