ncnv.pas 72 KB

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