ncnv.pas 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543
  1. {
  2. $Id$
  3. Copyright (c) 2000 by Florian Klaempfl
  4. Type checking and register allocation for type converting nodes
  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 ncnv;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node,
  23. symtype,types,
  24. nld;
  25. type
  26. ttypeconvnode = class(tunarynode)
  27. totype : ttype;
  28. convtype : tconverttype;
  29. constructor create(node : tnode;const t : ttype);virtual;
  30. function getcopy : tnode;override;
  31. function pass_1 : tnode;override;
  32. function det_resulttype:tnode;override;
  33. function docompare(p: tnode) : boolean; override;
  34. private
  35. function resulttype_cord_to_pointer : tnode;
  36. function resulttype_string_to_string : tnode;
  37. function resulttype_char_to_string : tnode;
  38. function resulttype_int_to_real : tnode;
  39. function resulttype_real_to_real : tnode;
  40. function resulttype_cchar_to_pchar : tnode;
  41. function resulttype_cstring_to_pchar : tnode;
  42. function resulttype_char_to_char : tnode;
  43. function resulttype_arrayconstructor_to_set : tnode;
  44. function resulttype_call_helper(c : tconverttype) : tnode;
  45. protected
  46. function first_int_to_int : tnode;virtual;
  47. function first_cstring_to_pchar : tnode;virtual;
  48. function first_string_to_chararray : tnode;virtual;
  49. function first_string_to_string : tnode;virtual;
  50. function first_char_to_string : tnode;virtual;
  51. function first_nothing : tnode;virtual;
  52. function first_array_to_pointer : tnode;virtual;
  53. function first_int_to_real : tnode;virtual;
  54. function first_real_to_real : tnode;virtual;
  55. function first_pointer_to_array : tnode;virtual;
  56. function first_chararray_to_string : tnode;virtual;
  57. function first_cchar_to_pchar : tnode;virtual;
  58. function first_bool_to_int : tnode;virtual;
  59. function first_int_to_bool : tnode;virtual;
  60. function first_bool_to_bool : tnode;virtual;
  61. function first_proc_to_procvar : tnode;virtual;
  62. function first_load_smallset : tnode;virtual;
  63. function first_cord_to_pointer : tnode;virtual;
  64. function first_pchar_to_string : tnode;virtual;
  65. function first_ansistring_to_pchar : tnode;virtual;
  66. function first_arrayconstructor_to_set : tnode;virtual;
  67. function first_class_to_intf : tnode;virtual;
  68. function first_char_to_char : tnode;virtual;
  69. function first_call_helper(c : tconverttype) : tnode;
  70. end;
  71. tasnode = class(tbinarynode)
  72. constructor create(l,r : tnode);virtual;
  73. function pass_1 : tnode;override;
  74. function det_resulttype:tnode;override;
  75. end;
  76. tisnode = class(tbinarynode)
  77. constructor create(l,r : tnode);virtual;
  78. function pass_1 : tnode;override;
  79. function det_resulttype:tnode;override;
  80. end;
  81. var
  82. ctypeconvnode : class of ttypeconvnode;
  83. casnode : class of tasnode;
  84. cisnode : class of tisnode;
  85. procedure inserttypeconv(var p:tnode;const t:ttype);
  86. procedure arrayconstructor_to_set(var p : tarrayconstructornode);
  87. implementation
  88. uses
  89. globtype,systems,tokens,
  90. cutils,verbose,globals,widestr,
  91. symconst,symdef,symsym,symtable,
  92. ncon,ncal,nset,nadd,
  93. {$ifdef newcg}
  94. cgbase,
  95. {$else newcg}
  96. hcodegen,
  97. {$endif newcg}
  98. htypechk,pass_1,cpubase,cpuinfo;
  99. {*****************************************************************************
  100. Helpers
  101. *****************************************************************************}
  102. procedure inserttypeconv(var p:tnode;const t:ttype);
  103. begin
  104. if not assigned(p.resulttype.def) then
  105. begin
  106. resulttypepass(p);
  107. if codegenerror then
  108. exit;
  109. end;
  110. { don't insert obsolete type conversions }
  111. if is_equal(p.resulttype.def,t.def) then
  112. begin
  113. p.resulttype:=t;
  114. end
  115. else
  116. begin
  117. p:=ctypeconvnode.create(p,t);
  118. resulttypepass(p);
  119. end;
  120. end;
  121. {*****************************************************************************
  122. Array constructor to Set Conversion
  123. *****************************************************************************}
  124. procedure arrayconstructor_to_set(var p : tarrayconstructornode);
  125. var
  126. constp : tsetconstnode;
  127. buildp,
  128. p2,p3,p4 : tnode;
  129. htype : ttype;
  130. constset : pconstset;
  131. constsetlo,
  132. constsethi : longint;
  133. procedure update_constsethi(t:ttype);
  134. begin
  135. if ((t.def.deftype=orddef) and
  136. (torddef(t.def).high>=constsethi)) then
  137. begin
  138. constsethi:=torddef(t.def).high;
  139. if htype.def=nil then
  140. begin
  141. if (constsethi>255) or
  142. (torddef(t.def).low<0) then
  143. htype:=u8bittype
  144. else
  145. htype:=t;
  146. end;
  147. if constsethi>255 then
  148. constsethi:=255;
  149. end
  150. else if ((t.def.deftype=enumdef) and
  151. (tenumdef(t.def).max>=constsethi)) then
  152. begin
  153. if htype.def=nil then
  154. htype:=t;
  155. constsethi:=tenumdef(t.def).max;
  156. end;
  157. end;
  158. procedure do_set(pos : longint);
  159. var
  160. mask,l : longint;
  161. begin
  162. if (pos>255) or (pos<0) then
  163. Message(parser_e_illegal_set_expr);
  164. if pos>constsethi then
  165. constsethi:=pos;
  166. if pos<constsetlo then
  167. constsetlo:=pos;
  168. { to do this correctly we use the 32bit array }
  169. l:=pos shr 5;
  170. mask:=1 shl (pos mod 32);
  171. { do we allow the same twice }
  172. if (pconst32bitset(constset)^[l] and mask)<>0 then
  173. Message(parser_e_illegal_set_expr);
  174. pconst32bitset(constset)^[l]:=pconst32bitset(constset)^[l] or mask;
  175. end;
  176. var
  177. l : longint;
  178. lr,hr : longint;
  179. begin
  180. new(constset);
  181. FillChar(constset^,sizeof(constset^),0);
  182. htype.reset;
  183. constsetlo:=0;
  184. constsethi:=0;
  185. constp:=csetconstnode.create(nil,htype);
  186. constp.value_set:=constset;
  187. buildp:=constp;
  188. if assigned(p.left) then
  189. begin
  190. while assigned(p) do
  191. begin
  192. p4:=nil; { will contain the tree to create the set }
  193. {split a range into p2 and p3 }
  194. if p.left.nodetype=arrayconstructorrangen then
  195. begin
  196. p2:=tarrayconstructorrangenode(p.left).left;
  197. p3:=tarrayconstructorrangenode(p.left).right;
  198. tarrayconstructorrangenode(p.left).left:=nil;
  199. tarrayconstructorrangenode(p.left).right:=nil;
  200. end
  201. else
  202. begin
  203. p2:=p.left;
  204. p.left:=nil;
  205. p3:=nil;
  206. end;
  207. resulttypepass(p2);
  208. if assigned(p3) then
  209. resulttypepass(p3);
  210. if codegenerror then
  211. break;
  212. case p2.resulttype.def.deftype of
  213. enumdef,
  214. orddef:
  215. begin
  216. getrange(p2.resulttype.def,lr,hr);
  217. if assigned(p3) then
  218. begin
  219. { this isn't good, you'll get problems with
  220. type t010 = 0..10;
  221. ts = set of t010;
  222. var s : ts;b : t010
  223. begin s:=[1,2,b]; end.
  224. if is_integer(p3^.resulttype.def) then
  225. begin
  226. inserttypeconv(p3,u8bitdef);
  227. end;
  228. }
  229. if assigned(htype.def) and not(is_equal(htype.def,p3.resulttype.def)) then
  230. begin
  231. aktfilepos:=p3.fileinfo;
  232. CGMessage(type_e_typeconflict_in_set);
  233. end
  234. else
  235. begin
  236. if (p2.nodetype=ordconstn) and (p3.nodetype=ordconstn) then
  237. begin
  238. if not(is_integer(p3.resulttype.def)) then
  239. htype:=p3.resulttype
  240. else
  241. begin
  242. inserttypeconv(p3,u8bittype);
  243. inserttypeconv(p2,u8bittype);
  244. end;
  245. for l:=tordconstnode(p2).value to tordconstnode(p3).value do
  246. do_set(l);
  247. p2.free;
  248. p3.free;
  249. end
  250. else
  251. begin
  252. update_constsethi(p2.resulttype);
  253. inserttypeconv(p2,htype);
  254. update_constsethi(p3.resulttype);
  255. inserttypeconv(p3,htype);
  256. if assigned(htype.def) then
  257. inserttypeconv(p3,htype)
  258. else
  259. inserttypeconv(p3,u8bittype);
  260. p4:=csetelementnode.create(p2,p3);
  261. end;
  262. end;
  263. end
  264. else
  265. begin
  266. { Single value }
  267. if p2.nodetype=ordconstn then
  268. begin
  269. if not(is_integer(p2.resulttype.def)) then
  270. update_constsethi(p2.resulttype)
  271. else
  272. inserttypeconv(p2,u8bittype);
  273. do_set(tordconstnode(p2).value);
  274. p2.free;
  275. end
  276. else
  277. begin
  278. update_constsethi(p2.resulttype);
  279. if assigned(htype.def) then
  280. inserttypeconv(p2,htype)
  281. else
  282. inserttypeconv(p2,u8bittype);
  283. p4:=csetelementnode.create(p2,nil);
  284. end;
  285. end;
  286. end;
  287. stringdef :
  288. begin
  289. { if we've already set elements which are constants }
  290. { throw an error }
  291. if ((htype.def=nil) and assigned(buildp)) or
  292. not(is_char(htype.def)) then
  293. CGMessage(type_e_typeconflict_in_set)
  294. else
  295. for l:=1 to length(pstring(tstringconstnode(p2).value_str)^) do
  296. do_set(ord(pstring(tstringconstnode(p2).value_str)^[l]));
  297. if htype.def=nil then
  298. htype:=cchartype;
  299. p2.free;
  300. end;
  301. else
  302. CGMessage(type_e_ordinal_expr_expected);
  303. end;
  304. { insert the set creation tree }
  305. if assigned(p4) then
  306. buildp:=caddnode.create(addn,buildp,p4);
  307. { load next and dispose current node }
  308. p2:=p;
  309. p:=tarrayconstructornode(tarrayconstructornode(p2).right);
  310. tarrayconstructornode(p2).right:=nil;
  311. p2.free;
  312. end;
  313. if (htype.def=nil) then
  314. begin
  315. htype:=u8bittype;
  316. constsethi:=255;
  317. end;
  318. end
  319. else
  320. begin
  321. { empty set [], only remove node }
  322. p.free;
  323. end;
  324. { set the initial set type }
  325. constp.resulttype.setdef(tsetdef.create(htype,constsethi));
  326. { determine the resulttype for the tree }
  327. resulttypepass(buildp);
  328. { set the new tree }
  329. p:=tarrayconstructornode(buildp);
  330. end;
  331. {*****************************************************************************
  332. TTYPECONVNODE
  333. *****************************************************************************}
  334. constructor ttypeconvnode.create(node : tnode;const t:ttype);
  335. begin
  336. inherited create(typeconvn,node);
  337. convtype:=tc_not_possible;
  338. totype:=t;
  339. if t.def=nil then
  340. internalerror(200103281);
  341. set_file_line(node);
  342. end;
  343. function ttypeconvnode.getcopy : tnode;
  344. var
  345. n : ttypeconvnode;
  346. begin
  347. n:=ttypeconvnode(inherited getcopy);
  348. n.convtype:=convtype;
  349. getcopy:=n;
  350. end;
  351. function ttypeconvnode.resulttype_cord_to_pointer : tnode;
  352. var
  353. t : tnode;
  354. begin
  355. result:=nil;
  356. if left.nodetype=ordconstn then
  357. begin
  358. { check if we have a valid pointer constant (JM) }
  359. if (sizeof(tordconstnode) > sizeof(tpointerord)) then
  360. if (sizeof(tpointerord) = 4) then
  361. begin
  362. if (tordconstnode(left).value < low(longint)) or
  363. (tordconstnode(left).value > high(cardinal)) then
  364. CGMessage(parser_e_range_check_error);
  365. end
  366. else if (sizeof(tpointerord) = 8) then
  367. begin
  368. if (tordconstnode(left).value < low(int64)) or
  369. (tordconstnode(left).value > high(qword)) then
  370. CGMessage(parser_e_range_check_error);
  371. end
  372. else
  373. internalerror(2001020801);
  374. t:=cpointerconstnode.create(tpointerord(tordconstnode(left).value),resulttype);
  375. resulttypepass(t);
  376. result:=t;
  377. end
  378. else
  379. internalerror(200104023);
  380. end;
  381. function ttypeconvnode.resulttype_string_to_string : tnode;
  382. var
  383. pw : pcompilerwidestring;
  384. pc : pchar;
  385. begin
  386. result:=nil;
  387. if left.nodetype=stringconstn then
  388. begin
  389. { convert ascii 2 unicode }
  390. if (tstringdef(resulttype.def).string_typ=st_widestring) and
  391. (tstringconstnode(left).st_type in [st_ansistring,st_shortstring,st_longstring]) then
  392. begin
  393. initwidestring(pw);
  394. ascii2unicode(tstringconstnode(left).value_str,tstringconstnode(left).len,pw);
  395. ansistringdispose(tstringconstnode(left).value_str,tstringconstnode(left).len);
  396. pcompilerwidestring(tstringconstnode(left).value_str):=pw;
  397. end
  398. else
  399. { convert unicode 2 ascii }
  400. if (tstringconstnode(left).st_type=st_widestring) and
  401. (tstringdef(resulttype.def).string_typ in [st_ansistring,st_shortstring,st_longstring]) then
  402. begin
  403. pw:=pcompilerwidestring(tstringconstnode(left).value_str);
  404. getmem(pc,getlengthwidestring(pw)+1);
  405. unicode2ascii(pw,pc);
  406. donewidestring(pw);
  407. tstringconstnode(left).value_str:=pc;
  408. end;
  409. tstringconstnode(left).st_type:=tstringdef(resulttype.def).string_typ;
  410. tstringconstnode(left).resulttype:=resulttype;
  411. result:=left;
  412. left:=nil;
  413. end;
  414. end;
  415. function ttypeconvnode.resulttype_char_to_string : tnode;
  416. var
  417. hp : tstringconstnode;
  418. ws : pcompilerwidestring;
  419. begin
  420. result:=nil;
  421. if left.nodetype=ordconstn then
  422. begin
  423. if tstringdef(resulttype.def).string_typ=st_widestring then
  424. begin
  425. initwidestring(ws);
  426. concatwidestringchar(ws,tcompilerwidechar(chr(tordconstnode(left).value)));
  427. hp:=cstringconstnode.createwstr(ws);
  428. donewidestring(ws);
  429. end
  430. else
  431. hp:=cstringconstnode.createstr(chr(tordconstnode(left).value),tstringdef(resulttype.def).string_typ);
  432. resulttypepass(hp);
  433. result:=hp;
  434. end;
  435. end;
  436. function ttypeconvnode.resulttype_char_to_char : tnode;
  437. var
  438. hp : tordconstnode;
  439. begin
  440. result:=nil;
  441. if left.nodetype=ordconstn then
  442. begin
  443. if (torddef(resulttype.def).typ=uchar) and
  444. (torddef(left.resulttype.def).typ=uwidechar) then
  445. begin
  446. hp:=cordconstnode.create(
  447. ord(unicode2asciichar(tcompilerwidechar(tordconstnode(left).value))),cchartype);
  448. resulttypepass(hp);
  449. result:=hp;
  450. end
  451. else if (torddef(resulttype.def).typ=uwidechar) and
  452. (torddef(left.resulttype.def).typ=uchar) then
  453. begin
  454. hp:=cordconstnode.create(
  455. asciichar2unicode(chr(tordconstnode(left).value)),cwidechartype);
  456. resulttypepass(hp);
  457. result:=hp;
  458. end
  459. else
  460. internalerror(200105131);
  461. exit;
  462. end;
  463. end;
  464. function ttypeconvnode.resulttype_int_to_real : tnode;
  465. var
  466. t : trealconstnode;
  467. begin
  468. result:=nil;
  469. if left.nodetype=ordconstn then
  470. begin
  471. t:=crealconstnode.create(tordconstnode(left).value,resulttype);
  472. resulttypepass(t);
  473. result:=t;
  474. exit;
  475. end;
  476. end;
  477. function ttypeconvnode.resulttype_real_to_real : tnode;
  478. var
  479. t : tnode;
  480. begin
  481. result:=nil;
  482. if left.nodetype=realconstn then
  483. begin
  484. t:=crealconstnode.create(trealconstnode(left).value_real,resulttype);
  485. resulttypepass(t);
  486. result:=t;
  487. end;
  488. end;
  489. function ttypeconvnode.resulttype_cchar_to_pchar : tnode;
  490. begin
  491. result:=nil;
  492. if is_pwidechar(resulttype.def) then
  493. inserttypeconv(left,cwidestringtype)
  494. else
  495. inserttypeconv(left,cshortstringtype);
  496. { evaluate again, reset resulttype so the convert_typ
  497. will be calculated again and cstring_to_pchar will
  498. be used for futher conversion }
  499. result:=det_resulttype;
  500. end;
  501. function ttypeconvnode.resulttype_cstring_to_pchar : tnode;
  502. begin
  503. result:=nil;
  504. if is_pwidechar(resulttype.def) then
  505. inserttypeconv(left,cwidestringtype);
  506. end;
  507. function ttypeconvnode.resulttype_arrayconstructor_to_set : tnode;
  508. var
  509. hp : tnode;
  510. begin
  511. result:=nil;
  512. if left.nodetype<>arrayconstructorn then
  513. internalerror(5546);
  514. { remove typeconv node }
  515. hp:=left;
  516. left:=nil;
  517. { create a set constructor tree }
  518. arrayconstructor_to_set(tarrayconstructornode(hp));
  519. { now resulttypepass the set }
  520. resulttypepass(hp);
  521. result:=hp;
  522. end;
  523. function ttypeconvnode.resulttype_call_helper(c : tconverttype) : tnode;
  524. const
  525. resulttypeconvert : array[tconverttype] of pointer = (
  526. {equal} nil,
  527. {not_possible} nil,
  528. { string_2_string } @ttypeconvnode.resulttype_string_to_string,
  529. { char_2_string } @ttypeconvnode.resulttype_char_to_string,
  530. { pchar_2_string } nil,
  531. { cchar_2_pchar } @ttypeconvnode.resulttype_cchar_to_pchar,
  532. { cstring_2_pchar } @ttypeconvnode.resulttype_cstring_to_pchar,
  533. { ansistring_2_pchar } nil,
  534. { string_2_chararray } nil,
  535. { chararray_2_string } nil,
  536. { array_2_pointer } nil,
  537. { pointer_2_array } nil,
  538. { int_2_int } nil,
  539. { int_2_bool } nil,
  540. { bool_2_bool } nil,
  541. { bool_2_int } nil,
  542. { real_2_real } @ttypeconvnode.resulttype_real_to_real,
  543. { int_2_real } @ttypeconvnode.resulttype_int_to_real,
  544. { proc_2_procvar } nil,
  545. { arrayconstructor_2_set } @ttypeconvnode.resulttype_arrayconstructor_to_set,
  546. { load_smallset } nil,
  547. { cord_2_pointer } @ttypeconvnode.resulttype_cord_to_pointer,
  548. { intf_2_string } nil,
  549. { intf_2_guid } nil,
  550. { class_2_intf } nil,
  551. { char_2_char } @ttypeconvnode.resulttype_char_to_char
  552. );
  553. type
  554. tprocedureofobject = function : tnode of object;
  555. var
  556. r : packed record
  557. proc : pointer;
  558. obj : pointer;
  559. end;
  560. begin
  561. result:=nil;
  562. { this is a little bit dirty but it works }
  563. { and should be quite portable too }
  564. r.proc:=resulttypeconvert[c];
  565. r.obj:=self;
  566. if assigned(r.proc) then
  567. result:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
  568. end;
  569. function ttypeconvnode.det_resulttype:tnode;
  570. var
  571. hp : tnode;
  572. aprocdef : tprocdef;
  573. begin
  574. result:=nil;
  575. resulttype:=totype;
  576. resulttypepass(left);
  577. if codegenerror then
  578. exit;
  579. { remove obsolete type conversions }
  580. if is_equal(left.resulttype.def,resulttype.def) then
  581. begin
  582. { becuase is_equal only checks the basetype for sets we need to
  583. check here if we are loading a smallset into a normalset }
  584. if (resulttype.def.deftype=setdef) and
  585. (left.resulttype.def.deftype=setdef) and
  586. (tsetdef(resulttype.def).settype<>smallset) and
  587. (tsetdef(left.resulttype.def).settype=smallset) then
  588. begin
  589. { try to define the set as a normalset if it's a constant set }
  590. if left.nodetype=setconstn then
  591. begin
  592. resulttype:=left.resulttype;
  593. tsetdef(resulttype.def).settype:=normset
  594. end
  595. else
  596. convtype:=tc_load_smallset;
  597. exit;
  598. end
  599. else
  600. begin
  601. left.resulttype:=resulttype;
  602. result:=left;
  603. left:=nil;
  604. exit;
  605. end;
  606. end;
  607. aprocdef:=assignment_overloaded(left.resulttype.def,resulttype.def);
  608. if assigned(aprocdef) then
  609. begin
  610. procinfo^.flags:=procinfo^.flags or pi_do_call;
  611. hp:=ccallnode.create(ccallparanode.create(left,nil),
  612. overloaded_operators[_assignment],nil,nil);
  613. { tell explicitly which def we must use !! (PM) }
  614. tcallnode(hp).procdefinition:=aprocdef;
  615. left:=nil;
  616. resulttypepass(hp);
  617. result:=hp;
  618. exit;
  619. end;
  620. if isconvertable(left.resulttype.def,resulttype.def,convtype,left.nodetype,nf_explizit in flags)=0 then
  621. begin
  622. {Procedures have a resulttype.def of voiddef and functions of their
  623. own resulttype.def. They will therefore always be incompatible with
  624. a procvar. Because isconvertable cannot check for procedures we
  625. use an extra check for them.}
  626. if (m_tp_procvar in aktmodeswitches) then
  627. begin
  628. if (resulttype.def.deftype=procvardef) and
  629. (is_procsym_load(left) or is_procsym_call(left)) then
  630. begin
  631. if is_procsym_call(left) then
  632. begin
  633. hp:=cloadnode.create(tprocsym(tcallnode(left).symtableprocentry),
  634. tcallnode(left).symtableproc);
  635. if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) and
  636. assigned(tcallnode(left).methodpointer) then
  637. tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy);
  638. resulttypepass(hp);
  639. left.free;
  640. left:=hp;
  641. aprocdef:=tprocdef(left.resulttype.def);
  642. end
  643. else
  644. begin
  645. if (left.nodetype<>addrn) then
  646. aprocdef:=tprocsym(tloadnode(left).symtableentry).definition;
  647. end;
  648. convtype:=tc_proc_2_procvar;
  649. { Now check if the procedure we are going to assign to
  650. the procvar, is compatible with the procvar's type }
  651. if assigned(aprocdef) then
  652. begin
  653. if not proc_to_procvar_equal(aprocdef,tprocvardef(resulttype.def)) then
  654. CGMessage2(type_e_incompatible_types,aprocdef.typename,resulttype.def.typename);
  655. end
  656. else
  657. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  658. exit;
  659. end;
  660. end;
  661. if nf_explizit in flags then
  662. begin
  663. { check if the result could be in a register }
  664. if not(tstoreddef(resulttype.def).is_intregable) and
  665. not(tstoreddef(resulttype.def).is_fpuregable) then
  666. make_not_regable(left);
  667. { boolean to byte are special because the
  668. location can be different }
  669. if is_integer(resulttype.def) and
  670. is_boolean(left.resulttype.def) then
  671. begin
  672. convtype:=tc_bool_2_int;
  673. exit;
  674. end;
  675. { ansistring to pchar }
  676. if is_pchar(resulttype.def) and
  677. is_ansistring(left.resulttype.def) then
  678. begin
  679. convtype:=tc_ansistring_2_pchar;
  680. exit;
  681. end;
  682. { do common tc_equal cast }
  683. convtype:=tc_equal;
  684. { enum to ordinal will always be s32bit }
  685. if (left.resulttype.def.deftype=enumdef) and
  686. is_ordinal(resulttype.def) then
  687. begin
  688. if left.nodetype=ordconstn then
  689. begin
  690. hp:=cordconstnode.create(tordconstnode(left).value,resulttype);
  691. resulttypepass(hp);
  692. result:=hp;
  693. exit;
  694. end
  695. else
  696. begin
  697. if isconvertable(s32bittype.def,resulttype.def,convtype,ordconstn,false)=0 then
  698. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  699. end;
  700. end
  701. { ordinal to enumeration }
  702. else
  703. if (resulttype.def.deftype=enumdef) and
  704. is_ordinal(left.resulttype.def) then
  705. begin
  706. if left.nodetype=ordconstn then
  707. begin
  708. hp:=cordconstnode.create(tordconstnode(left).value,resulttype);
  709. resulttypepass(hp);
  710. result:=hp;
  711. exit;
  712. end
  713. else
  714. begin
  715. if IsConvertable(left.resulttype.def,s32bittype.def,convtype,ordconstn,false)=0 then
  716. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  717. end;
  718. end
  719. { nil to ordinal node }
  720. else if (left.nodetype=niln) and is_ordinal(resulttype.def) then
  721. begin
  722. hp:=cordconstnode.create(0,resulttype);
  723. resulttypepass(hp);
  724. result:=hp;
  725. exit;
  726. end
  727. { constant pointer to ordinal }
  728. else if is_ordinal(resulttype.def) and
  729. (left.nodetype=pointerconstn) then
  730. begin
  731. hp:=cordconstnode.create(tpointerconstnode(left).value,resulttype);
  732. resulttypepass(hp);
  733. result:=hp;
  734. exit;
  735. end
  736. {Are we typecasting an ordconst to a char?}
  737. else
  738. if is_char(resulttype.def) and
  739. is_ordinal(left.resulttype.def) then
  740. begin
  741. if left.nodetype=ordconstn then
  742. begin
  743. hp:=cordconstnode.create(tordconstnode(left).value,resulttype);
  744. resulttypepass(hp);
  745. result:=hp;
  746. exit;
  747. end
  748. else
  749. begin
  750. if IsConvertable(left.resulttype.def,u8bittype.def,convtype,ordconstn,false)=0 then
  751. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  752. end;
  753. end
  754. {Are we typecasting an ordconst to a wchar?}
  755. else
  756. if is_widechar(resulttype.def) and
  757. is_ordinal(left.resulttype.def) then
  758. begin
  759. if left.nodetype=ordconstn then
  760. begin
  761. hp:=cordconstnode.create(tordconstnode(left).value,resulttype);
  762. resulttypepass(hp);
  763. result:=hp;
  764. exit;
  765. end
  766. else
  767. begin
  768. if IsConvertable(left.resulttype.def,u16bittype.def,convtype,ordconstn,false)=0 then
  769. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  770. end;
  771. end
  772. { char to ordinal }
  773. else
  774. if is_char(left.resulttype.def) and
  775. is_ordinal(resulttype.def) then
  776. begin
  777. if left.nodetype=ordconstn then
  778. begin
  779. hp:=cordconstnode.create(tordconstnode(left).value,resulttype);
  780. resulttypepass(hp);
  781. result:=hp;
  782. exit;
  783. end
  784. else
  785. begin
  786. if IsConvertable(u8bittype.def,resulttype.def,convtype,ordconstn,false)=0 then
  787. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  788. end;
  789. end
  790. { widechar to ordinal }
  791. else
  792. if is_widechar(left.resulttype.def) and
  793. is_ordinal(resulttype.def) then
  794. begin
  795. if left.nodetype=ordconstn then
  796. begin
  797. hp:=cordconstnode.create(tordconstnode(left).value,resulttype);
  798. resulttypepass(hp);
  799. result:=hp;
  800. exit;
  801. end
  802. else
  803. begin
  804. if IsConvertable(u16bittype.def,resulttype.def,convtype,ordconstn,false)=0 then
  805. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  806. end;
  807. end
  808. { only if the same size or formal def }
  809. { why do we allow typecasting of voiddef ?? (PM) }
  810. else
  811. begin
  812. if not(
  813. (left.resulttype.def.deftype=formaldef) or
  814. (left.resulttype.def.size=resulttype.def.size) or
  815. (is_void(left.resulttype.def) and
  816. (left.nodetype=derefn))
  817. ) then
  818. CGMessage(cg_e_illegal_type_conversion);
  819. if ((left.resulttype.def.deftype=orddef) and
  820. (resulttype.def.deftype=pointerdef)) or
  821. ((resulttype.def.deftype=orddef) and
  822. (left.resulttype.def.deftype=pointerdef)) then
  823. CGMessage(cg_d_pointer_to_longint_conv_not_portable);
  824. end;
  825. { the conversion into a strutured type is only }
  826. { possible, if the source is not a register }
  827. if ((resulttype.def.deftype in [recorddef,stringdef,arraydef]) or
  828. ((resulttype.def.deftype=objectdef) and not(is_class(resulttype.def)))
  829. ) and (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
  830. it also works if the assignment is overloaded
  831. YES but this code is not executed if assignment is overloaded (PM)
  832. not assigned(assignment_overloaded(left.resulttype.def,resulttype.def))} then
  833. CGMessage(cg_e_illegal_type_conversion);
  834. end
  835. else
  836. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  837. end;
  838. { tp7 procvar support, when right is not a procvardef and we got a
  839. loadn of a procvar then convert to a calln, the check for the
  840. result is already done in is_convertible, also no conflict with
  841. @procvar is here because that has an extra addrn }
  842. if (m_tp_procvar in aktmodeswitches) and
  843. (resulttype.def.deftype<>procvardef) and
  844. (left.resulttype.def.deftype=procvardef) and
  845. (left.nodetype=loadn) then
  846. begin
  847. hp:=ccallnode.create(nil,nil,nil,nil);
  848. tcallnode(hp).set_procvar(left);
  849. resulttypepass(hp);
  850. left:=hp;
  851. end;
  852. { ordinal contants can be directly converted }
  853. if (left.nodetype=ordconstn) and is_ordinal(resulttype.def) then
  854. begin
  855. { replace the resulttype and recheck the range }
  856. left.resulttype:=resulttype;
  857. testrange(left.resulttype.def,tordconstnode(left).value,(nf_explizit in flags));
  858. result:=left;
  859. left:=nil;
  860. exit;
  861. end;
  862. { fold nil to any pointer type }
  863. if (left.nodetype=niln) and (resulttype.def.deftype=pointerdef) then
  864. begin
  865. hp:=cnilnode.create;
  866. hp.resulttype:=resulttype;
  867. resulttypepass(hp);
  868. result:=hp;
  869. exit;
  870. end;
  871. { further, pointerconstn to any pointer is folded too }
  872. if (left.nodetype=pointerconstn) and (resulttype.def.deftype=pointerdef) then
  873. begin
  874. left.resulttype:=resulttype;
  875. result:=left;
  876. left:=nil;
  877. exit;
  878. end;
  879. { now call the resulttype helper to do constant folding }
  880. result:=resulttype_call_helper(convtype);
  881. end;
  882. function ttypeconvnode.first_cord_to_pointer : tnode;
  883. begin
  884. result:=nil;
  885. internalerror(200104043);
  886. end;
  887. function ttypeconvnode.first_int_to_int : tnode;
  888. begin
  889. first_int_to_int:=nil;
  890. if (left.location.loc<>LOC_REGISTER) and
  891. (resulttype.def.size>left.resulttype.def.size) then
  892. location.loc:=LOC_REGISTER;
  893. if is_64bitint(resulttype.def) then
  894. registers32:=max(registers32,2)
  895. else
  896. registers32:=max(registers32,1);
  897. end;
  898. function ttypeconvnode.first_cstring_to_pchar : tnode;
  899. begin
  900. first_cstring_to_pchar:=nil;
  901. registers32:=1;
  902. location.loc:=LOC_REGISTER;
  903. end;
  904. function ttypeconvnode.first_string_to_chararray : tnode;
  905. begin
  906. first_string_to_chararray:=nil;
  907. registers32:=1;
  908. location.loc:=LOC_REGISTER;
  909. end;
  910. function ttypeconvnode.first_string_to_string : tnode;
  911. begin
  912. first_string_to_string:=nil;
  913. if tstringdef(resulttype.def).string_typ<>
  914. tstringdef(left.resulttype.def).string_typ then
  915. begin
  916. procinfo^.flags:=procinfo^.flags or pi_do_call;
  917. end;
  918. { for simplicity lets first keep all ansistrings
  919. as LOC_MEM, could also become LOC_REGISTER }
  920. if tstringdef(resulttype.def).string_typ in [st_ansistring,st_widestring] then
  921. { we may use ansistrings so no fast exit here }
  922. procinfo^.no_fast_exit:=true;
  923. location.loc:=LOC_MEM;
  924. end;
  925. function ttypeconvnode.first_char_to_string : tnode;
  926. begin
  927. first_char_to_string:=nil;
  928. location.loc:=LOC_MEM;
  929. end;
  930. function ttypeconvnode.first_nothing : tnode;
  931. begin
  932. first_nothing:=nil;
  933. location.loc:=LOC_MEM;
  934. end;
  935. function ttypeconvnode.first_array_to_pointer : tnode;
  936. begin
  937. first_array_to_pointer:=nil;
  938. if registers32<1 then
  939. registers32:=1;
  940. location.loc:=LOC_REGISTER;
  941. end;
  942. function ttypeconvnode.first_int_to_real : tnode;
  943. begin
  944. first_int_to_real:=nil;
  945. {$ifdef m68k}
  946. if (cs_fp_emulation in aktmoduleswitches) or
  947. (tfloatdef(resulttype.def).typ=s32real) then
  948. begin
  949. if registers32<1 then
  950. registers32:=1;
  951. end
  952. else
  953. if registersfpu<1 then
  954. registersfpu:=1;
  955. {$else not m68k}
  956. if registersfpu<1 then
  957. registersfpu:=1;
  958. {$endif not m68k}
  959. location.loc:=LOC_FPU;
  960. end;
  961. function ttypeconvnode.first_real_to_real : tnode;
  962. begin
  963. first_real_to_real:=nil;
  964. { comp isn't a floating type }
  965. {$ifdef i386}
  966. if (tfloatdef(resulttype.def).typ=s64comp) and
  967. (tfloatdef(left.resulttype.def).typ<>s64comp) and
  968. not (nf_explizit in flags) then
  969. CGMessage(type_w_convert_real_2_comp);
  970. {$endif}
  971. if registersfpu<1 then
  972. registersfpu:=1;
  973. location.loc:=LOC_FPU;
  974. end;
  975. function ttypeconvnode.first_pointer_to_array : tnode;
  976. begin
  977. first_pointer_to_array:=nil;
  978. if registers32<1 then
  979. registers32:=1;
  980. location.loc:=LOC_REFERENCE;
  981. end;
  982. function ttypeconvnode.first_chararray_to_string : tnode;
  983. begin
  984. first_chararray_to_string:=nil;
  985. { the only important information is the location of the }
  986. { result }
  987. { other stuff is done by firsttypeconv }
  988. location.loc:=LOC_MEM;
  989. end;
  990. function ttypeconvnode.first_cchar_to_pchar : tnode;
  991. begin
  992. first_cchar_to_pchar:=nil;
  993. internalerror(200104021);
  994. end;
  995. function ttypeconvnode.first_bool_to_int : tnode;
  996. begin
  997. first_bool_to_int:=nil;
  998. { byte(boolean) or word(wordbool) or longint(longbool) must
  999. be accepted for var parameters }
  1000. if (nf_explizit in flags) and
  1001. (left.resulttype.def.size=resulttype.def.size) and
  1002. (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  1003. exit;
  1004. location.loc:=LOC_REGISTER;
  1005. if registers32<1 then
  1006. registers32:=1;
  1007. end;
  1008. function ttypeconvnode.first_int_to_bool : tnode;
  1009. begin
  1010. first_int_to_bool:=nil;
  1011. { byte(boolean) or word(wordbool) or longint(longbool) must
  1012. be accepted for var parameters }
  1013. if (nf_explizit in flags) and
  1014. (left.resulttype.def.size=resulttype.def.size) and
  1015. (left.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  1016. exit;
  1017. location.loc:=LOC_REGISTER;
  1018. { need if bool to bool !!
  1019. not very nice !!
  1020. insertypeconv(left,s32bittype);
  1021. left.explizit:=true;
  1022. firstpass(left); }
  1023. if registers32<1 then
  1024. registers32:=1;
  1025. end;
  1026. function ttypeconvnode.first_bool_to_bool : tnode;
  1027. begin
  1028. first_bool_to_bool:=nil;
  1029. location.loc:=LOC_REGISTER;
  1030. if registers32<1 then
  1031. registers32:=1;
  1032. end;
  1033. function ttypeconvnode.first_char_to_char : tnode;
  1034. begin
  1035. first_char_to_char:=nil;
  1036. location.loc:=LOC_REGISTER;
  1037. if registers32<1 then
  1038. registers32:=1;
  1039. end;
  1040. function ttypeconvnode.first_proc_to_procvar : tnode;
  1041. begin
  1042. first_proc_to_procvar:=nil;
  1043. if (left.location.loc<>LOC_REFERENCE) then
  1044. CGMessage(cg_e_illegal_expression);
  1045. registers32:=left.registers32;
  1046. if registers32<1 then
  1047. registers32:=1;
  1048. location.loc:=LOC_REGISTER;
  1049. end;
  1050. function ttypeconvnode.first_load_smallset : tnode;
  1051. begin
  1052. first_load_smallset:=nil;
  1053. end;
  1054. function ttypeconvnode.first_pchar_to_string : tnode;
  1055. begin
  1056. first_pchar_to_string:=nil;
  1057. location.loc:=LOC_REFERENCE;
  1058. end;
  1059. function ttypeconvnode.first_ansistring_to_pchar : tnode;
  1060. begin
  1061. first_ansistring_to_pchar:=nil;
  1062. location.loc:=LOC_REGISTER;
  1063. if registers32<1 then
  1064. registers32:=1;
  1065. end;
  1066. function ttypeconvnode.first_arrayconstructor_to_set : tnode;
  1067. begin
  1068. first_arrayconstructor_to_set:=nil;
  1069. internalerror(200104022);
  1070. end;
  1071. function ttypeconvnode.first_class_to_intf : tnode;
  1072. begin
  1073. first_class_to_intf:=nil;
  1074. location.loc:=LOC_REFERENCE;
  1075. if registers32<1 then
  1076. registers32:=1;
  1077. end;
  1078. function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
  1079. const
  1080. firstconvert : array[tconverttype] of pointer = (
  1081. @ttypeconvnode.first_nothing, {equal}
  1082. @ttypeconvnode.first_nothing, {not_possible}
  1083. @ttypeconvnode.first_string_to_string,
  1084. @ttypeconvnode.first_char_to_string,
  1085. @ttypeconvnode.first_pchar_to_string,
  1086. @ttypeconvnode.first_cchar_to_pchar,
  1087. @ttypeconvnode.first_cstring_to_pchar,
  1088. @ttypeconvnode.first_ansistring_to_pchar,
  1089. @ttypeconvnode.first_string_to_chararray,
  1090. @ttypeconvnode.first_chararray_to_string,
  1091. @ttypeconvnode.first_array_to_pointer,
  1092. @ttypeconvnode.first_pointer_to_array,
  1093. @ttypeconvnode.first_int_to_int,
  1094. @ttypeconvnode.first_int_to_bool,
  1095. @ttypeconvnode.first_bool_to_bool,
  1096. @ttypeconvnode.first_bool_to_int,
  1097. @ttypeconvnode.first_real_to_real,
  1098. @ttypeconvnode.first_int_to_real,
  1099. @ttypeconvnode.first_proc_to_procvar,
  1100. @ttypeconvnode.first_arrayconstructor_to_set,
  1101. @ttypeconvnode.first_load_smallset,
  1102. @ttypeconvnode.first_cord_to_pointer,
  1103. @ttypeconvnode.first_nothing,
  1104. @ttypeconvnode.first_nothing,
  1105. @ttypeconvnode.first_class_to_intf,
  1106. @ttypeconvnode.first_char_to_char
  1107. );
  1108. type
  1109. tprocedureofobject = function : tnode of object;
  1110. var
  1111. r : packed record
  1112. proc : pointer;
  1113. obj : pointer;
  1114. end;
  1115. begin
  1116. { this is a little bit dirty but it works }
  1117. { and should be quite portable too }
  1118. r.proc:=firstconvert[c];
  1119. r.obj:=self;
  1120. first_call_helper:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
  1121. end;
  1122. function ttypeconvnode.pass_1 : tnode;
  1123. begin
  1124. result:=nil;
  1125. firstpass(left);
  1126. if codegenerror then
  1127. exit;
  1128. { load the value_str from the left part }
  1129. registers32:=left.registers32;
  1130. registersfpu:=left.registersfpu;
  1131. {$ifdef SUPPORT_MMX}
  1132. registersmmx:=left.registersmmx;
  1133. {$endif}
  1134. set_location(location,left.location);
  1135. if nf_explizit in flags then
  1136. begin
  1137. { check if the result could be in a register }
  1138. if not(tstoreddef(resulttype.def).is_intregable) and
  1139. not(tstoreddef(resulttype.def).is_fpuregable) then
  1140. make_not_regable(left);
  1141. end;
  1142. if convtype=tc_equal then
  1143. begin
  1144. { remove typeconv node if left is a const. For other nodes we can't
  1145. remove it because the secondpass can still depend on the old type (PFV) }
  1146. if is_constnode(left) then
  1147. begin
  1148. left.resulttype:=resulttype;
  1149. result:=left;
  1150. left:=nil;
  1151. end;
  1152. end
  1153. else
  1154. begin
  1155. result:=first_call_helper(convtype);
  1156. end;
  1157. end;
  1158. {*****************************************************************************
  1159. TISNODE
  1160. *****************************************************************************}
  1161. constructor tisnode.create(l,r : tnode);
  1162. begin
  1163. inherited create(isn,l,r);
  1164. end;
  1165. function tisnode.det_resulttype:tnode;
  1166. begin
  1167. result:=nil;
  1168. resulttypepass(left);
  1169. resulttypepass(right);
  1170. set_varstate(left,true);
  1171. set_varstate(right,true);
  1172. if codegenerror then
  1173. exit;
  1174. if (right.resulttype.def.deftype=classrefdef) then
  1175. begin
  1176. { left must be a class }
  1177. if is_class(left.resulttype.def) then
  1178. begin
  1179. { the operands must be related }
  1180. if (not(tobjectdef(left.resulttype.def).is_related(
  1181. tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
  1182. (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
  1183. tobjectdef(left.resulttype.def)))) then
  1184. CGMessage(type_e_mismatch);
  1185. end
  1186. else
  1187. CGMessage(type_e_mismatch);
  1188. end
  1189. else
  1190. CGMessage(type_e_mismatch);
  1191. resulttype:=booltype;
  1192. end;
  1193. function tisnode.pass_1 : tnode;
  1194. begin
  1195. result:=nil;
  1196. firstpass(left);
  1197. firstpass(right);
  1198. if codegenerror then
  1199. exit;
  1200. left_right_max;
  1201. location.loc:=LOC_FLAGS;
  1202. end;
  1203. {*****************************************************************************
  1204. TASNODE
  1205. *****************************************************************************}
  1206. constructor tasnode.create(l,r : tnode);
  1207. begin
  1208. inherited create(asn,l,r);
  1209. end;
  1210. function tasnode.det_resulttype:tnode;
  1211. begin
  1212. result:=nil;
  1213. resulttypepass(right);
  1214. resulttypepass(left);
  1215. set_varstate(right,true);
  1216. set_varstate(left,true);
  1217. if codegenerror then
  1218. exit;
  1219. if (right.resulttype.def.deftype=classrefdef) then
  1220. begin
  1221. { left must be a class }
  1222. if is_class(left.resulttype.def) then
  1223. begin
  1224. { the operands must be related }
  1225. if (not(tobjectdef(left.resulttype.def).is_related(
  1226. tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
  1227. (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
  1228. tobjectdef(left.resulttype.def)))) then
  1229. CGMessage(type_e_mismatch);
  1230. end
  1231. else
  1232. CGMessage(type_e_mismatch);
  1233. resulttype:=tclassrefdef(right.resulttype.def).pointertype;
  1234. end
  1235. else
  1236. CGMessage(type_e_mismatch);
  1237. end;
  1238. function tasnode.pass_1 : tnode;
  1239. begin
  1240. result:=nil;
  1241. firstpass(right);
  1242. firstpass(left);
  1243. if codegenerror then
  1244. exit;
  1245. left_right_max;
  1246. set_location(location,left.location);
  1247. end;
  1248. function ttypeconvnode.docompare(p: tnode) : boolean;
  1249. begin
  1250. docompare :=
  1251. inherited docompare(p) and
  1252. (convtype = ttypeconvnode(p).convtype);
  1253. end;
  1254. begin
  1255. ctypeconvnode:=ttypeconvnode;
  1256. casnode:=tasnode;
  1257. cisnode:=tisnode;
  1258. end.
  1259. {
  1260. $Log$
  1261. Revision 1.30 2001-07-30 20:59:27 peter
  1262. * m68k updates from v10 merged
  1263. Revision 1.29 2001/07/08 21:00:15 peter
  1264. * various widestring updates, it works now mostly without charset
  1265. mapping supported
  1266. Revision 1.28 2001/05/13 15:43:46 florian
  1267. * made resultype_char_to_char a little bit robuster
  1268. Revision 1.27 2001/05/08 21:06:30 florian
  1269. * some more support for widechars commited especially
  1270. regarding type casting and constants
  1271. Revision 1.26 2001/05/04 15:52:03 florian
  1272. * some Delphi incompatibilities fixed:
  1273. - out, dispose and new can be used as idenfiers now
  1274. - const p = apointerype(nil); is supported now
  1275. + support for const p = apointertype(pointer(1234)); added
  1276. Revision 1.25 2001/04/13 22:20:58 peter
  1277. * remove wrongly placed first_call_helper
  1278. Revision 1.24 2001/04/13 01:22:08 peter
  1279. * symtable change to classes
  1280. * range check generation and errors fixed, make cycle DEBUG=1 works
  1281. * memory leaks fixed
  1282. Revision 1.23 2001/04/04 22:42:39 peter
  1283. * move constant folding into det_resulttype
  1284. Revision 1.22 2001/04/02 21:20:30 peter
  1285. * resulttype rewrite
  1286. Revision 1.21 2001/03/08 17:44:47 jonas
  1287. * fixed web bug 1430
  1288. Revision 1.20 2001/02/21 11:49:50 jonas
  1289. * evaluate typecasts of const pointers to ordinals inline ('merged')
  1290. Revision 1.19 2001/02/20 18:37:10 peter
  1291. * removed unused code
  1292. Revision 1.18 2001/02/20 13:14:18 marco
  1293. * Fix from Peter for passing a procedure of method to a other method in a method
  1294. Revision 1.17 2001/02/08 13:09:03 jonas
  1295. * fixed web bug 1396: tpointerord is now a cardinal instead of a longint,
  1296. but added a hack in ncnv so that pointer(-1) still works
  1297. Revision 1.16 2000/12/31 11:14:10 jonas
  1298. + implemented/fixed docompare() mathods for all nodes (not tested)
  1299. + nopt.pas, nadd.pas, i386/n386opt.pas: optimized nodes for adding strings
  1300. and constant strings/chars together
  1301. * n386add.pas: don't copy temp strings (of size 256) to another temp string
  1302. when adding
  1303. Revision 1.15 2000/12/08 12:41:01 jonas
  1304. * fixed bug in sign extension patch
  1305. Revision 1.14 2000/12/07 17:19:42 jonas
  1306. * new constant handling: from now on, hex constants >$7fffffff are
  1307. parsed as unsigned constants (otherwise, $80000000 got sign extended
  1308. and became $ffffffff80000000), all constants in the longint range
  1309. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  1310. are cardinals and the rest are int64's.
  1311. * added lots of longint typecast to prevent range check errors in the
  1312. compiler and rtl
  1313. * type casts of symbolic ordinal constants are now preserved
  1314. * fixed bug where the original resulttype.def wasn't restored correctly
  1315. after doing a 64bit rangecheck
  1316. Revision 1.13 2000/11/29 00:30:32 florian
  1317. * unused units removed from uses clause
  1318. * some changes for widestrings
  1319. Revision 1.12 2000/11/20 16:06:04 jonas
  1320. + allow evaluation of 64bit constant expressions at compile time
  1321. * disable range checking for explicit typecasts of constant expressions
  1322. Revision 1.11 2000/11/12 23:24:11 florian
  1323. * interfaces are basically running
  1324. Revision 1.10 2000/11/04 14:25:20 florian
  1325. + merged Attila's changes for interfaces, not tested yet
  1326. Revision 1.9 2000/10/31 22:02:48 peter
  1327. * symtable splitted, no real code changes
  1328. Revision 1.8 2000/10/14 21:52:55 peter
  1329. * fixed memory leaks
  1330. Revision 1.7 2000/10/14 10:14:50 peter
  1331. * moehrendorf oct 2000 rewrite
  1332. Revision 1.6 2000/10/01 19:48:24 peter
  1333. * lot of compile updates for cg11
  1334. Revision 1.5 2000/09/28 19:49:52 florian
  1335. *** empty log message ***
  1336. Revision 1.4 2000/09/27 18:14:31 florian
  1337. * fixed a lot of syntax errors in the n*.pas stuff
  1338. Revision 1.3 2000/09/26 20:06:13 florian
  1339. * hmm, still a lot of work to get things compilable
  1340. Revision 1.2 2000/09/26 14:59:34 florian
  1341. * more conversion work done
  1342. Revision 1.1 2000/09/25 15:37:14 florian
  1343. * more fixes
  1344. }