ncnv.pas 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 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 fpcdefs.inc}
  20. interface
  21. uses
  22. node,
  23. symtype,symppu,defbase,
  24. nld
  25. {$ifdef Delphi}
  26. ,dmisc
  27. {$endif}
  28. ;
  29. type
  30. ttypeconvnode = class(tunarynode)
  31. totype : ttype;
  32. convtype : tconverttype;
  33. constructor create(node : tnode;const t : ttype);virtual;
  34. constructor create_explicit(node : tnode;const t : ttype);
  35. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  36. procedure ppuwrite(ppufile:tcompilerppufile);override;
  37. procedure derefimpl;override;
  38. function getcopy : tnode;override;
  39. function pass_1 : tnode;override;
  40. function det_resulttype:tnode;override;
  41. {$ifdef var_notification}
  42. procedure mark_write;override;
  43. {$endif}
  44. function docompare(p: tnode) : boolean; override;
  45. private
  46. function resulttype_cord_to_pointer : tnode;
  47. function resulttype_chararray_to_string : tnode;
  48. function resulttype_string_to_chararray : tnode;
  49. function resulttype_string_to_string : tnode;
  50. function resulttype_char_to_string : tnode;
  51. function resulttype_char_to_chararray : tnode;
  52. function resulttype_int_to_real : tnode;
  53. function resulttype_real_to_real : tnode;
  54. function resulttype_cchar_to_pchar : tnode;
  55. function resulttype_cstring_to_pchar : tnode;
  56. function resulttype_char_to_char : tnode;
  57. function resulttype_arrayconstructor_to_set : tnode;
  58. function resulttype_pchar_to_string : tnode;
  59. function resulttype_interface_to_guid : tnode;
  60. function resulttype_dynarray_to_openarray : tnode;
  61. function resulttype_pwchar_to_string : tnode;
  62. function resulttype_call_helper(c : tconverttype) : tnode;
  63. protected
  64. function first_int_to_int : tnode;virtual;
  65. function first_cstring_to_pchar : tnode;virtual;
  66. function first_string_to_chararray : tnode;virtual;
  67. function first_char_to_string : tnode;virtual;
  68. function first_nothing : tnode;virtual;
  69. function first_array_to_pointer : tnode;virtual;
  70. function first_int_to_real : tnode;virtual;
  71. function first_real_to_real : tnode;virtual;
  72. function first_pointer_to_array : tnode;virtual;
  73. function first_cchar_to_pchar : tnode;virtual;
  74. function first_bool_to_int : tnode;virtual;
  75. function first_int_to_bool : tnode;virtual;
  76. function first_bool_to_bool : tnode;virtual;
  77. function first_proc_to_procvar : tnode;virtual;
  78. function first_load_smallset : tnode;virtual;
  79. function first_cord_to_pointer : tnode;virtual;
  80. function first_ansistring_to_pchar : tnode;virtual;
  81. function first_arrayconstructor_to_set : tnode;virtual;
  82. function first_class_to_intf : tnode;virtual;
  83. function first_char_to_char : tnode;virtual;
  84. function first_call_helper(c : tconverttype) : tnode;
  85. { these wrapper are necessary, because the first_* stuff is called }
  86. { through a table. Without the wrappers override wouldn't have }
  87. { any effect }
  88. function _first_int_to_int : tnode;
  89. function _first_cstring_to_pchar : tnode;
  90. function _first_string_to_chararray : tnode;
  91. function _first_char_to_string : tnode;
  92. function _first_nothing : tnode;
  93. function _first_array_to_pointer : tnode;
  94. function _first_int_to_real : tnode;
  95. function _first_real_to_real : tnode;
  96. function _first_pointer_to_array : tnode;
  97. function _first_cchar_to_pchar : tnode;
  98. function _first_bool_to_int : tnode;
  99. function _first_int_to_bool : tnode;
  100. function _first_bool_to_bool : tnode;
  101. function _first_proc_to_procvar : tnode;
  102. function _first_load_smallset : tnode;
  103. function _first_cord_to_pointer : tnode;
  104. function _first_ansistring_to_pchar : tnode;
  105. function _first_arrayconstructor_to_set : tnode;
  106. function _first_class_to_intf : tnode;
  107. function _first_char_to_char : tnode;
  108. procedure second_int_to_int;virtual;abstract;
  109. procedure second_string_to_string;virtual;abstract;
  110. procedure second_cstring_to_pchar;virtual;abstract;
  111. procedure second_string_to_chararray;virtual;abstract;
  112. procedure second_array_to_pointer;virtual;abstract;
  113. procedure second_pointer_to_array;virtual;abstract;
  114. procedure second_chararray_to_string;virtual;abstract;
  115. procedure second_char_to_string;virtual;abstract;
  116. procedure second_int_to_real;virtual;abstract;
  117. procedure second_real_to_real;virtual;abstract;
  118. procedure second_cord_to_pointer;virtual;abstract;
  119. procedure second_proc_to_procvar;virtual;abstract;
  120. procedure second_bool_to_int;virtual;abstract;
  121. procedure second_int_to_bool;virtual;abstract;
  122. procedure second_bool_to_bool;virtual;abstract;
  123. procedure second_load_smallset;virtual;abstract;
  124. procedure second_ansistring_to_pchar;virtual;abstract;
  125. procedure second_class_to_intf;virtual;abstract;
  126. procedure second_char_to_char;virtual;abstract;
  127. procedure second_nothing; virtual;abstract;
  128. end;
  129. ttypeconvnodeclass = class of ttypeconvnode;
  130. tasnode = class(tbinarynode)
  131. constructor create(l,r : tnode);virtual;
  132. function pass_1 : tnode;override;
  133. function det_resulttype:tnode;override;
  134. function getcopy: tnode;override;
  135. destructor destroy; override;
  136. protected
  137. call: tnode;
  138. end;
  139. tasnodeclass = class of tasnode;
  140. tisnode = class(tbinarynode)
  141. constructor create(l,r : tnode);virtual;
  142. function pass_1 : tnode;override;
  143. function det_resulttype:tnode;override;
  144. procedure pass_2;override;
  145. end;
  146. tisnodeclass = class of tisnode;
  147. var
  148. ctypeconvnode : ttypeconvnodeclass;
  149. casnode : tasnodeclass;
  150. cisnode : tisnodeclass;
  151. procedure inserttypeconv(var p:tnode;const t:ttype);
  152. procedure inserttypeconv_explicit(var p:tnode;const t:ttype);
  153. procedure arrayconstructor_to_set(var p : tnode);
  154. implementation
  155. uses
  156. globtype,systems,tokens,
  157. cutils,verbose,globals,widestr,
  158. symconst,symdef,symsym,symtable,
  159. ncon,ncal,nset,nadd,ninl,nmem,nmat,
  160. cgbase,
  161. htypechk,pass_1,cpubase,cpuinfo;
  162. {*****************************************************************************
  163. Helpers
  164. *****************************************************************************}
  165. procedure inserttypeconv(var p:tnode;const t:ttype);
  166. begin
  167. if not assigned(p.resulttype.def) then
  168. begin
  169. resulttypepass(p);
  170. if codegenerror then
  171. exit;
  172. end;
  173. { don't insert obsolete type conversions }
  174. if is_equal(p.resulttype.def,t.def) and
  175. not ((p.resulttype.def.deftype=setdef) and
  176. (tsetdef(p.resulttype.def).settype <>
  177. tsetdef(t.def).settype)) then
  178. begin
  179. p.resulttype:=t;
  180. end
  181. else
  182. begin
  183. p:=ctypeconvnode.create(p,t);
  184. resulttypepass(p);
  185. end;
  186. end;
  187. procedure inserttypeconv_explicit(var p:tnode;const t:ttype);
  188. begin
  189. if not assigned(p.resulttype.def) then
  190. begin
  191. resulttypepass(p);
  192. if codegenerror then
  193. exit;
  194. end;
  195. { don't insert obsolete type conversions }
  196. if is_equal(p.resulttype.def,t.def) and
  197. not ((p.resulttype.def.deftype=setdef) and
  198. (tsetdef(p.resulttype.def).settype <>
  199. tsetdef(t.def).settype)) then
  200. begin
  201. p.resulttype:=t;
  202. end
  203. else
  204. begin
  205. p:=ctypeconvnode.create_explicit(p,t);
  206. resulttypepass(p);
  207. end;
  208. end;
  209. {*****************************************************************************
  210. Array constructor to Set Conversion
  211. *****************************************************************************}
  212. procedure arrayconstructor_to_set(var p : tnode);
  213. var
  214. constp : tsetconstnode;
  215. buildp,
  216. p2,p3,p4 : tnode;
  217. htype : ttype;
  218. constset : Pconstset;
  219. constsetlo,
  220. constsethi : longint;
  221. procedure update_constsethi(t:ttype);
  222. begin
  223. if ((t.def.deftype=orddef) and
  224. (torddef(t.def).high>=constsethi)) then
  225. begin
  226. constsethi:=torddef(t.def).high;
  227. if htype.def=nil then
  228. begin
  229. if (constsethi>255) or
  230. (torddef(t.def).low<0) then
  231. htype:=u8bittype
  232. else
  233. htype:=t;
  234. end;
  235. if constsethi>255 then
  236. constsethi:=255;
  237. end
  238. else if ((t.def.deftype=enumdef) and
  239. (tenumdef(t.def).max>=constsethi)) then
  240. begin
  241. if htype.def=nil then
  242. htype:=t;
  243. constsethi:=tenumdef(t.def).max;
  244. end;
  245. end;
  246. procedure do_set(pos : longint);
  247. {$ifdef oldset}
  248. var
  249. mask,l : longint;
  250. {$endif}
  251. begin
  252. if (pos and not $ff)<>0 then
  253. Message(parser_e_illegal_set_expr);
  254. if pos>constsethi then
  255. constsethi:=pos;
  256. if pos<constsetlo then
  257. constsetlo:=pos;
  258. {$ifdef oldset}
  259. { to do this correctly we use the 32bit array }
  260. l:=pos shr 5;
  261. mask:=1 shl (pos mod 32);
  262. { do we allow the same twice }
  263. if (pconst32bitset(constset)^[l] and mask)<>0 then
  264. Message(parser_e_illegal_set_expr);
  265. pconst32bitset(constset)^[l]:=pconst32bitset(constset)^[l] or mask;
  266. {$else}
  267. include(constset^,pos);
  268. {$endif}
  269. end;
  270. var
  271. l : Longint;
  272. lr,hr : TConstExprInt;
  273. hp : tarrayconstructornode;
  274. begin
  275. if p.nodetype<>arrayconstructorn then
  276. internalerror(200205105);
  277. new(constset);
  278. {$ifdef oldset}
  279. FillChar(constset^,sizeof(constset^),0);
  280. {$else}
  281. constset^:=[];
  282. {$endif}
  283. htype.reset;
  284. constsetlo:=0;
  285. constsethi:=0;
  286. constp:=csetconstnode.create(nil,htype);
  287. constp.value_set:=constset;
  288. buildp:=constp;
  289. hp:=tarrayconstructornode(p);
  290. if assigned(hp.left) then
  291. begin
  292. while assigned(hp) do
  293. begin
  294. p4:=nil; { will contain the tree to create the set }
  295. {split a range into p2 and p3 }
  296. if hp.left.nodetype=arrayconstructorrangen then
  297. begin
  298. p2:=tarrayconstructorrangenode(hp.left).left;
  299. p3:=tarrayconstructorrangenode(hp.left).right;
  300. tarrayconstructorrangenode(hp.left).left:=nil;
  301. tarrayconstructorrangenode(hp.left).right:=nil;
  302. end
  303. else
  304. begin
  305. p2:=hp.left;
  306. hp.left:=nil;
  307. p3:=nil;
  308. end;
  309. resulttypepass(p2);
  310. if assigned(p3) then
  311. resulttypepass(p3);
  312. if codegenerror then
  313. break;
  314. case p2.resulttype.def.deftype of
  315. enumdef,
  316. orddef:
  317. begin
  318. getrange(p2.resulttype.def,lr,hr);
  319. if assigned(p3) then
  320. begin
  321. { this isn't good, you'll get problems with
  322. type t010 = 0..10;
  323. ts = set of t010;
  324. var s : ts;b : t010
  325. begin s:=[1,2,b]; end.
  326. if is_integer(p3^.resulttype.def) then
  327. begin
  328. inserttypeconv(p3,u8bitdef);
  329. end;
  330. }
  331. if assigned(htype.def) and not(is_equal(htype.def,p3.resulttype.def)) then
  332. begin
  333. aktfilepos:=p3.fileinfo;
  334. CGMessage(type_e_typeconflict_in_set);
  335. end
  336. else
  337. begin
  338. if (p2.nodetype=ordconstn) and (p3.nodetype=ordconstn) then
  339. begin
  340. if not(is_integer(p3.resulttype.def)) then
  341. htype:=p3.resulttype
  342. else
  343. begin
  344. inserttypeconv(p3,u8bittype);
  345. inserttypeconv(p2,u8bittype);
  346. end;
  347. for l:=tordconstnode(p2).value to tordconstnode(p3).value do
  348. do_set(l);
  349. p2.free;
  350. p3.free;
  351. end
  352. else
  353. begin
  354. update_constsethi(p2.resulttype);
  355. inserttypeconv(p2,htype);
  356. update_constsethi(p3.resulttype);
  357. inserttypeconv(p3,htype);
  358. if assigned(htype.def) then
  359. inserttypeconv(p3,htype)
  360. else
  361. inserttypeconv(p3,u8bittype);
  362. p4:=csetelementnode.create(p2,p3);
  363. end;
  364. end;
  365. end
  366. else
  367. begin
  368. { Single value }
  369. if p2.nodetype=ordconstn then
  370. begin
  371. if not(is_integer(p2.resulttype.def)) then
  372. update_constsethi(p2.resulttype)
  373. else
  374. inserttypeconv(p2,u8bittype);
  375. do_set(tordconstnode(p2).value);
  376. p2.free;
  377. end
  378. else
  379. begin
  380. update_constsethi(p2.resulttype);
  381. if assigned(htype.def) then
  382. inserttypeconv(p2,htype)
  383. else
  384. inserttypeconv(p2,u8bittype);
  385. p4:=csetelementnode.create(p2,nil);
  386. end;
  387. end;
  388. end;
  389. stringdef :
  390. begin
  391. { if we've already set elements which are constants }
  392. { throw an error }
  393. if ((htype.def=nil) and assigned(buildp)) or
  394. not(is_char(htype.def)) then
  395. CGMessage(type_e_typeconflict_in_set)
  396. else
  397. for l:=1 to length(pstring(tstringconstnode(p2).value_str)^) do
  398. do_set(ord(pstring(tstringconstnode(p2).value_str)^[l]));
  399. if htype.def=nil then
  400. htype:=cchartype;
  401. p2.free;
  402. end;
  403. else
  404. CGMessage(type_e_ordinal_expr_expected);
  405. end;
  406. { insert the set creation tree }
  407. if assigned(p4) then
  408. buildp:=caddnode.create(addn,buildp,p4);
  409. { load next and dispose current node }
  410. p2:=hp;
  411. hp:=tarrayconstructornode(tarrayconstructornode(p2).right);
  412. tarrayconstructornode(p2).right:=nil;
  413. p2.free;
  414. end;
  415. if (htype.def=nil) then
  416. htype:=u8bittype;
  417. end
  418. else
  419. begin
  420. { empty set [], only remove node }
  421. p.free;
  422. end;
  423. { set the initial set type }
  424. constp.resulttype.setdef(tsetdef.create(htype,constsethi));
  425. { determine the resulttype for the tree }
  426. resulttypepass(buildp);
  427. { set the new tree }
  428. p:=buildp;
  429. end;
  430. {*****************************************************************************
  431. TTYPECONVNODE
  432. *****************************************************************************}
  433. constructor ttypeconvnode.create(node : tnode;const t:ttype);
  434. begin
  435. inherited create(typeconvn,node);
  436. convtype:=tc_not_possible;
  437. totype:=t;
  438. if t.def=nil then
  439. internalerror(200103281);
  440. set_file_line(node);
  441. end;
  442. constructor ttypeconvnode.create_explicit(node : tnode;const t:ttype);
  443. begin
  444. self.create(node,t);
  445. toggleflag(nf_explizit);
  446. end;
  447. constructor ttypeconvnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  448. begin
  449. inherited ppuload(t,ppufile);
  450. ppufile.gettype(totype);
  451. convtype:=tconverttype(ppufile.getbyte);
  452. end;
  453. procedure ttypeconvnode.ppuwrite(ppufile:tcompilerppufile);
  454. begin
  455. inherited ppuwrite(ppufile);
  456. ppufile.puttype(totype);
  457. ppufile.putbyte(byte(convtype));
  458. end;
  459. procedure ttypeconvnode.derefimpl;
  460. begin
  461. inherited derefimpl;
  462. totype.resolve;
  463. end;
  464. function ttypeconvnode.getcopy : tnode;
  465. var
  466. n : ttypeconvnode;
  467. begin
  468. n:=ttypeconvnode(inherited getcopy);
  469. n.convtype:=convtype;
  470. getcopy:=n;
  471. end;
  472. function ttypeconvnode.resulttype_cord_to_pointer : tnode;
  473. var
  474. t : tnode;
  475. begin
  476. result:=nil;
  477. if left.nodetype=ordconstn then
  478. begin
  479. { check if we have a valid pointer constant (JM) }
  480. if (sizeof(pointer) > sizeof(TConstPtrUInt)) then
  481. if (sizeof(TConstPtrUInt) = 4) then
  482. begin
  483. if (tordconstnode(left).value < low(longint)) or
  484. (tordconstnode(left).value > high(cardinal)) then
  485. CGMessage(parser_e_range_check_error);
  486. end
  487. else if (sizeof(TConstPtrUInt) = 8) then
  488. begin
  489. if (tordconstnode(left).value < low(int64)) or
  490. (tordconstnode(left).value > high(qword)) then
  491. CGMessage(parser_e_range_check_error);
  492. end
  493. else
  494. internalerror(2001020801);
  495. t:=cpointerconstnode.create(TConstPtrUInt(tordconstnode(left).value),resulttype);
  496. result:=t;
  497. end
  498. else
  499. internalerror(200104023);
  500. end;
  501. function ttypeconvnode.resulttype_chararray_to_string : tnode;
  502. begin
  503. result := ccallnode.createinternres(
  504. 'fpc_chararray_to_'+tstringdef(resulttype.def).stringtypname,
  505. ccallparanode.create(left,nil),resulttype);
  506. left := nil;
  507. end;
  508. function ttypeconvnode.resulttype_string_to_chararray : tnode;
  509. var
  510. arrsize: longint;
  511. begin
  512. with tarraydef(resulttype.def) do
  513. begin
  514. if highrange<lowrange then
  515. internalerror(75432653);
  516. arrsize := highrange-lowrange+1;
  517. end;
  518. if (left.nodetype = stringconstn) and
  519. { left.length+1 since there's always a terminating #0 character (JM) }
  520. (tstringconstnode(left).len+1 >= arrsize) and
  521. (tstringdef(left.resulttype.def).string_typ=st_shortstring) then
  522. begin
  523. { handled separately }
  524. result := nil;
  525. exit;
  526. end;
  527. result := ccallnode.createinternres(
  528. 'fpc_'+tstringdef(left.resulttype.def).stringtypname+
  529. '_to_chararray',ccallparanode.create(left,ccallparanode.create(
  530. cordconstnode.create(arrsize,s32bittype,true),nil)),resulttype);
  531. left := nil;
  532. end;
  533. function ttypeconvnode.resulttype_string_to_string : tnode;
  534. var
  535. procname: string[31];
  536. stringpara : tcallparanode;
  537. pw : pcompilerwidestring;
  538. pc : pchar;
  539. begin
  540. result:=nil;
  541. if left.nodetype=stringconstn then
  542. begin
  543. { convert ascii 2 unicode }
  544. if (tstringdef(resulttype.def).string_typ=st_widestring) and
  545. (tstringconstnode(left).st_type in [st_ansistring,st_shortstring,st_longstring]) then
  546. begin
  547. initwidestring(pw);
  548. ascii2unicode(tstringconstnode(left).value_str,tstringconstnode(left).len,pw);
  549. ansistringdispose(tstringconstnode(left).value_str,tstringconstnode(left).len);
  550. pcompilerwidestring(tstringconstnode(left).value_str):=pw;
  551. end
  552. else
  553. { convert unicode 2 ascii }
  554. if (tstringconstnode(left).st_type=st_widestring) and
  555. (tstringdef(resulttype.def).string_typ in [st_ansistring,st_shortstring,st_longstring]) then
  556. begin
  557. pw:=pcompilerwidestring(tstringconstnode(left).value_str);
  558. getmem(pc,getlengthwidestring(pw)+1);
  559. unicode2ascii(pw,pc);
  560. donewidestring(pw);
  561. tstringconstnode(left).value_str:=pc;
  562. end;
  563. tstringconstnode(left).st_type:=tstringdef(resulttype.def).string_typ;
  564. tstringconstnode(left).resulttype:=resulttype;
  565. result:=left;
  566. left:=nil;
  567. end
  568. else
  569. begin
  570. { get the correct procedure name }
  571. procname := 'fpc_'+tstringdef(left.resulttype.def).stringtypname+
  572. '_to_'+tstringdef(resulttype.def).stringtypname;
  573. { create parameter (and remove left node from typeconvnode }
  574. { since it's reused as parameter) }
  575. stringpara := ccallparanode.create(left,nil);
  576. left := nil;
  577. { when converting to shortstrings, we have to pass high(destination) too }
  578. if (tstringdef(resulttype.def).string_typ = st_shortstring) then
  579. stringpara.right := ccallparanode.create(cinlinenode.create(
  580. in_high_x,false,self.getcopy),nil);
  581. { and create the callnode }
  582. result := ccallnode.createinternres(procname,stringpara,resulttype);
  583. end;
  584. end;
  585. function ttypeconvnode.resulttype_char_to_string : tnode;
  586. var
  587. procname: string[31];
  588. para : tcallparanode;
  589. hp : tstringconstnode;
  590. ws : pcompilerwidestring;
  591. begin
  592. result:=nil;
  593. if left.nodetype=ordconstn then
  594. begin
  595. if tstringdef(resulttype.def).string_typ=st_widestring then
  596. begin
  597. initwidestring(ws);
  598. concatwidestringchar(ws,tcompilerwidechar(chr(tordconstnode(left).value)));
  599. hp:=cstringconstnode.createwstr(ws);
  600. donewidestring(ws);
  601. end
  602. else
  603. hp:=cstringconstnode.createstr(chr(tordconstnode(left).value),tstringdef(resulttype.def).string_typ);
  604. result:=hp;
  605. end
  606. else
  607. { shortstrings are handled 'inline' }
  608. if tstringdef(resulttype.def).string_typ <> st_shortstring then
  609. begin
  610. { create the parameter }
  611. para := ccallparanode.create(left,nil);
  612. left := nil;
  613. { and the procname }
  614. procname := 'fpc_char_to_' +tstringdef(resulttype.def).stringtypname;
  615. { and finally the call }
  616. result := ccallnode.createinternres(procname,para,resulttype);
  617. end
  618. else
  619. begin
  620. { create word(byte(char) shl 8 or 1) for litte endian machines }
  621. { and word(byte(char) or 256) for big endian machines }
  622. left := ctypeconvnode.create(left,u8bittype);
  623. left.toggleflag(nf_explizit);
  624. if (target_info.endian = endian_little) then
  625. left := caddnode.create(orn,
  626. cshlshrnode.create(shln,left,cordconstnode.create(8,s32bittype,false)),
  627. cordconstnode.create(1,s32bittype,false))
  628. else
  629. left := caddnode.create(orn,left,
  630. cordconstnode.create(1 shl 8,s32bittype,false));
  631. left := ctypeconvnode.create(left,u16bittype);
  632. left.toggleflag(nf_explizit);
  633. resulttypepass(left);
  634. end;
  635. end;
  636. function ttypeconvnode.resulttype_char_to_chararray : tnode;
  637. begin
  638. if resulttype.def.size <> 1 then
  639. begin
  640. { convert first to string, then to chararray }
  641. inserttypeconv(left,cshortstringtype);
  642. inserttypeconv(left,resulttype);
  643. result:=left;
  644. left := nil;
  645. exit;
  646. end;
  647. result := nil;
  648. end;
  649. function ttypeconvnode.resulttype_char_to_char : tnode;
  650. var
  651. hp : tordconstnode;
  652. begin
  653. result:=nil;
  654. if left.nodetype=ordconstn then
  655. begin
  656. if (torddef(resulttype.def).typ=uchar) and
  657. (torddef(left.resulttype.def).typ=uwidechar) then
  658. begin
  659. hp:=cordconstnode.create(
  660. ord(unicode2asciichar(tcompilerwidechar(tordconstnode(left).value))),
  661. cchartype,true);
  662. result:=hp;
  663. end
  664. else if (torddef(resulttype.def).typ=uwidechar) and
  665. (torddef(left.resulttype.def).typ=uchar) then
  666. begin
  667. hp:=cordconstnode.create(
  668. asciichar2unicode(chr(tordconstnode(left).value)),
  669. cwidechartype,true);
  670. result:=hp;
  671. end
  672. else
  673. internalerror(200105131);
  674. exit;
  675. end;
  676. end;
  677. function ttypeconvnode.resulttype_int_to_real : tnode;
  678. var
  679. t : trealconstnode;
  680. begin
  681. result:=nil;
  682. if left.nodetype=ordconstn then
  683. begin
  684. t:=crealconstnode.create(tordconstnode(left).value,resulttype);
  685. result:=t;
  686. end;
  687. end;
  688. function ttypeconvnode.resulttype_real_to_real : tnode;
  689. var
  690. t : tnode;
  691. begin
  692. result:=nil;
  693. if is_currency(left.resulttype.def) and not(is_currency(resulttype.def)) then
  694. begin
  695. end
  696. else
  697. if is_currency(resulttype.def) then
  698. begin
  699. end;
  700. if left.nodetype=realconstn then
  701. begin
  702. t:=crealconstnode.create(trealconstnode(left).value_real,resulttype);
  703. result:=t;
  704. end;
  705. end;
  706. function ttypeconvnode.resulttype_cchar_to_pchar : tnode;
  707. begin
  708. result:=nil;
  709. if is_pwidechar(resulttype.def) then
  710. inserttypeconv(left,cwidestringtype)
  711. else
  712. inserttypeconv(left,cshortstringtype);
  713. { evaluate again, reset resulttype so the convert_typ
  714. will be calculated again and cstring_to_pchar will
  715. be used for futher conversion }
  716. result:=det_resulttype;
  717. end;
  718. function ttypeconvnode.resulttype_cstring_to_pchar : tnode;
  719. begin
  720. result:=nil;
  721. if is_pwidechar(resulttype.def) then
  722. inserttypeconv(left,cwidestringtype);
  723. end;
  724. function ttypeconvnode.resulttype_arrayconstructor_to_set : tnode;
  725. var
  726. hp : tnode;
  727. begin
  728. result:=nil;
  729. if left.nodetype<>arrayconstructorn then
  730. internalerror(5546);
  731. { remove typeconv node }
  732. hp:=left;
  733. left:=nil;
  734. { create a set constructor tree }
  735. arrayconstructor_to_set(hp);
  736. result:=hp;
  737. end;
  738. function ttypeconvnode.resulttype_pchar_to_string : tnode;
  739. begin
  740. result := ccallnode.createinternres(
  741. 'fpc_pchar_to_'+tstringdef(resulttype.def).stringtypname,
  742. ccallparanode.create(left,nil),resulttype);
  743. left := nil;
  744. end;
  745. function ttypeconvnode.resulttype_interface_to_guid : tnode;
  746. begin
  747. if tobjectdef(left.resulttype.def).isiidguidvalid then
  748. result:=cguidconstnode.create(tobjectdef(left.resulttype.def).iidguid);
  749. end;
  750. function ttypeconvnode.resulttype_dynarray_to_openarray : tnode;
  751. begin
  752. { a dynamic array is a pointer to an array, so to convert it to }
  753. { an open array, we have to dereference it (JM) }
  754. result := ctypeconvnode.create(left,voidpointertype);
  755. { left is reused }
  756. left := nil;
  757. result.toggleflag(nf_explizit);
  758. result := cderefnode.create(result);
  759. result.resulttype := resulttype;
  760. end;
  761. function ttypeconvnode.resulttype_pwchar_to_string : tnode;
  762. begin
  763. result := ccallnode.createinternres(
  764. 'fpc_pwidechar_to_'+tstringdef(resulttype.def).stringtypname,
  765. ccallparanode.create(left,nil),resulttype);
  766. left := nil;
  767. end;
  768. function ttypeconvnode.resulttype_call_helper(c : tconverttype) : tnode;
  769. {$ifdef fpc}
  770. const
  771. resulttypeconvert : array[tconverttype] of pointer = (
  772. {equal} nil,
  773. {not_possible} nil,
  774. { string_2_string } @ttypeconvnode.resulttype_string_to_string,
  775. { char_2_string } @ttypeconvnode.resulttype_char_to_string,
  776. { char_2_chararray } @ttypeconvnode.resulttype_char_to_chararray,
  777. { pchar_2_string } @ttypeconvnode.resulttype_pchar_to_string,
  778. { cchar_2_pchar } @ttypeconvnode.resulttype_cchar_to_pchar,
  779. { cstring_2_pchar } @ttypeconvnode.resulttype_cstring_to_pchar,
  780. { ansistring_2_pchar } nil,
  781. { string_2_chararray } @ttypeconvnode.resulttype_string_to_chararray,
  782. { chararray_2_string } @ttypeconvnode.resulttype_chararray_to_string,
  783. { array_2_pointer } nil,
  784. { pointer_2_array } nil,
  785. { int_2_int } nil,
  786. { int_2_bool } nil,
  787. { bool_2_bool } nil,
  788. { bool_2_int } nil,
  789. { real_2_real } @ttypeconvnode.resulttype_real_to_real,
  790. { int_2_real } @ttypeconvnode.resulttype_int_to_real,
  791. { proc_2_procvar } nil,
  792. { arrayconstructor_2_set } @ttypeconvnode.resulttype_arrayconstructor_to_set,
  793. { load_smallset } nil,
  794. { cord_2_pointer } @ttypeconvnode.resulttype_cord_to_pointer,
  795. { intf_2_string } nil,
  796. { intf_2_guid } @ttypeconvnode.resulttype_interface_to_guid,
  797. { class_2_intf } nil,
  798. { char_2_char } @ttypeconvnode.resulttype_char_to_char,
  799. { normal_2_smallset} nil,
  800. { dynarray_2_openarray} @resulttype_dynarray_to_openarray,
  801. { pwchar_2_string} @resulttype_pwchar_to_string
  802. );
  803. type
  804. tprocedureofobject = function : tnode of object;
  805. var
  806. r : packed record
  807. proc : pointer;
  808. obj : pointer;
  809. end;
  810. begin
  811. result:=nil;
  812. { this is a little bit dirty but it works }
  813. { and should be quite portable too }
  814. r.proc:=resulttypeconvert[c];
  815. r.obj:=self;
  816. if assigned(r.proc) then
  817. result:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
  818. end;
  819. {$else}
  820. begin
  821. case c of
  822. tc_string_2_string: resulttype_string_to_string;
  823. tc_char_2_string : resulttype_char_to_string;
  824. tc_char_2_chararray: resulttype_char_to_chararray;
  825. tc_pchar_2_string : resulttype_pchar_to_string;
  826. tc_cchar_2_pchar : resulttype_cchar_to_pchar;
  827. tc_cstring_2_pchar : resulttype_cstring_to_pchar;
  828. tc_string_2_chararray : resulttype_string_to_chararray;
  829. tc_chararray_2_string : resulttype_chararray_to_string;
  830. tc_real_2_real : resulttype_real_to_real;
  831. tc_int_2_real : resulttype_int_to_real;
  832. tc_arrayconstructor_2_set : resulttype_arrayconstructor_to_set;
  833. tc_cord_2_pointer : resulttype_cord_to_pointer;
  834. tc_intf_2_guid : resulttype_interface_to_guid;
  835. tc_char_2_char : resulttype_char_to_char;
  836. tc_dynarray_2_openarray : resulttype_dynarray_to_openarray;
  837. tc_pwchar_2_string : resulttype_pwchar_to_string;
  838. end;
  839. end;
  840. {$Endif fpc}
  841. function ttypeconvnode.det_resulttype:tnode;
  842. var
  843. hp : tnode;
  844. currprocdef,
  845. aprocdef : tprocdef;
  846. begin
  847. result:=nil;
  848. resulttype:=totype;
  849. resulttypepass(left);
  850. if codegenerror then
  851. exit;
  852. { remove obsolete type conversions }
  853. if is_equal(left.resulttype.def,resulttype.def) then
  854. begin
  855. { because is_equal only checks the basetype for sets we need to
  856. check here if we are loading a smallset into a normalset }
  857. if (resulttype.def.deftype=setdef) and
  858. (left.resulttype.def.deftype=setdef) and
  859. ((tsetdef(resulttype.def).settype = smallset) xor
  860. (tsetdef(left.resulttype.def).settype = smallset)) then
  861. begin
  862. { constant sets can be converted by changing the type only }
  863. if (left.nodetype=setconstn) then
  864. begin
  865. tsetdef(left.resulttype.def).changesettype(tsetdef(resulttype.def).settype);
  866. result:=left;
  867. left:=nil;
  868. exit;
  869. end;
  870. if (tsetdef(resulttype.def).settype <> smallset) then
  871. convtype:=tc_load_smallset
  872. else
  873. convtype := tc_normal_2_smallset;
  874. exit;
  875. end
  876. else
  877. begin
  878. left.resulttype:=resulttype;
  879. result:=left;
  880. left:=nil;
  881. exit;
  882. end;
  883. end;
  884. aprocdef:=assignment_overloaded(left.resulttype.def,resulttype.def);
  885. if assigned(aprocdef) then
  886. begin
  887. procinfo.flags:=procinfo.flags or pi_do_call;
  888. hp:=ccallnode.create(ccallparanode.create(left,nil),
  889. overloaded_operators[_assignment],nil,nil);
  890. { tell explicitly which def we must use !! (PM) }
  891. tcallnode(hp).procdefinition:=aprocdef;
  892. left:=nil;
  893. result:=hp;
  894. exit;
  895. end;
  896. if isconvertable(left.resulttype.def,resulttype.def,convtype,left.nodetype,nf_explizit in flags)=0 then
  897. begin
  898. {Procedures have a resulttype.def of voiddef and functions of their
  899. own resulttype.def. They will therefore always be incompatible with
  900. a procvar. Because isconvertable cannot check for procedures we
  901. use an extra check for them.}
  902. if (m_tp_procvar in aktmodeswitches) then
  903. begin
  904. if (resulttype.def.deftype=procvardef) and
  905. (is_procsym_load(left) or is_procsym_call(left)) then
  906. begin
  907. if is_procsym_call(left) then
  908. begin
  909. currprocdef:=Tprocsym(Tcallnode(left).symtableprocentry).search_procdef_byprocvardef(Tprocvardef(resulttype.def));
  910. hp:=cloadnode.create_procvar(tprocsym(tcallnode(left).symtableprocentry),
  911. currprocdef,tcallnode(left).symtableproc);
  912. if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) and
  913. assigned(tcallnode(left).methodpointer) then
  914. tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy);
  915. resulttypepass(hp);
  916. left.free;
  917. left:=hp;
  918. aprocdef:=tprocdef(left.resulttype.def);
  919. end
  920. else
  921. begin
  922. if (left.nodetype<>addrn) then
  923. aprocdef:=tprocsym(tloadnode(left).symtableentry).first_procdef;
  924. end;
  925. convtype:=tc_proc_2_procvar;
  926. { Now check if the procedure we are going to assign to
  927. the procvar, is compatible with the procvar's type }
  928. if assigned(aprocdef) then
  929. begin
  930. if not proc_to_procvar_equal(aprocdef,tprocvardef(resulttype.def),false) then
  931. CGMessage2(type_e_incompatible_types,aprocdef.typename,resulttype.def.typename);
  932. end
  933. else
  934. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  935. exit;
  936. end;
  937. end;
  938. if nf_explizit in flags then
  939. begin
  940. { check if the result could be in a register }
  941. if not(tstoreddef(resulttype.def).is_intregable) and
  942. not(tstoreddef(resulttype.def).is_fpuregable) then
  943. make_not_regable(left);
  944. { boolean to byte are special because the
  945. location can be different }
  946. if is_integer(resulttype.def) and
  947. is_boolean(left.resulttype.def) then
  948. begin
  949. convtype:=tc_bool_2_int;
  950. exit;
  951. end;
  952. if is_char(resulttype.def) and
  953. is_boolean(left.resulttype.def) then
  954. begin
  955. convtype:=tc_bool_2_int;
  956. exit;
  957. end;
  958. { ansistring to pchar }
  959. if is_pchar(resulttype.def) and
  960. is_ansistring(left.resulttype.def) then
  961. begin
  962. convtype:=tc_ansistring_2_pchar;
  963. exit;
  964. end;
  965. { do common tc_equal cast }
  966. convtype:=tc_equal;
  967. { enum to ordinal will always be s32bit }
  968. if (left.resulttype.def.deftype=enumdef) and
  969. is_ordinal(resulttype.def) then
  970. begin
  971. if left.nodetype=ordconstn then
  972. begin
  973. hp:=cordconstnode.create(tordconstnode(left).value,
  974. resulttype,true);
  975. result:=hp;
  976. exit;
  977. end
  978. else
  979. begin
  980. if isconvertable(s32bittype.def,resulttype.def,convtype,ordconstn,false)=0 then
  981. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  982. end;
  983. end
  984. { ordinal to enumeration }
  985. else
  986. if (resulttype.def.deftype=enumdef) and
  987. is_ordinal(left.resulttype.def) then
  988. begin
  989. if left.nodetype=ordconstn then
  990. begin
  991. hp:=cordconstnode.create(tordconstnode(left).value,
  992. resulttype,true);
  993. result:=hp;
  994. exit;
  995. end
  996. else
  997. begin
  998. if IsConvertable(left.resulttype.def,s32bittype.def,convtype,ordconstn,false)=0 then
  999. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1000. end;
  1001. end
  1002. { nil to ordinal node }
  1003. else if (left.nodetype=niln) and is_ordinal(resulttype.def) then
  1004. begin
  1005. hp:=cordconstnode.create(0,resulttype,true);
  1006. result:=hp;
  1007. exit;
  1008. end
  1009. { constant pointer to ordinal }
  1010. else if is_ordinal(resulttype.def) and
  1011. (left.nodetype=pointerconstn) then
  1012. begin
  1013. hp:=cordconstnode.create(tpointerconstnode(left).value,
  1014. resulttype,true);
  1015. result:=hp;
  1016. exit;
  1017. end
  1018. { class to class or object to object, with checkobject support }
  1019. else if (resulttype.def.deftype=objectdef) and
  1020. (left.resulttype.def.deftype=objectdef) then
  1021. begin
  1022. if (cs_check_object in aktlocalswitches) then
  1023. begin
  1024. if is_class_or_interface(resulttype.def) then
  1025. begin
  1026. { we can translate the typeconvnode to 'as' when
  1027. typecasting to a class or interface }
  1028. hp:=casnode.create(left,cloadvmtnode.create(ctypenode.create(resulttype)));
  1029. left:=nil;
  1030. result:=hp;
  1031. exit;
  1032. end;
  1033. end
  1034. else
  1035. begin
  1036. { check if the types are related }
  1037. if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(resulttype.def)))) and
  1038. (not(tobjectdef(resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
  1039. CGMessage2(type_w_classes_not_related,left.resulttype.def.typename,resulttype.def.typename);
  1040. end;
  1041. end
  1042. {Are we typecasting an ordconst to a char?}
  1043. else
  1044. if is_char(resulttype.def) and
  1045. is_ordinal(left.resulttype.def) then
  1046. begin
  1047. if left.nodetype=ordconstn then
  1048. begin
  1049. hp:=cordconstnode.create(tordconstnode(left).value,
  1050. resulttype,true);
  1051. result:=hp;
  1052. exit;
  1053. end
  1054. else
  1055. begin
  1056. if IsConvertable(left.resulttype.def,u8bittype.def,convtype,ordconstn,false)=0 then
  1057. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1058. end;
  1059. end
  1060. {Are we typecasting an ordconst to a wchar?}
  1061. else
  1062. if is_widechar(resulttype.def) and
  1063. is_ordinal(left.resulttype.def) then
  1064. begin
  1065. if left.nodetype=ordconstn then
  1066. begin
  1067. hp:=cordconstnode.create(tordconstnode(left).value,
  1068. resulttype,true);
  1069. result:=hp;
  1070. exit;
  1071. end
  1072. else
  1073. begin
  1074. if IsConvertable(left.resulttype.def,u16bittype.def,convtype,ordconstn,false)=0 then
  1075. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1076. end;
  1077. end
  1078. { char to ordinal }
  1079. else
  1080. if is_char(left.resulttype.def) and
  1081. is_ordinal(resulttype.def) then
  1082. begin
  1083. if left.nodetype=ordconstn then
  1084. begin
  1085. hp:=cordconstnode.create(tordconstnode(left).value,
  1086. resulttype,true);
  1087. result:=hp;
  1088. exit;
  1089. end
  1090. else
  1091. begin
  1092. if IsConvertable(u8bittype.def,resulttype.def,convtype,ordconstn,false)=0 then
  1093. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1094. end;
  1095. end
  1096. { widechar to ordinal }
  1097. else
  1098. if is_widechar(left.resulttype.def) and
  1099. is_ordinal(resulttype.def) then
  1100. begin
  1101. if left.nodetype=ordconstn then
  1102. begin
  1103. hp:=cordconstnode.create(tordconstnode(left).value,
  1104. resulttype,true);
  1105. result:=hp;
  1106. exit;
  1107. end
  1108. else
  1109. begin
  1110. if IsConvertable(u16bittype.def,resulttype.def,convtype,ordconstn,false)=0 then
  1111. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1112. end;
  1113. end
  1114. { ordinal to pointer }
  1115. else
  1116. if (m_delphi in aktmodeswitches) and
  1117. is_ordinal(left.resulttype.def) and
  1118. (resulttype.def.deftype=pointerdef) then
  1119. begin
  1120. if left.nodetype=pointerconstn then
  1121. begin
  1122. hp:=cordconstnode.create(tpointerconstnode(left).value,
  1123. resulttype,true);
  1124. result:=hp;
  1125. exit;
  1126. end
  1127. else
  1128. begin
  1129. if IsConvertable(left.resulttype.def,ordpointertype.def,convtype,ordconstn,false)=0 then
  1130. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1131. end;
  1132. end
  1133. { only if the same size or formal def }
  1134. { why do we allow typecasting of voiddef ?? (PM) }
  1135. else
  1136. begin
  1137. if not(
  1138. (left.resulttype.def.deftype=formaldef) or
  1139. (not(is_open_array(left.resulttype.def)) and
  1140. (left.resulttype.def.size=resulttype.def.size)) or
  1141. (is_void(left.resulttype.def) and
  1142. (left.nodetype=derefn))
  1143. ) then
  1144. CGMessage(cg_e_illegal_type_conversion);
  1145. if ((left.resulttype.def.deftype=orddef) and
  1146. (resulttype.def.deftype=pointerdef)) or
  1147. ((resulttype.def.deftype=orddef) and
  1148. (left.resulttype.def.deftype=pointerdef)) then
  1149. CGMessage(cg_d_pointer_to_longint_conv_not_portable);
  1150. end;
  1151. { the conversion into a strutured type is only }
  1152. { possible, if the source is not a register }
  1153. if ((resulttype.def.deftype in [recorddef,stringdef,arraydef]) or
  1154. ((resulttype.def.deftype=objectdef) and not(is_class(resulttype.def)))
  1155. ) and (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
  1156. it also works if the assignment is overloaded
  1157. YES but this code is not executed if assignment is overloaded (PM)
  1158. not assigned(assignment_overloaded(left.resulttype.def,resulttype.def))} then
  1159. CGMessage(cg_e_illegal_type_conversion);
  1160. end
  1161. else
  1162. CGMessage2(type_e_incompatible_types,left.resulttype.def.typename,resulttype.def.typename);
  1163. end;
  1164. { tp7 procvar support, when right is not a procvardef and we got a
  1165. loadn of a procvar then convert to a calln, the check for the
  1166. result is already done in is_convertible, also no conflict with
  1167. @procvar is here because that has an extra addrn }
  1168. if (m_tp_procvar in aktmodeswitches) and
  1169. (resulttype.def.deftype<>procvardef) and
  1170. (left.resulttype.def.deftype=procvardef) and
  1171. (left.nodetype=loadn) then
  1172. begin
  1173. hp:=ccallnode.create(nil,nil,nil,nil);
  1174. tcallnode(hp).set_procvar(left);
  1175. resulttypepass(hp);
  1176. left:=hp;
  1177. end;
  1178. { remove typeconv after niln, but not when the result is a
  1179. methodpointer. The typeconv of the methodpointer will then
  1180. take care of updateing size of niln to OS_64 }
  1181. if (left.nodetype=niln) and
  1182. not((resulttype.def.deftype=procvardef) and
  1183. (po_methodpointer in tprocvardef(resulttype.def).procoptions)) then
  1184. begin
  1185. left.resulttype:=resulttype;
  1186. result:=left;
  1187. left:=nil;
  1188. exit;
  1189. end;
  1190. { ordinal contants can be directly converted }
  1191. if (left.nodetype=ordconstn) and is_ordinal(resulttype.def) and
  1192. { but not char to char because it is a widechar to char or via versa }
  1193. { which needs extra code to do the code page transistion }
  1194. not(convtype=tc_char_2_char) then
  1195. begin
  1196. { replace the resulttype and recheck the range }
  1197. left.resulttype:=resulttype;
  1198. testrange(left.resulttype.def,tordconstnode(left).value,(nf_explizit in flags));
  1199. result:=left;
  1200. left:=nil;
  1201. exit;
  1202. end;
  1203. { fold nil to any pointer type }
  1204. if (left.nodetype=niln) and (resulttype.def.deftype=pointerdef) then
  1205. begin
  1206. hp:=cnilnode.create;
  1207. hp.resulttype:=resulttype;
  1208. result:=hp;
  1209. exit;
  1210. end;
  1211. { further, pointerconstn to any pointer is folded too }
  1212. if (left.nodetype=pointerconstn) and (resulttype.def.deftype=pointerdef) then
  1213. begin
  1214. left.resulttype:=resulttype;
  1215. result:=left;
  1216. left:=nil;
  1217. exit;
  1218. end;
  1219. { now call the resulttype helper to do constant folding }
  1220. result:=resulttype_call_helper(convtype);
  1221. end;
  1222. {$ifdef var_notification}
  1223. procedure Ttypeconvnode.mark_write;
  1224. begin
  1225. left.mark_write;
  1226. end;
  1227. {$endif}
  1228. function ttypeconvnode.first_cord_to_pointer : tnode;
  1229. begin
  1230. result:=nil;
  1231. internalerror(200104043);
  1232. end;
  1233. function ttypeconvnode.first_int_to_int : tnode;
  1234. begin
  1235. first_int_to_int:=nil;
  1236. if (left.location.loc<>LOC_REGISTER) and
  1237. (resulttype.def.size>left.resulttype.def.size) then
  1238. location.loc:=LOC_REGISTER;
  1239. if is_64bitint(resulttype.def) then
  1240. registers32:=max(registers32,2)
  1241. else
  1242. registers32:=max(registers32,1);
  1243. end;
  1244. function ttypeconvnode.first_cstring_to_pchar : tnode;
  1245. begin
  1246. first_cstring_to_pchar:=nil;
  1247. registers32:=1;
  1248. location.loc:=LOC_REGISTER;
  1249. end;
  1250. function ttypeconvnode.first_string_to_chararray : tnode;
  1251. begin
  1252. first_string_to_chararray:=nil;
  1253. registers32:=1;
  1254. location.loc:=LOC_REGISTER;
  1255. end;
  1256. function ttypeconvnode.first_char_to_string : tnode;
  1257. begin
  1258. first_char_to_string:=nil;
  1259. location.loc:=LOC_CREFERENCE;
  1260. end;
  1261. function ttypeconvnode.first_nothing : tnode;
  1262. begin
  1263. first_nothing:=nil;
  1264. end;
  1265. function ttypeconvnode.first_array_to_pointer : tnode;
  1266. begin
  1267. first_array_to_pointer:=nil;
  1268. if registers32<1 then
  1269. registers32:=1;
  1270. location.loc:=LOC_REGISTER;
  1271. end;
  1272. function ttypeconvnode.first_int_to_real: tnode;
  1273. var
  1274. fname: string[19];
  1275. typname : string[12];
  1276. begin
  1277. { Get the type name }
  1278. { Normally the typename should be one of the following:
  1279. single, double - carl
  1280. }
  1281. typname := lower(pbestrealtype^.def.gettypename);
  1282. { converting a 64bit integer to a float requires a helper }
  1283. if is_64bitint(left.resulttype.def) then
  1284. begin
  1285. if is_signed(left.resulttype.def) then
  1286. fname := 'fpc_int64_to_'+typname
  1287. else
  1288. fname := 'fpc_qword_to_'+typname;
  1289. result := ccallnode.createintern(fname,ccallparanode.create(
  1290. left,nil));
  1291. left:=nil;
  1292. firstpass(result);
  1293. exit;
  1294. end
  1295. else
  1296. { other integers are supposed to be 32 bit }
  1297. begin
  1298. if is_signed(left.resulttype.def) then
  1299. fname := 'fpc_longint_to_'+typname
  1300. else
  1301. fname := 'fpc_longword_to_'+typname;
  1302. result := ccallnode.createintern(fname,ccallparanode.create(
  1303. left,nil));
  1304. left:=nil;
  1305. firstpass(result);
  1306. exit;
  1307. end;
  1308. end;
  1309. function ttypeconvnode.first_real_to_real : tnode;
  1310. begin
  1311. first_real_to_real:=nil;
  1312. { comp isn't a floating type }
  1313. {$ifdef i386}
  1314. if (tfloatdef(resulttype.def).typ=s64comp) and
  1315. (tfloatdef(left.resulttype.def).typ<>s64comp) and
  1316. not (nf_explizit in flags) then
  1317. CGMessage(type_w_convert_real_2_comp);
  1318. {$endif}
  1319. if registersfpu<1 then
  1320. registersfpu:=1;
  1321. location.loc:=LOC_FPUREGISTER;
  1322. end;
  1323. function ttypeconvnode.first_pointer_to_array : tnode;
  1324. begin
  1325. first_pointer_to_array:=nil;
  1326. if registers32<1 then
  1327. registers32:=1;
  1328. location.loc:=LOC_REFERENCE;
  1329. end;
  1330. function ttypeconvnode.first_cchar_to_pchar : tnode;
  1331. begin
  1332. first_cchar_to_pchar:=nil;
  1333. internalerror(200104021);
  1334. end;
  1335. function ttypeconvnode.first_bool_to_int : tnode;
  1336. begin
  1337. first_bool_to_int:=nil;
  1338. { byte(boolean) or word(wordbool) or longint(longbool) must
  1339. be accepted for var parameters }
  1340. if (nf_explizit in flags) and
  1341. (left.resulttype.def.size=resulttype.def.size) and
  1342. (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  1343. exit;
  1344. { when converting to 64bit, first convert to a 32bit int and then }
  1345. { convert to a 64bit int (only necessary for 32bit processors) (JM) }
  1346. if resulttype.def.size > sizeof(aword) then
  1347. begin
  1348. result := ctypeconvnode.create(left,u32bittype);
  1349. result.toggleflag(nf_explizit);
  1350. result := ctypeconvnode.create(result,resulttype);
  1351. left := nil;
  1352. firstpass(result);
  1353. exit;
  1354. end;
  1355. location.loc:=LOC_REGISTER;
  1356. if registers32<1 then
  1357. registers32:=1;
  1358. end;
  1359. function ttypeconvnode.first_int_to_bool : tnode;
  1360. begin
  1361. first_int_to_bool:=nil;
  1362. { byte(boolean) or word(wordbool) or longint(longbool) must
  1363. be accepted for var parameters }
  1364. if (nf_explizit in flags) and
  1365. (left.resulttype.def.size=resulttype.def.size) and
  1366. (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  1367. exit;
  1368. location.loc:=LOC_REGISTER;
  1369. { need if bool to bool !!
  1370. not very nice !!
  1371. insertypeconv(left,s32bittype);
  1372. left.explizit:=true;
  1373. firstpass(left); }
  1374. if registers32<1 then
  1375. registers32:=1;
  1376. end;
  1377. function ttypeconvnode.first_bool_to_bool : tnode;
  1378. begin
  1379. first_bool_to_bool:=nil;
  1380. location.loc:=LOC_REGISTER;
  1381. if registers32<1 then
  1382. registers32:=1;
  1383. end;
  1384. function ttypeconvnode.first_char_to_char : tnode;
  1385. begin
  1386. first_char_to_char:=nil;
  1387. location.loc:=LOC_REGISTER;
  1388. if registers32<1 then
  1389. registers32:=1;
  1390. end;
  1391. function ttypeconvnode.first_proc_to_procvar : tnode;
  1392. begin
  1393. first_proc_to_procvar:=nil;
  1394. if (left.location.loc<>LOC_REFERENCE) then
  1395. CGMessage(cg_e_illegal_expression);
  1396. registers32:=left.registers32;
  1397. if registers32<1 then
  1398. registers32:=1;
  1399. location.loc:=LOC_REGISTER;
  1400. end;
  1401. function ttypeconvnode.first_load_smallset : tnode;
  1402. var
  1403. srsym: ttypesym;
  1404. p: tcallparanode;
  1405. begin
  1406. if not searchsystype('FPC_SMALL_SET',srsym) then
  1407. internalerror(200108313);
  1408. p := ccallparanode.create(left,nil);
  1409. { reused }
  1410. left := nil;
  1411. { convert parameter explicitely to fpc_small_set }
  1412. p.left := ctypeconvnode.create(p.left,srsym.restype);
  1413. p.left.toggleflag(nf_explizit);
  1414. { create call, adjust resulttype }
  1415. result :=
  1416. ccallnode.createinternres('fpc_set_load_small',p,resulttype);
  1417. firstpass(result);
  1418. end;
  1419. function ttypeconvnode.first_ansistring_to_pchar : tnode;
  1420. begin
  1421. first_ansistring_to_pchar:=nil;
  1422. location.loc:=LOC_REGISTER;
  1423. if registers32<1 then
  1424. registers32:=1;
  1425. end;
  1426. function ttypeconvnode.first_arrayconstructor_to_set : tnode;
  1427. begin
  1428. first_arrayconstructor_to_set:=nil;
  1429. internalerror(200104022);
  1430. end;
  1431. function ttypeconvnode.first_class_to_intf : tnode;
  1432. begin
  1433. first_class_to_intf:=nil;
  1434. location.loc:=LOC_REFERENCE;
  1435. if registers32<1 then
  1436. registers32:=1;
  1437. end;
  1438. function ttypeconvnode._first_int_to_int : tnode;
  1439. begin
  1440. result:=first_int_to_int;
  1441. end;
  1442. function ttypeconvnode._first_cstring_to_pchar : tnode;
  1443. begin
  1444. result:=first_cstring_to_pchar;
  1445. end;
  1446. function ttypeconvnode._first_string_to_chararray : tnode;
  1447. begin
  1448. result:=first_string_to_chararray;
  1449. end;
  1450. function ttypeconvnode._first_char_to_string : tnode;
  1451. begin
  1452. result:=first_char_to_string;
  1453. end;
  1454. function ttypeconvnode._first_nothing : tnode;
  1455. begin
  1456. result:=first_nothing;
  1457. end;
  1458. function ttypeconvnode._first_array_to_pointer : tnode;
  1459. begin
  1460. result:=first_array_to_pointer;
  1461. end;
  1462. function ttypeconvnode._first_int_to_real : tnode;
  1463. begin
  1464. result:=first_int_to_real;
  1465. end;
  1466. function ttypeconvnode._first_real_to_real : tnode;
  1467. begin
  1468. result:=first_real_to_real;
  1469. end;
  1470. function ttypeconvnode._first_pointer_to_array : tnode;
  1471. begin
  1472. result:=first_pointer_to_array;
  1473. end;
  1474. function ttypeconvnode._first_cchar_to_pchar : tnode;
  1475. begin
  1476. result:=first_cchar_to_pchar;
  1477. end;
  1478. function ttypeconvnode._first_bool_to_int : tnode;
  1479. begin
  1480. result:=first_bool_to_int;
  1481. end;
  1482. function ttypeconvnode._first_int_to_bool : tnode;
  1483. begin
  1484. result:=first_int_to_bool;
  1485. end;
  1486. function ttypeconvnode._first_bool_to_bool : tnode;
  1487. begin
  1488. result:=first_bool_to_bool;
  1489. end;
  1490. function ttypeconvnode._first_proc_to_procvar : tnode;
  1491. begin
  1492. result:=first_proc_to_procvar;
  1493. end;
  1494. function ttypeconvnode._first_load_smallset : tnode;
  1495. begin
  1496. result:=first_load_smallset;
  1497. end;
  1498. function ttypeconvnode._first_cord_to_pointer : tnode;
  1499. begin
  1500. result:=first_cord_to_pointer;
  1501. end;
  1502. function ttypeconvnode._first_ansistring_to_pchar : tnode;
  1503. begin
  1504. result:=first_ansistring_to_pchar;
  1505. end;
  1506. function ttypeconvnode._first_arrayconstructor_to_set : tnode;
  1507. begin
  1508. result:=first_arrayconstructor_to_set;
  1509. end;
  1510. function ttypeconvnode._first_class_to_intf : tnode;
  1511. begin
  1512. result:=first_class_to_intf;
  1513. end;
  1514. function ttypeconvnode._first_char_to_char : tnode;
  1515. begin
  1516. result:=first_char_to_char;
  1517. end;
  1518. function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
  1519. const
  1520. firstconvert : array[tconverttype] of pointer = (
  1521. @ttypeconvnode._first_nothing, {equal}
  1522. @ttypeconvnode._first_nothing, {not_possible}
  1523. nil, { removed in resulttype_string_to_string }
  1524. @ttypeconvnode._first_char_to_string,
  1525. @ttypeconvnode._first_nothing, { char_2_chararray, needs nothing extra }
  1526. nil, { removed in resulttype_chararray_to_string }
  1527. @ttypeconvnode._first_cchar_to_pchar,
  1528. @ttypeconvnode._first_cstring_to_pchar,
  1529. @ttypeconvnode._first_ansistring_to_pchar,
  1530. @ttypeconvnode._first_string_to_chararray,
  1531. nil, { removed in resulttype_chararray_to_string }
  1532. @ttypeconvnode._first_array_to_pointer,
  1533. @ttypeconvnode._first_pointer_to_array,
  1534. @ttypeconvnode._first_int_to_int,
  1535. @ttypeconvnode._first_int_to_bool,
  1536. @ttypeconvnode._first_bool_to_bool,
  1537. @ttypeconvnode._first_bool_to_int,
  1538. @ttypeconvnode._first_real_to_real,
  1539. @ttypeconvnode._first_int_to_real,
  1540. @ttypeconvnode._first_proc_to_procvar,
  1541. @ttypeconvnode._first_arrayconstructor_to_set,
  1542. @ttypeconvnode._first_load_smallset,
  1543. @ttypeconvnode._first_cord_to_pointer,
  1544. @ttypeconvnode._first_nothing,
  1545. @ttypeconvnode._first_nothing,
  1546. @ttypeconvnode._first_class_to_intf,
  1547. @ttypeconvnode._first_char_to_char,
  1548. @ttypeconvnode._first_nothing,
  1549. @ttypeconvnode._first_nothing,
  1550. nil
  1551. );
  1552. type
  1553. tprocedureofobject = function : tnode of object;
  1554. var
  1555. r : packed record
  1556. proc : pointer;
  1557. obj : pointer;
  1558. end;
  1559. begin
  1560. { this is a little bit dirty but it works }
  1561. { and should be quite portable too }
  1562. r.proc:=firstconvert[c];
  1563. r.obj:=self;
  1564. first_call_helper:=tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
  1565. end;
  1566. function ttypeconvnode.pass_1 : tnode;
  1567. begin
  1568. result:=nil;
  1569. firstpass(left);
  1570. if codegenerror then
  1571. exit;
  1572. { load the value_str from the left part }
  1573. registers32:=left.registers32;
  1574. registersfpu:=left.registersfpu;
  1575. {$ifdef SUPPORT_MMX}
  1576. registersmmx:=left.registersmmx;
  1577. {$endif}
  1578. location.loc:=left.location.loc;
  1579. if nf_explizit in flags then
  1580. begin
  1581. { check if the result could be in a register }
  1582. if not(tstoreddef(resulttype.def).is_intregable) and
  1583. not(tstoreddef(resulttype.def).is_fpuregable) then
  1584. make_not_regable(left);
  1585. end;
  1586. result:=first_call_helper(convtype);
  1587. end;
  1588. function ttypeconvnode.docompare(p: tnode) : boolean;
  1589. begin
  1590. docompare :=
  1591. inherited docompare(p) and
  1592. (convtype = ttypeconvnode(p).convtype);
  1593. end;
  1594. {*****************************************************************************
  1595. TISNODE
  1596. *****************************************************************************}
  1597. constructor tisnode.create(l,r : tnode);
  1598. begin
  1599. inherited create(isn,l,r);
  1600. end;
  1601. function tisnode.det_resulttype:tnode;
  1602. var
  1603. paras: tcallparanode;
  1604. begin
  1605. result:=nil;
  1606. resulttypepass(left);
  1607. resulttypepass(right);
  1608. set_varstate(left,true);
  1609. set_varstate(right,true);
  1610. if codegenerror then
  1611. exit;
  1612. if (right.resulttype.def.deftype=classrefdef) then
  1613. begin
  1614. { left must be a class }
  1615. if is_class(left.resulttype.def) then
  1616. begin
  1617. { the operands must be related }
  1618. if (not(tobjectdef(left.resulttype.def).is_related(
  1619. tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
  1620. (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
  1621. tobjectdef(left.resulttype.def)))) then
  1622. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,
  1623. tclassrefdef(right.resulttype.def).pointertype.def.typename);
  1624. end
  1625. else
  1626. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1627. { call fpc_do_is helper }
  1628. paras := ccallparanode.create(
  1629. left,
  1630. ccallparanode.create(
  1631. right,nil));
  1632. result := ccallnode.createintern('fpc_do_is',paras);
  1633. left := nil;
  1634. right := nil;
  1635. end
  1636. else if is_interface(right.resulttype.def) then
  1637. begin
  1638. { left is a class }
  1639. if is_class(left.resulttype.def) then
  1640. begin
  1641. { the operands must be related }
  1642. if not(assigned(tobjectdef(left.resulttype.def).implementedinterfaces) and
  1643. (tobjectdef(left.resulttype.def).implementedinterfaces.searchintf(right.resulttype.def)<>-1)) then
  1644. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  1645. end
  1646. { left is an interface }
  1647. else if is_interface(left.resulttype.def) then
  1648. begin
  1649. { the operands must be related }
  1650. if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(right.resulttype.def)))) and
  1651. (not(tobjectdef(right.resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
  1652. CGMessage(type_e_mismatch);
  1653. end
  1654. else
  1655. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1656. { call fpc_do_is helper }
  1657. paras := ccallparanode.create(
  1658. left,
  1659. ccallparanode.create(
  1660. right,nil));
  1661. result := ccallnode.createintern('fpc_do_is',paras);
  1662. left := nil;
  1663. right := nil;
  1664. end
  1665. else
  1666. CGMessage1(type_e_class_or_interface_type_expected,right.resulttype.def.typename);
  1667. resulttype:=booltype;
  1668. end;
  1669. function tisnode.pass_1 : tnode;
  1670. begin
  1671. internalerror(200204254);
  1672. result:=nil;
  1673. end;
  1674. { dummy pass_2, it will never be called, but we need one since }
  1675. { you can't instantiate an abstract class }
  1676. procedure tisnode.pass_2;
  1677. begin
  1678. end;
  1679. {*****************************************************************************
  1680. TASNODE
  1681. *****************************************************************************}
  1682. constructor tasnode.create(l,r : tnode);
  1683. begin
  1684. inherited create(asn,l,r);
  1685. call := nil;
  1686. end;
  1687. destructor tasnode.destroy;
  1688. begin
  1689. call.free;
  1690. inherited destroy;
  1691. end;
  1692. function tasnode.det_resulttype:tnode;
  1693. var
  1694. hp : tnode;
  1695. b : boolean;
  1696. o : tobjectdef;
  1697. begin
  1698. result:=nil;
  1699. resulttypepass(right);
  1700. resulttypepass(left);
  1701. set_varstate(right,true);
  1702. set_varstate(left,true);
  1703. if codegenerror then
  1704. exit;
  1705. if (right.resulttype.def.deftype=classrefdef) then
  1706. begin
  1707. { left must be a class }
  1708. if is_class(left.resulttype.def) then
  1709. begin
  1710. { the operands must be related }
  1711. if (not(tobjectdef(left.resulttype.def).is_related(
  1712. tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
  1713. (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
  1714. tobjectdef(left.resulttype.def)))) then
  1715. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,
  1716. tclassrefdef(right.resulttype.def).pointertype.def.typename);
  1717. end
  1718. else
  1719. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1720. resulttype:=tclassrefdef(right.resulttype.def).pointertype;
  1721. end
  1722. else if is_interface(right.resulttype.def) then
  1723. begin
  1724. { left is a class }
  1725. if is_class(left.resulttype.def) then
  1726. begin
  1727. { the operands must be related
  1728. no, because the class instance could be a child class of the current one which
  1729. implements additional interfaces (FK)
  1730. b:=false;
  1731. o:=tobjectdef(left.resulttype.def);
  1732. while assigned(o) do
  1733. begin
  1734. if assigned(o.implementedinterfaces) and
  1735. (o.implementedinterfaces.searchintf(right.resulttype.def)<>-1) then
  1736. begin
  1737. b:=true;
  1738. break;
  1739. end;
  1740. o:=o.childof;
  1741. end;
  1742. if not(b) then
  1743. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  1744. }
  1745. end
  1746. { left is an interface }
  1747. else if is_interface(left.resulttype.def) then
  1748. begin
  1749. { the operands must be related
  1750. we don't necessarily know how the both interfaces are implemented, so we can't do this check (FK)
  1751. if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(right.resulttype.def)))) and
  1752. (not(tobjectdef(right.resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
  1753. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  1754. }
  1755. end
  1756. else
  1757. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1758. resulttype:=right.resulttype;
  1759. { load the GUID of the interface }
  1760. if (right.nodetype=typen) then
  1761. begin
  1762. if tobjectdef(right.resulttype.def).isiidguidvalid then
  1763. begin
  1764. hp:=cguidconstnode.create(tobjectdef(right.resulttype.def).iidguid);
  1765. right.free;
  1766. right:=hp;
  1767. end
  1768. else
  1769. internalerror(200206282);
  1770. resulttypepass(right);
  1771. end;
  1772. end
  1773. else
  1774. CGMessage1(type_e_class_or_interface_type_expected,right.resulttype.def.typename);
  1775. end;
  1776. function tasnode.getcopy: tnode;
  1777. begin
  1778. result := inherited getcopy;
  1779. if assigned(call) then
  1780. tasnode(result).call := call.getcopy
  1781. else
  1782. tasnode(result).call := nil;
  1783. end;
  1784. function tasnode.pass_1 : tnode;
  1785. var
  1786. procname: string;
  1787. begin
  1788. result:=nil;
  1789. if not assigned(call) then
  1790. begin
  1791. if is_class(left.resulttype.def) and
  1792. (right.resulttype.def.deftype=classrefdef) then
  1793. call := ccallnode.createinternres('fpc_do_as',
  1794. ccallparanode.create(left,ccallparanode.create(right,nil)),
  1795. resulttype)
  1796. else
  1797. begin
  1798. if is_class(left.resulttype.def) then
  1799. procname := 'fpc_class_as_intf'
  1800. else
  1801. procname := 'fpc_intf_as';
  1802. call := ccallnode.createinternres(procname,
  1803. ccallparanode.create(right,ccallparanode.create(left,nil)),
  1804. resulttype);
  1805. end;
  1806. left := nil;
  1807. right := nil;
  1808. firstpass(call);
  1809. if codegenerror then
  1810. exit;
  1811. location.loc:=call.location.loc;
  1812. registers32:=call.registers32;
  1813. registersfpu:=call.registersfpu;
  1814. {$ifdef SUPPORT_MMX}
  1815. registersmmx:=call.registersmmx;
  1816. {$endif SUPPORT_MMX}
  1817. end;
  1818. end;
  1819. begin
  1820. ctypeconvnode:=ttypeconvnode;
  1821. casnode:=tasnode;
  1822. cisnode:=tisnode;
  1823. end.
  1824. {
  1825. $Log$
  1826. Revision 1.87 2002-10-10 16:07:57 florian
  1827. + several widestring/pwidechar related stuff added
  1828. Revision 1.86 2002/10/06 16:10:23 florian
  1829. * when compiling <interface> as <interface> we can't assume
  1830. anything about relation
  1831. Revision 1.85 2002/10/05 12:43:25 carl
  1832. * fixes for Delphi 6 compilation
  1833. (warning : Some features do not work under Delphi)
  1834. Revision 1.84 2002/10/02 20:23:50 florian
  1835. - removed the relation check for <class> as <interface> because we don't
  1836. know the runtime type of <class>! It could be a child class of the given type
  1837. which implements additional interfaces
  1838. Revision 1.83 2002/10/02 20:17:14 florian
  1839. + the as operator for <class> as <interface> has to check the parent classes as well
  1840. Revision 1.82 2002/09/30 07:00:47 florian
  1841. * fixes to common code to get the alpha compiler compiled applied
  1842. Revision 1.81 2002/09/16 14:11:13 peter
  1843. * add argument to equal_paras() to support default values or not
  1844. Revision 1.80 2002/09/07 20:40:23 carl
  1845. * cardinal -> longword
  1846. Revision 1.79 2002/09/07 15:25:03 peter
  1847. * old logs removed and tabs fixed
  1848. Revision 1.78 2002/09/07 12:16:04 carl
  1849. * second part bug report 1996 fix, testrange in cordconstnode
  1850. only called if option is set (also make parsing a tiny faster)
  1851. Revision 1.77 2002/09/05 05:56:07 jonas
  1852. - reverted my last commit, it was completely bogus :(
  1853. Revision 1.75 2002/09/02 19:24:42 peter
  1854. * array of char support for Str()
  1855. Revision 1.74 2002/09/01 08:01:16 daniel
  1856. * Removed sets from Tcallnode.det_resulttype
  1857. + Added read/write notifications of variables. These will be usefull
  1858. for providing information for several optimizations. For example
  1859. the value of the loop variable of a for loop does matter is the
  1860. variable is read after the for loop, but if it's no longer used
  1861. or written, it doesn't matter and this can be used to optimize
  1862. the loop code generation.
  1863. Revision 1.73 2002/08/23 16:14:49 peter
  1864. * tempgen cleanup
  1865. * tt_noreuse temp type added that will be used in genentrycode
  1866. Revision 1.72 2002/08/20 18:23:33 jonas
  1867. * the as node again uses a compilerproc
  1868. + (untested) support for interface "as" statements
  1869. Revision 1.71 2002/08/19 19:36:43 peter
  1870. * More fixes for cross unit inlining, all tnodes are now implemented
  1871. * Moved pocall_internconst to po_internconst because it is not a
  1872. calling type at all and it conflicted when inlining of these small
  1873. functions was requested
  1874. Revision 1.70 2002/08/17 09:23:36 florian
  1875. * first part of procinfo rewrite
  1876. Revision 1.69 2002/08/14 19:26:55 carl
  1877. + generic int_to_real type conversion
  1878. + generic unaryminus node
  1879. Revision 1.68 2002/08/11 16:08:55 florian
  1880. + support of explicit type case boolean->char
  1881. Revision 1.67 2002/08/11 15:28:00 florian
  1882. + support of explicit type case <any ordinal type>->pointer
  1883. (delphi mode only)
  1884. Revision 1.66 2002/08/09 07:33:01 florian
  1885. * a couple of interface related fixes
  1886. Revision 1.65 2002/07/29 21:23:42 florian
  1887. * more fixes for the ppc
  1888. + wrappers for the tcnvnode.first_* stuff introduced
  1889. Revision 1.64 2002/07/23 12:34:30 daniel
  1890. * Readded old set code. To use it define 'oldset'. Activated by default
  1891. for ppc.
  1892. Revision 1.63 2002/07/23 09:51:22 daniel
  1893. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  1894. are worth comitting.
  1895. Revision 1.62 2002/07/22 11:48:04 daniel
  1896. * Sets are now internally sets.
  1897. Revision 1.61 2002/07/20 17:16:02 florian
  1898. + source code page support
  1899. Revision 1.60 2002/07/20 11:57:54 florian
  1900. * types.pas renamed to defbase.pas because D6 contains a types
  1901. unit so this would conflicts if D6 programms are compiled
  1902. + Willamette/SSE2 instructions to assembler added
  1903. Revision 1.59 2002/07/01 16:23:53 peter
  1904. * cg64 patch
  1905. * basics for currency
  1906. * asnode updates for class and interface (not finished)
  1907. Revision 1.58 2002/05/18 13:34:09 peter
  1908. * readded missing revisions
  1909. }