ncnv.pas 74 KB

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