ncnv.pas 56 KB

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