ncnv.pas 71 KB

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