ncnv.pas 60 KB

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