ncnv.pas 95 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756
  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,
  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 buildderefimpl;override;
  39. procedure derefimpl;override;
  40. function getcopy : tnode;override;
  41. function pass_1 : tnode;override;
  42. function det_resulttype:tnode;override;
  43. procedure mark_write;override;
  44. function docompare(p: tnode) : boolean; override;
  45. procedure second_call_helper(c : tconverttype);
  46. private
  47. function resulttype_int_to_int : tnode;
  48. function resulttype_cord_to_pointer : tnode;
  49. function resulttype_chararray_to_string : tnode;
  50. function resulttype_string_to_chararray : tnode;
  51. function resulttype_string_to_string : tnode;
  52. function resulttype_char_to_string : tnode;
  53. function resulttype_char_to_chararray : tnode;
  54. function resulttype_int_to_real : tnode;
  55. function resulttype_real_to_real : tnode;
  56. function resulttype_real_to_currency : tnode;
  57. function resulttype_cchar_to_pchar : tnode;
  58. function resulttype_cstring_to_pchar : tnode;
  59. function resulttype_char_to_char : tnode;
  60. function resulttype_arrayconstructor_to_set : tnode;
  61. function resulttype_pchar_to_string : tnode;
  62. function resulttype_interface_to_guid : tnode;
  63. function resulttype_dynarray_to_openarray : tnode;
  64. function resulttype_pwchar_to_string : tnode;
  65. function resulttype_variant_to_dynarray : tnode;
  66. function resulttype_dynarray_to_variant : tnode;
  67. function resulttype_call_helper(c : tconverttype) : tnode;
  68. function resulttype_variant_to_enum : tnode;
  69. function resulttype_enum_to_variant : tnode;
  70. protected
  71. function first_int_to_int : tnode;virtual;
  72. function first_cstring_to_pchar : tnode;virtual;
  73. function first_string_to_chararray : tnode;virtual;
  74. function first_char_to_string : tnode;virtual;
  75. function first_nothing : tnode;virtual;
  76. function first_array_to_pointer : tnode;virtual;
  77. function first_int_to_real : tnode;virtual;
  78. function first_real_to_real : tnode;virtual;
  79. function first_pointer_to_array : tnode;virtual;
  80. function first_cchar_to_pchar : tnode;virtual;
  81. function first_bool_to_int : tnode;virtual;
  82. function first_int_to_bool : tnode;virtual;
  83. function first_bool_to_bool : tnode;virtual;
  84. function first_proc_to_procvar : tnode;virtual;
  85. function first_load_smallset : tnode;virtual;
  86. function first_cord_to_pointer : tnode;virtual;
  87. function first_ansistring_to_pchar : tnode;virtual;
  88. function first_arrayconstructor_to_set : tnode;virtual;
  89. function first_class_to_intf : tnode;virtual;
  90. function first_char_to_char : tnode;virtual;
  91. function first_call_helper(c : tconverttype) : tnode;
  92. { these wrapper are necessary, because the first_* stuff is called }
  93. { through a table. Without the wrappers override wouldn't have }
  94. { any effect }
  95. function _first_int_to_int : tnode;
  96. function _first_cstring_to_pchar : tnode;
  97. function _first_string_to_chararray : tnode;
  98. function _first_char_to_string : tnode;
  99. function _first_nothing : tnode;
  100. function _first_array_to_pointer : tnode;
  101. function _first_int_to_real : tnode;
  102. function _first_real_to_real: tnode;
  103. function _first_pointer_to_array : tnode;
  104. function _first_cchar_to_pchar : tnode;
  105. function _first_bool_to_int : tnode;
  106. function _first_int_to_bool : tnode;
  107. function _first_bool_to_bool : tnode;
  108. function _first_proc_to_procvar : tnode;
  109. function _first_load_smallset : tnode;
  110. function _first_cord_to_pointer : tnode;
  111. function _first_ansistring_to_pchar : tnode;
  112. function _first_arrayconstructor_to_set : tnode;
  113. function _first_class_to_intf : tnode;
  114. function _first_char_to_char : tnode;
  115. procedure _second_int_to_int;virtual;
  116. procedure _second_string_to_string;virtual;
  117. procedure _second_cstring_to_pchar;virtual;
  118. procedure _second_string_to_chararray;virtual;
  119. procedure _second_array_to_pointer;virtual;
  120. procedure _second_pointer_to_array;virtual;
  121. procedure _second_chararray_to_string;virtual;
  122. procedure _second_char_to_string;virtual;
  123. procedure _second_int_to_real;virtual;
  124. procedure _second_real_to_real;virtual;
  125. procedure _second_cord_to_pointer;virtual;
  126. procedure _second_proc_to_procvar;virtual;
  127. procedure _second_bool_to_int;virtual;
  128. procedure _second_int_to_bool;virtual;
  129. procedure _second_bool_to_bool;virtual;
  130. procedure _second_load_smallset;virtual;
  131. procedure _second_ansistring_to_pchar;virtual;
  132. procedure _second_class_to_intf;virtual;
  133. procedure _second_char_to_char;virtual;
  134. procedure _second_nothing; virtual;
  135. procedure second_int_to_int;virtual;abstract;
  136. procedure second_string_to_string;virtual;abstract;
  137. procedure second_cstring_to_pchar;virtual;abstract;
  138. procedure second_string_to_chararray;virtual;abstract;
  139. procedure second_array_to_pointer;virtual;abstract;
  140. procedure second_pointer_to_array;virtual;abstract;
  141. procedure second_chararray_to_string;virtual;abstract;
  142. procedure second_char_to_string;virtual;abstract;
  143. procedure second_int_to_real;virtual;abstract;
  144. procedure second_real_to_real;virtual;abstract;
  145. procedure second_cord_to_pointer;virtual;abstract;
  146. procedure second_proc_to_procvar;virtual;abstract;
  147. procedure second_bool_to_int;virtual;abstract;
  148. procedure second_int_to_bool;virtual;abstract;
  149. procedure second_bool_to_bool;virtual;abstract;
  150. procedure second_load_smallset;virtual;abstract;
  151. procedure second_ansistring_to_pchar;virtual;abstract;
  152. procedure second_class_to_intf;virtual;abstract;
  153. procedure second_char_to_char;virtual;abstract;
  154. procedure second_nothing; virtual;abstract;
  155. end;
  156. ttypeconvnodeclass = class of ttypeconvnode;
  157. tasnode = class(tbinarynode)
  158. constructor create(l,r : tnode);virtual;
  159. function pass_1 : tnode;override;
  160. function det_resulttype:tnode;override;
  161. function getcopy: tnode;override;
  162. destructor destroy; override;
  163. protected
  164. call: tnode;
  165. end;
  166. tasnodeclass = class of tasnode;
  167. tisnode = class(tbinarynode)
  168. constructor create(l,r : tnode);virtual;
  169. function pass_1 : tnode;override;
  170. function det_resulttype:tnode;override;
  171. procedure pass_2;override;
  172. end;
  173. tisnodeclass = class of tisnode;
  174. var
  175. ctypeconvnode : ttypeconvnodeclass;
  176. casnode : tasnodeclass;
  177. cisnode : tisnodeclass;
  178. procedure inserttypeconv(var p:tnode;const t:ttype);
  179. procedure inserttypeconv_explicit(var p:tnode;const t:ttype);
  180. procedure arrayconstructor_to_set(var p : tnode);
  181. implementation
  182. uses
  183. globtype,systems,
  184. cutils,verbose,globals,widestr,
  185. symconst,symdef,symsym,symtable,
  186. ncon,ncal,nset,nadd,ninl,nmem,nmat,nutils,
  187. cgbase,procinfo,
  188. htypechk,pass_1,cpuinfo;
  189. {*****************************************************************************
  190. Helpers
  191. *****************************************************************************}
  192. procedure inserttypeconv(var p:tnode;const t:ttype);
  193. begin
  194. if not assigned(p.resulttype.def) then
  195. begin
  196. resulttypepass(p);
  197. if codegenerror then
  198. exit;
  199. end;
  200. { don't insert obsolete type conversions }
  201. if equal_defs(p.resulttype.def,t.def) and
  202. not ((p.resulttype.def.deftype=setdef) and
  203. (tsetdef(p.resulttype.def).settype <>
  204. tsetdef(t.def).settype)) then
  205. begin
  206. p.resulttype:=t;
  207. end
  208. else
  209. begin
  210. p:=ctypeconvnode.create(p,t);
  211. resulttypepass(p);
  212. end;
  213. end;
  214. procedure inserttypeconv_explicit(var p:tnode;const t:ttype);
  215. begin
  216. if not assigned(p.resulttype.def) then
  217. begin
  218. resulttypepass(p);
  219. if codegenerror then
  220. exit;
  221. end;
  222. { don't insert obsolete type conversions }
  223. if equal_defs(p.resulttype.def,t.def) and
  224. not ((p.resulttype.def.deftype=setdef) and
  225. (tsetdef(p.resulttype.def).settype <>
  226. tsetdef(t.def).settype)) then
  227. begin
  228. p.resulttype:=t;
  229. end
  230. else
  231. begin
  232. p:=ctypeconvnode.create_explicit(p,t);
  233. resulttypepass(p);
  234. end;
  235. end;
  236. {*****************************************************************************
  237. Array constructor to Set Conversion
  238. *****************************************************************************}
  239. procedure arrayconstructor_to_set(var p : tnode);
  240. var
  241. constp : tsetconstnode;
  242. buildp,
  243. p2,p3,p4 : tnode;
  244. htype : ttype;
  245. constset : Pconstset;
  246. constsetlo,
  247. constsethi : TConstExprInt;
  248. procedure update_constsethi(t:ttype);
  249. begin
  250. if ((t.def.deftype=orddef) and
  251. (torddef(t.def).high>=constsethi)) then
  252. begin
  253. if torddef(t.def).typ=uwidechar then
  254. begin
  255. constsethi:=255;
  256. if htype.def=nil then
  257. htype:=t;
  258. end
  259. else
  260. begin
  261. constsethi:=torddef(t.def).high;
  262. if htype.def=nil then
  263. begin
  264. if (constsethi>255) or
  265. (torddef(t.def).low<0) then
  266. htype:=u8inttype
  267. else
  268. htype:=t;
  269. end;
  270. if constsethi>255 then
  271. constsethi:=255;
  272. end;
  273. end
  274. else if ((t.def.deftype=enumdef) and
  275. (tenumdef(t.def).max>=constsethi)) then
  276. begin
  277. if htype.def=nil then
  278. htype:=t;
  279. constsethi:=tenumdef(t.def).max;
  280. end;
  281. end;
  282. procedure do_set(pos : longint);
  283. begin
  284. if (pos and not $ff)<>0 then
  285. Message(parser_e_illegal_set_expr);
  286. if pos>constsethi then
  287. constsethi:=pos;
  288. if pos<constsetlo then
  289. constsetlo:=pos;
  290. if pos in constset^ then
  291. Message(parser_e_illegal_set_expr);
  292. include(constset^,pos);
  293. end;
  294. var
  295. l : Longint;
  296. lr,hr : TConstExprInt;
  297. hp : tarrayconstructornode;
  298. begin
  299. if p.nodetype<>arrayconstructorn then
  300. internalerror(200205105);
  301. new(constset);
  302. constset^:=[];
  303. htype.reset;
  304. constsetlo:=0;
  305. constsethi:=0;
  306. constp:=csetconstnode.create(nil,htype);
  307. constp.value_set:=constset;
  308. buildp:=constp;
  309. hp:=tarrayconstructornode(p);
  310. if assigned(hp.left) then
  311. begin
  312. while assigned(hp) do
  313. begin
  314. p4:=nil; { will contain the tree to create the set }
  315. {split a range into p2 and p3 }
  316. if hp.left.nodetype=arrayconstructorrangen then
  317. begin
  318. p2:=tarrayconstructorrangenode(hp.left).left;
  319. p3:=tarrayconstructorrangenode(hp.left).right;
  320. tarrayconstructorrangenode(hp.left).left:=nil;
  321. tarrayconstructorrangenode(hp.left).right:=nil;
  322. end
  323. else
  324. begin
  325. p2:=hp.left;
  326. hp.left:=nil;
  327. p3:=nil;
  328. end;
  329. resulttypepass(p2);
  330. if assigned(p3) then
  331. resulttypepass(p3);
  332. if codegenerror then
  333. break;
  334. case p2.resulttype.def.deftype of
  335. enumdef,
  336. orddef:
  337. begin
  338. getrange(p2.resulttype.def,lr,hr);
  339. if assigned(p3) then
  340. begin
  341. { this isn't good, you'll get problems with
  342. type t010 = 0..10;
  343. ts = set of t010;
  344. var s : ts;b : t010
  345. begin s:=[1,2,b]; end.
  346. if is_integer(p3^.resulttype.def) then
  347. begin
  348. inserttypeconv(p3,u8bitdef);
  349. end;
  350. }
  351. if assigned(htype.def) and not(equal_defs(htype.def,p3.resulttype.def)) then
  352. begin
  353. aktfilepos:=p3.fileinfo;
  354. CGMessage(type_e_typeconflict_in_set);
  355. end
  356. else
  357. begin
  358. if (p2.nodetype=ordconstn) and (p3.nodetype=ordconstn) then
  359. begin
  360. if not(is_integer(p3.resulttype.def)) then
  361. htype:=p3.resulttype
  362. else
  363. begin
  364. inserttypeconv(p3,u8inttype);
  365. inserttypeconv(p2,u8inttype);
  366. end;
  367. for l:=tordconstnode(p2).value to tordconstnode(p3).value do
  368. do_set(l);
  369. p2.free;
  370. p3.free;
  371. end
  372. else
  373. begin
  374. update_constsethi(p2.resulttype);
  375. inserttypeconv(p2,htype);
  376. update_constsethi(p3.resulttype);
  377. inserttypeconv(p3,htype);
  378. if assigned(htype.def) then
  379. inserttypeconv(p3,htype)
  380. else
  381. inserttypeconv(p3,u8inttype);
  382. p4:=csetelementnode.create(p2,p3);
  383. end;
  384. end;
  385. end
  386. else
  387. begin
  388. { Single value }
  389. if p2.nodetype=ordconstn then
  390. begin
  391. if not(is_integer(p2.resulttype.def)) then
  392. update_constsethi(p2.resulttype)
  393. else
  394. inserttypeconv(p2,u8inttype);
  395. do_set(tordconstnode(p2).value);
  396. p2.free;
  397. end
  398. else
  399. begin
  400. update_constsethi(p2.resulttype);
  401. if assigned(htype.def) then
  402. inserttypeconv(p2,htype)
  403. else
  404. inserttypeconv(p2,u8inttype);
  405. p4:=csetelementnode.create(p2,nil);
  406. end;
  407. end;
  408. end;
  409. stringdef :
  410. begin
  411. { if we've already set elements which are constants }
  412. { throw an error }
  413. if ((htype.def=nil) and assigned(buildp)) or
  414. not(is_char(htype.def)) then
  415. CGMessage(type_e_typeconflict_in_set)
  416. else
  417. for l:=1 to length(pstring(tstringconstnode(p2).value_str)^) do
  418. do_set(ord(pstring(tstringconstnode(p2).value_str)^[l]));
  419. if htype.def=nil then
  420. htype:=cchartype;
  421. p2.free;
  422. end;
  423. else
  424. CGMessage(type_e_ordinal_expr_expected);
  425. end;
  426. { insert the set creation tree }
  427. if assigned(p4) then
  428. buildp:=caddnode.create(addn,buildp,p4);
  429. { load next and dispose current node }
  430. p2:=hp;
  431. hp:=tarrayconstructornode(tarrayconstructornode(p2).right);
  432. tarrayconstructornode(p2).right:=nil;
  433. p2.free;
  434. end;
  435. if (htype.def=nil) then
  436. htype:=u8inttype;
  437. end
  438. else
  439. begin
  440. { empty set [], only remove node }
  441. p.free;
  442. end;
  443. { set the initial set type }
  444. constp.resulttype.setdef(tsetdef.create(htype,constsethi));
  445. { determine the resulttype for the tree }
  446. resulttypepass(buildp);
  447. { set the new tree }
  448. p:=buildp;
  449. end;
  450. {*****************************************************************************
  451. TTYPECONVNODE
  452. *****************************************************************************}
  453. constructor ttypeconvnode.create(node : tnode;const t:ttype);
  454. begin
  455. inherited create(typeconvn,node);
  456. convtype:=tc_not_possible;
  457. totype:=t;
  458. if t.def=nil then
  459. internalerror(200103281);
  460. set_file_line(node);
  461. end;
  462. constructor ttypeconvnode.create_explicit(node : tnode;const t:ttype);
  463. begin
  464. self.create(node,t);
  465. include(flags,nf_explicit);
  466. end;
  467. constructor ttypeconvnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  468. begin
  469. inherited ppuload(t,ppufile);
  470. ppufile.gettype(totype);
  471. convtype:=tconverttype(ppufile.getbyte);
  472. end;
  473. procedure ttypeconvnode.ppuwrite(ppufile:tcompilerppufile);
  474. begin
  475. inherited ppuwrite(ppufile);
  476. ppufile.puttype(totype);
  477. ppufile.putbyte(byte(convtype));
  478. end;
  479. procedure ttypeconvnode.buildderefimpl;
  480. begin
  481. inherited buildderefimpl;
  482. totype.buildderef;
  483. end;
  484. procedure ttypeconvnode.derefimpl;
  485. begin
  486. inherited derefimpl;
  487. totype.resolve;
  488. end;
  489. function ttypeconvnode.getcopy : tnode;
  490. var
  491. n : ttypeconvnode;
  492. begin
  493. n:=ttypeconvnode(inherited getcopy);
  494. n.convtype:=convtype;
  495. getcopy:=n;
  496. end;
  497. function ttypeconvnode.resulttype_cord_to_pointer : tnode;
  498. var
  499. t : tnode;
  500. begin
  501. result:=nil;
  502. if left.nodetype=ordconstn then
  503. begin
  504. { check if we have a valid pointer constant (JM) }
  505. if (sizeof(pointer) > sizeof(TConstPtrUInt)) then
  506. if (sizeof(TConstPtrUInt) = 4) then
  507. begin
  508. if (tordconstnode(left).value < low(longint)) or
  509. (tordconstnode(left).value > high(cardinal)) then
  510. CGMessage(parser_e_range_check_error);
  511. end
  512. else if (sizeof(TConstPtrUInt) = 8) then
  513. begin
  514. if (tordconstnode(left).value < low(int64)) or
  515. (tordconstnode(left).value > high(qword)) then
  516. CGMessage(parser_e_range_check_error);
  517. end
  518. else
  519. internalerror(2001020801);
  520. t:=cpointerconstnode.create(TConstPtrUInt(tordconstnode(left).value),resulttype);
  521. result:=t;
  522. end
  523. else
  524. internalerror(200104023);
  525. end;
  526. function ttypeconvnode.resulttype_chararray_to_string : tnode;
  527. begin
  528. result := ccallnode.createinternres(
  529. 'fpc_chararray_to_'+tstringdef(resulttype.def).stringtypname,
  530. ccallparanode.create(left,nil),resulttype);
  531. left := nil;
  532. end;
  533. function ttypeconvnode.resulttype_string_to_chararray : tnode;
  534. var
  535. arrsize: aword;
  536. begin
  537. with tarraydef(resulttype.def) do
  538. begin
  539. if highrange<lowrange then
  540. internalerror(75432653);
  541. arrsize := highrange-lowrange+1;
  542. end;
  543. if (left.nodetype = stringconstn) and
  544. { left.length+1 since there's always a terminating #0 character (JM) }
  545. (tstringconstnode(left).len+1 >= arrsize) and
  546. (tstringdef(left.resulttype.def).string_typ=st_shortstring) then
  547. begin
  548. { handled separately }
  549. result := nil;
  550. exit;
  551. end;
  552. result := ccallnode.createinternres(
  553. 'fpc_'+tstringdef(left.resulttype.def).stringtypname+
  554. '_to_chararray',ccallparanode.create(left,ccallparanode.create(
  555. cordconstnode.create(arrsize,s32inttype,true),nil)),resulttype);
  556. left := nil;
  557. end;
  558. function ttypeconvnode.resulttype_string_to_string : tnode;
  559. var
  560. procname: string[31];
  561. stringpara : tcallparanode;
  562. pw : pcompilerwidestring;
  563. pc : pchar;
  564. begin
  565. result:=nil;
  566. if left.nodetype=stringconstn then
  567. begin
  568. { convert ascii 2 unicode }
  569. {$ifdef ansistring_bits}
  570. if (tstringdef(resulttype.def).string_typ=st_widestring) and
  571. (tstringconstnode(left).st_type in [st_ansistring16,st_ansistring32,
  572. st_ansistring64,st_shortstring,st_longstring]) then
  573. {$else}
  574. if (tstringdef(resulttype.def).string_typ=st_widestring) and
  575. (tstringconstnode(left).st_type in [st_ansistring,st_shortstring,st_longstring]) then
  576. {$endif}
  577. begin
  578. initwidestring(pw);
  579. ascii2unicode(tstringconstnode(left).value_str,tstringconstnode(left).len,pw);
  580. ansistringdispose(tstringconstnode(left).value_str,tstringconstnode(left).len);
  581. pcompilerwidestring(tstringconstnode(left).value_str):=pw;
  582. end
  583. else
  584. { convert unicode 2 ascii }
  585. {$ifdef ansistring_bits}
  586. if (tstringconstnode(left).st_type=st_widestring) and
  587. (tstringdef(resulttype.def).string_typ in [st_ansistring16,st_ansistring32,
  588. st_ansistring64,st_shortstring,st_longstring]) then
  589. {$else}
  590. if (tstringconstnode(left).st_type=st_widestring) and
  591. (tstringdef(resulttype.def).string_typ in [st_ansistring,st_shortstring,st_longstring]) then
  592. {$endif}
  593. begin
  594. pw:=pcompilerwidestring(tstringconstnode(left).value_str);
  595. getmem(pc,getlengthwidestring(pw)+1);
  596. unicode2ascii(pw,pc);
  597. donewidestring(pw);
  598. tstringconstnode(left).value_str:=pc;
  599. end;
  600. tstringconstnode(left).st_type:=tstringdef(resulttype.def).string_typ;
  601. tstringconstnode(left).resulttype:=resulttype;
  602. result:=left;
  603. left:=nil;
  604. end
  605. else
  606. begin
  607. { get the correct procedure name }
  608. procname := 'fpc_'+tstringdef(left.resulttype.def).stringtypname+
  609. '_to_'+tstringdef(resulttype.def).stringtypname;
  610. { create parameter (and remove left node from typeconvnode }
  611. { since it's reused as parameter) }
  612. stringpara := ccallparanode.create(left,nil);
  613. left := nil;
  614. { when converting to shortstrings, we have to pass high(destination) too }
  615. if (tstringdef(resulttype.def).string_typ = st_shortstring) then
  616. stringpara.right := ccallparanode.create(cinlinenode.create(
  617. in_high_x,false,self.getcopy),nil);
  618. { and create the callnode }
  619. result := ccallnode.createinternres(procname,stringpara,resulttype);
  620. end;
  621. end;
  622. function ttypeconvnode.resulttype_char_to_string : tnode;
  623. var
  624. procname: string[31];
  625. para : tcallparanode;
  626. hp : tstringconstnode;
  627. ws : pcompilerwidestring;
  628. begin
  629. result:=nil;
  630. if left.nodetype=ordconstn then
  631. begin
  632. if tstringdef(resulttype.def).string_typ=st_widestring then
  633. begin
  634. initwidestring(ws);
  635. concatwidestringchar(ws,tcompilerwidechar(chr(tordconstnode(left).value)));
  636. hp:=cstringconstnode.createwstr(ws);
  637. donewidestring(ws);
  638. end
  639. else
  640. hp:=cstringconstnode.createstr(chr(tordconstnode(left).value),tstringdef(resulttype.def).string_typ);
  641. result:=hp;
  642. end
  643. else
  644. { shortstrings are handled 'inline' }
  645. if tstringdef(resulttype.def).string_typ <> st_shortstring then
  646. begin
  647. { create the parameter }
  648. para := ccallparanode.create(left,nil);
  649. left := nil;
  650. { and the procname }
  651. procname := 'fpc_char_to_' +tstringdef(resulttype.def).stringtypname;
  652. { and finally the call }
  653. result := ccallnode.createinternres(procname,para,resulttype);
  654. end
  655. else
  656. begin
  657. { create word(byte(char) shl 8 or 1) for litte endian machines }
  658. { and word(byte(char) or 256) for big endian machines }
  659. left := ctypeconvnode.create_explicit(left,u8inttype);
  660. if (target_info.endian = endian_little) then
  661. left := caddnode.create(orn,
  662. cshlshrnode.create(shln,left,cordconstnode.create(8,s32inttype,false)),
  663. cordconstnode.create(1,s32inttype,false))
  664. else
  665. left := caddnode.create(orn,left,
  666. cordconstnode.create(1 shl 8,s32inttype,false));
  667. left := ctypeconvnode.create_explicit(left,u16inttype);
  668. resulttypepass(left);
  669. end;
  670. end;
  671. function ttypeconvnode.resulttype_char_to_chararray : tnode;
  672. begin
  673. if resulttype.def.size <> 1 then
  674. begin
  675. { convert first to string, then to chararray }
  676. inserttypeconv(left,cshortstringtype);
  677. inserttypeconv(left,resulttype);
  678. result:=left;
  679. left := nil;
  680. exit;
  681. end;
  682. result := nil;
  683. end;
  684. function ttypeconvnode.resulttype_char_to_char : tnode;
  685. var
  686. hp : tordconstnode;
  687. begin
  688. result:=nil;
  689. if left.nodetype=ordconstn then
  690. begin
  691. if (torddef(resulttype.def).typ=uchar) and
  692. (torddef(left.resulttype.def).typ=uwidechar) then
  693. begin
  694. hp:=cordconstnode.create(
  695. ord(unicode2asciichar(tcompilerwidechar(tordconstnode(left).value))),
  696. cchartype,true);
  697. result:=hp;
  698. end
  699. else if (torddef(resulttype.def).typ=uwidechar) and
  700. (torddef(left.resulttype.def).typ=uchar) then
  701. begin
  702. hp:=cordconstnode.create(
  703. asciichar2unicode(chr(tordconstnode(left).value)),
  704. cwidechartype,true);
  705. result:=hp;
  706. end
  707. else
  708. internalerror(200105131);
  709. exit;
  710. end;
  711. end;
  712. function ttypeconvnode.resulttype_int_to_int : tnode;
  713. var
  714. v : TConstExprInt;
  715. begin
  716. result:=nil;
  717. if left.nodetype=ordconstn then
  718. begin
  719. v:=tordconstnode(left).value;
  720. if is_currency(resulttype.def) then
  721. v:=v*10000;
  722. if (resulttype.def.deftype=pointerdef) then
  723. result:=cpointerconstnode.create(TConstPtrUInt(v),resulttype)
  724. else
  725. begin
  726. if is_currency(left.resulttype.def) then
  727. v:=v div 10000;
  728. result:=cordconstnode.create(v,resulttype,false);
  729. end;
  730. end
  731. else if left.nodetype=pointerconstn then
  732. begin
  733. v:=tpointerconstnode(left).value;
  734. if (resulttype.def.deftype=pointerdef) then
  735. result:=cpointerconstnode.create(v,resulttype)
  736. else
  737. begin
  738. if is_currency(resulttype.def) then
  739. v:=v*10000;
  740. result:=cordconstnode.create(v,resulttype,false);
  741. end;
  742. end
  743. else
  744. begin
  745. { multiply by 10000 for currency. We need to use getcopy to pass
  746. the argument because the current node is always disposed. Only
  747. inserting the multiply in the left node is not possible because
  748. it'll get in an infinite loop to convert int->currency }
  749. if is_currency(resulttype.def) then
  750. begin
  751. result:=caddnode.create(muln,getcopy,cordconstnode.create(10000,resulttype,false));
  752. include(result.flags,nf_is_currency);
  753. end
  754. else if is_currency(left.resulttype.def) then
  755. begin
  756. result:=cmoddivnode.create(divn,getcopy,cordconstnode.create(10000,resulttype,false));
  757. include(result.flags,nf_is_currency);
  758. end;
  759. end;
  760. end;
  761. function ttypeconvnode.resulttype_int_to_real : tnode;
  762. var
  763. rv : bestreal;
  764. begin
  765. result:=nil;
  766. if left.nodetype=ordconstn then
  767. begin
  768. rv:=tordconstnode(left).value;
  769. if is_currency(resulttype.def) then
  770. rv:=rv*10000.0
  771. else if is_currency(left.resulttype.def) then
  772. rv:=rv/10000.0;
  773. result:=crealconstnode.create(rv,resulttype);
  774. end
  775. else
  776. begin
  777. { multiply by 10000 for currency. We need to use getcopy to pass
  778. the argument because the current node is always disposed. Only
  779. inserting the multiply in the left node is not possible because
  780. it'll get in an infinite loop to convert int->currency }
  781. if is_currency(resulttype.def) then
  782. begin
  783. result:=caddnode.create(muln,getcopy,crealconstnode.create(10000.0,resulttype));
  784. include(result.flags,nf_is_currency);
  785. end
  786. else if is_currency(left.resulttype.def) then
  787. begin
  788. result:=caddnode.create(slashn,getcopy,crealconstnode.create(10000.0,resulttype));
  789. include(result.flags,nf_is_currency);
  790. end;
  791. end;
  792. end;
  793. function ttypeconvnode.resulttype_real_to_currency : tnode;
  794. begin
  795. if not is_currency(resulttype.def) then
  796. internalerror(200304221);
  797. result:=nil;
  798. left:=caddnode.create(muln,left,crealconstnode.create(10000.0,left.resulttype));
  799. include(left.flags,nf_is_currency);
  800. resulttypepass(left);
  801. { Convert constants directly, else call Round() }
  802. if left.nodetype=realconstn then
  803. result:=cordconstnode.create(round(trealconstnode(left).value_real),resulttype,false)
  804. else
  805. result:=ccallnode.createinternres('fpc_round',
  806. ccallparanode.create(left,nil),resulttype);
  807. left:=nil;
  808. end;
  809. function ttypeconvnode.resulttype_real_to_real : tnode;
  810. begin
  811. result:=nil;
  812. if is_currency(left.resulttype.def) and not(is_currency(resulttype.def)) then
  813. begin
  814. left:=caddnode.create(slashn,left,crealconstnode.create(10000.0,left.resulttype));
  815. include(left.flags,nf_is_currency);
  816. resulttypepass(left);
  817. end
  818. else
  819. if is_currency(resulttype.def) and not(is_currency(left.resulttype.def)) then
  820. begin
  821. left:=caddnode.create(muln,left,crealconstnode.create(10000.0,left.resulttype));
  822. include(left.flags,nf_is_currency);
  823. resulttypepass(left);
  824. end;
  825. if left.nodetype=realconstn then
  826. result:=crealconstnode.create(trealconstnode(left).value_real,resulttype);
  827. end;
  828. function ttypeconvnode.resulttype_cchar_to_pchar : tnode;
  829. begin
  830. result:=nil;
  831. if is_pwidechar(resulttype.def) then
  832. inserttypeconv(left,cwidestringtype)
  833. else
  834. inserttypeconv(left,cshortstringtype);
  835. { evaluate again, reset resulttype so the convert_typ
  836. will be calculated again and cstring_to_pchar will
  837. be used for futher conversion }
  838. result:=det_resulttype;
  839. end;
  840. function ttypeconvnode.resulttype_cstring_to_pchar : tnode;
  841. begin
  842. result:=nil;
  843. if is_pwidechar(resulttype.def) then
  844. inserttypeconv(left,cwidestringtype);
  845. end;
  846. function ttypeconvnode.resulttype_arrayconstructor_to_set : tnode;
  847. var
  848. hp : tnode;
  849. begin
  850. result:=nil;
  851. if left.nodetype<>arrayconstructorn then
  852. internalerror(5546);
  853. { remove typeconv node }
  854. hp:=left;
  855. left:=nil;
  856. { create a set constructor tree }
  857. arrayconstructor_to_set(hp);
  858. result:=hp;
  859. end;
  860. function ttypeconvnode.resulttype_pchar_to_string : tnode;
  861. begin
  862. result := ccallnode.createinternres(
  863. 'fpc_pchar_to_'+tstringdef(resulttype.def).stringtypname,
  864. ccallparanode.create(left,nil),resulttype);
  865. left := nil;
  866. end;
  867. function ttypeconvnode.resulttype_interface_to_guid : tnode;
  868. begin
  869. if assigned(tobjectdef(left.resulttype.def).iidguid) then
  870. result:=cguidconstnode.create(tobjectdef(left.resulttype.def).iidguid^);
  871. end;
  872. function ttypeconvnode.resulttype_dynarray_to_openarray : tnode;
  873. begin
  874. { a dynamic array is a pointer to an array, so to convert it to }
  875. { an open array, we have to dereference it (JM) }
  876. result := ctypeconvnode.create_explicit(left,voidpointertype);
  877. resulttypepass(result);
  878. { left is reused }
  879. left := nil;
  880. result := cderefnode.create(result);
  881. result.resulttype := resulttype;
  882. end;
  883. function ttypeconvnode.resulttype_pwchar_to_string : tnode;
  884. begin
  885. result := ccallnode.createinternres(
  886. 'fpc_pwidechar_to_'+tstringdef(resulttype.def).stringtypname,
  887. ccallparanode.create(left,nil),resulttype);
  888. left := nil;
  889. end;
  890. function ttypeconvnode.resulttype_variant_to_dynarray : tnode;
  891. begin
  892. result := ccallnode.createinternres(
  893. 'fpc_variant_to_dynarray',
  894. ccallparanode.create(caddrnode.create(crttinode.create(tstoreddef(resulttype.def),initrtti)),
  895. ccallparanode.create(left,nil)
  896. ),resulttype);
  897. left := nil;
  898. end;
  899. function ttypeconvnode.resulttype_dynarray_to_variant : tnode;
  900. begin
  901. result := ccallnode.createinternres(
  902. 'fpc_dynarray_to_variant',
  903. ccallparanode.create(caddrnode.create(crttinode.create(tstoreddef(resulttype.def),initrtti)),
  904. ccallparanode.create(left,nil)
  905. ),resulttype);
  906. result:=nil;
  907. end;
  908. function ttypeconvnode.resulttype_variant_to_enum : tnode;
  909. begin
  910. result := ctypeconvnode.create_explicit(left,sinttype);
  911. result := ctypeconvnode.create_explicit(result,resulttype);
  912. resulttypepass(result);
  913. { left is reused }
  914. left := nil;
  915. end;
  916. function ttypeconvnode.resulttype_enum_to_variant : tnode;
  917. begin
  918. result := ctypeconvnode.create_explicit(left,sinttype);
  919. result := ctypeconvnode.create_explicit(result,cvarianttype);
  920. resulttypepass(result);
  921. { left is reused }
  922. left := nil;
  923. end;
  924. function ttypeconvnode.resulttype_call_helper(c : tconverttype) : tnode;
  925. {$ifdef fpc}
  926. const
  927. resulttypeconvert : array[tconverttype] of pointer = (
  928. {equal} nil,
  929. {not_possible} nil,
  930. { string_2_string } @ttypeconvnode.resulttype_string_to_string,
  931. { char_2_string } @ttypeconvnode.resulttype_char_to_string,
  932. { char_2_chararray } @ttypeconvnode.resulttype_char_to_chararray,
  933. { pchar_2_string } @ttypeconvnode.resulttype_pchar_to_string,
  934. { cchar_2_pchar } @ttypeconvnode.resulttype_cchar_to_pchar,
  935. { cstring_2_pchar } @ttypeconvnode.resulttype_cstring_to_pchar,
  936. { ansistring_2_pchar } nil,
  937. { string_2_chararray } @ttypeconvnode.resulttype_string_to_chararray,
  938. { chararray_2_string } @ttypeconvnode.resulttype_chararray_to_string,
  939. { array_2_pointer } nil,
  940. { pointer_2_array } nil,
  941. { int_2_int } @ttypeconvnode.resulttype_int_to_int,
  942. { int_2_bool } nil,
  943. { bool_2_bool } nil,
  944. { bool_2_int } nil,
  945. { real_2_real } @ttypeconvnode.resulttype_real_to_real,
  946. { int_2_real } @ttypeconvnode.resulttype_int_to_real,
  947. { real_2_currency } @ttypeconvnode.resulttype_real_to_currency,
  948. { proc_2_procvar } nil,
  949. { arrayconstructor_2_set } @ttypeconvnode.resulttype_arrayconstructor_to_set,
  950. { load_smallset } nil,
  951. { cord_2_pointer } @ttypeconvnode.resulttype_cord_to_pointer,
  952. { intf_2_string } nil,
  953. { intf_2_guid } @ttypeconvnode.resulttype_interface_to_guid,
  954. { class_2_intf } nil,
  955. { char_2_char } @ttypeconvnode.resulttype_char_to_char,
  956. { normal_2_smallset} nil,
  957. { dynarray_2_openarray} @resulttype_dynarray_to_openarray,
  958. { pwchar_2_string} @resulttype_pwchar_to_string,
  959. { variant_2_dynarray} @resulttype_variant_to_dynarray,
  960. { dynarray_2_variant} @resulttype_dynarray_to_variant,
  961. { variant_2_enum} @resulttype_variant_to_enum,
  962. { enum_2_variant} @resulttype_enum_to_variant
  963. );
  964. type
  965. tprocedureofobject = function : tnode of object;
  966. var
  967. r : packed record
  968. proc : pointer;
  969. obj : pointer;
  970. end;
  971. begin
  972. result:=nil;
  973. { this is a little bit dirty but it works }
  974. { and should be quite portable too }
  975. r.proc:=resulttypeconvert[c];
  976. r.obj:=self;
  977. if assigned(r.proc) then
  978. result:=tprocedureofobject(r)();
  979. end;
  980. {$else}
  981. begin
  982. case c of
  983. tc_string_2_string: resulttype_string_to_string;
  984. tc_char_2_string : resulttype_char_to_string;
  985. tc_char_2_chararray: resulttype_char_to_chararray;
  986. tc_pchar_2_string : resulttype_pchar_to_string;
  987. tc_cchar_2_pchar : resulttype_cchar_to_pchar;
  988. tc_cstring_2_pchar : resulttype_cstring_to_pchar;
  989. tc_string_2_chararray : resulttype_string_to_chararray;
  990. tc_chararray_2_string : resulttype_chararray_to_string;
  991. tc_real_2_real : resulttype_real_to_real;
  992. tc_int_2_real : resulttype_int_to_real;
  993. tc_real_2_currency : resulttype_real_to_currency;
  994. tc_arrayconstructor_2_set : resulttype_arrayconstructor_to_set;
  995. tc_cord_2_pointer : resulttype_cord_to_pointer;
  996. tc_intf_2_guid : resulttype_interface_to_guid;
  997. tc_char_2_char : resulttype_char_to_char;
  998. tc_dynarray_2_openarray : resulttype_dynarray_to_openarray;
  999. tc_pwchar_2_string : resulttype_pwchar_to_string;
  1000. tc_variant_2_dynarray : resulttype_variant_to_dynarray;
  1001. tc_dynarray_2_variant : resulttype_dynarray_to_variant;
  1002. end;
  1003. end;
  1004. {$Endif fpc}
  1005. function ttypeconvnode.det_resulttype:tnode;
  1006. var
  1007. htype : ttype;
  1008. hp : tnode;
  1009. currprocdef,
  1010. aprocdef : tprocdef;
  1011. eq : tequaltype;
  1012. cdoptions : tcompare_defs_options;
  1013. begin
  1014. result:=nil;
  1015. resulttype:=totype;
  1016. resulttypepass(left);
  1017. if codegenerror then
  1018. exit;
  1019. { When absolute force tc_equal }
  1020. if (nf_absolute in flags) then
  1021. begin
  1022. convtype:=tc_equal;
  1023. exit;
  1024. end;
  1025. { tp procvar support. Skip typecasts to record or set. Those
  1026. convert on the procvar value. This is used to access the
  1027. fields of a methodpointer }
  1028. if not(resulttype.def.deftype in [recorddef,setdef]) then
  1029. maybe_call_procvar(left,true);
  1030. cdoptions:=[cdo_check_operator,cdo_allow_variant];
  1031. if nf_explicit in flags then
  1032. include(cdoptions,cdo_explicit);
  1033. eq:=compare_defs_ext(left.resulttype.def,resulttype.def,left.nodetype,convtype,aprocdef,cdoptions);
  1034. case eq of
  1035. te_exact,
  1036. te_equal :
  1037. begin
  1038. { because is_equal only checks the basetype for sets we need to
  1039. check here if we are loading a smallset into a normalset }
  1040. if (resulttype.def.deftype=setdef) and
  1041. (left.resulttype.def.deftype=setdef) and
  1042. ((tsetdef(resulttype.def).settype = smallset) xor
  1043. (tsetdef(left.resulttype.def).settype = smallset)) then
  1044. begin
  1045. { constant sets can be converted by changing the type only }
  1046. if (left.nodetype=setconstn) then
  1047. begin
  1048. left.resulttype:=resulttype;
  1049. result:=left;
  1050. left:=nil;
  1051. exit;
  1052. end;
  1053. if (tsetdef(resulttype.def).settype <> smallset) then
  1054. convtype:=tc_load_smallset
  1055. else
  1056. convtype := tc_normal_2_smallset;
  1057. exit;
  1058. end
  1059. else
  1060. begin
  1061. { Only leave when there is no conversion to do.
  1062. We can still need to call a conversion routine,
  1063. like the routine to convert a stringconstnode }
  1064. if convtype in [tc_equal,tc_not_possible] then
  1065. begin
  1066. left.resulttype:=resulttype;
  1067. result:=left;
  1068. left:=nil;
  1069. exit;
  1070. end;
  1071. end;
  1072. end;
  1073. te_convert_l1,
  1074. te_convert_l2,
  1075. te_convert_l3 :
  1076. begin
  1077. { nothing to do }
  1078. end;
  1079. te_convert_operator :
  1080. begin
  1081. include(current_procinfo.flags,pi_do_call);
  1082. inc(aprocdef.procsym.refs);
  1083. hp:=ccallnode.create(ccallparanode.create(left,nil),
  1084. Tprocsym(aprocdef.procsym),nil,nil);
  1085. { tell explicitly which def we must use !! (PM) }
  1086. tcallnode(hp).procdefinition:=aprocdef;
  1087. left:=nil;
  1088. result:=hp;
  1089. exit;
  1090. end;
  1091. te_incompatible :
  1092. begin
  1093. { Procedures have a resulttype.def of voiddef and functions of their
  1094. own resulttype.def. They will therefore always be incompatible with
  1095. a procvar. Because isconvertable cannot check for procedures we
  1096. use an extra check for them.}
  1097. if (m_tp_procvar in aktmodeswitches) and
  1098. (resulttype.def.deftype=procvardef) then
  1099. begin
  1100. if is_procsym_load(left) then
  1101. begin
  1102. if (left.nodetype<>addrn) then
  1103. begin
  1104. convtype:=tc_proc_2_procvar;
  1105. { Now check if the procedure we are going to assign to
  1106. the procvar, is compatible with the procvar's type }
  1107. if not(nf_explicit in flags) and
  1108. (proc_to_procvar_equal(tprocsym(tloadnode(left).symtableentry).first_procdef,
  1109. tprocvardef(resulttype.def),true)=te_incompatible) then
  1110. IncompatibleTypes(tprocsym(tloadnode(left).symtableentry).first_procdef,resulttype.def);
  1111. exit;
  1112. end;
  1113. end
  1114. else
  1115. if (left.nodetype=calln) and
  1116. (tcallnode(left).para_count=0) then
  1117. begin
  1118. if assigned(tcallnode(left).right) then
  1119. begin
  1120. { this is already a procvar, if it is really equal
  1121. is checked below }
  1122. convtype:=tc_equal;
  1123. hp:=tcallnode(left).right.getcopy;
  1124. currprocdef:=tprocdef(hp.resulttype.def);
  1125. end
  1126. else
  1127. begin
  1128. convtype:=tc_proc_2_procvar;
  1129. currprocdef:=Tprocsym(Tcallnode(left).symtableprocentry).search_procdef_byprocvardef(Tprocvardef(resulttype.def));
  1130. hp:=cloadnode.create_procvar(tprocsym(tcallnode(left).symtableprocentry),
  1131. currprocdef,tcallnode(left).symtableproc);
  1132. if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) then
  1133. begin
  1134. if assigned(tcallnode(left).methodpointer) then
  1135. begin
  1136. { Under certain circumstances the methodpointer is a loadvmtaddrn
  1137. which isn't possible if it is used as a method pointer, so
  1138. fix this.
  1139. If you change this, ensure that tests/tbs/tw2669.pp still works }
  1140. if tcallnode(left).methodpointer.nodetype=loadvmtaddrn then
  1141. tloadnode(hp).set_mp(tloadvmtaddrnode(tcallnode(left).methodpointer).left.getcopy)
  1142. else
  1143. tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy);
  1144. end
  1145. else
  1146. tloadnode(hp).set_mp(load_self_node);
  1147. end;
  1148. resulttypepass(hp);
  1149. end;
  1150. left.free;
  1151. left:=hp;
  1152. { Now check if the procedure we are going to assign to
  1153. the procvar, is compatible with the procvar's type }
  1154. if not(nf_explicit in flags) and
  1155. (proc_to_procvar_equal(currprocdef,
  1156. tprocvardef(resulttype.def),true)=te_incompatible) then
  1157. IncompatibleTypes(left.resulttype.def,resulttype.def);
  1158. exit;
  1159. end;
  1160. end;
  1161. { Handle explicit type conversions }
  1162. if nf_explicit in flags then
  1163. begin
  1164. { do common tc_equal cast }
  1165. convtype:=tc_equal;
  1166. { ordinal constants can be resized to 1,2,4,8 bytes }
  1167. if (left.nodetype=ordconstn) then
  1168. begin
  1169. { Insert typeconv for ordinal to the correct size first on left, after
  1170. that the other conversion can be done }
  1171. htype.reset;
  1172. case resulttype.def.size of
  1173. 1 :
  1174. htype:=s8inttype;
  1175. 2 :
  1176. htype:=s16inttype;
  1177. 4 :
  1178. htype:=s32inttype;
  1179. 8 :
  1180. htype:=s64inttype;
  1181. end;
  1182. { we need explicit, because it can also be an enum }
  1183. if assigned(htype.def) then
  1184. inserttypeconv_explicit(left,htype)
  1185. else
  1186. CGMessage2(cg_e_illegal_type_conversion,left.resulttype.def.gettypename,resulttype.def.gettypename);
  1187. end;
  1188. { check if the result could be in a register }
  1189. if (not(tstoreddef(resulttype.def).is_intregable) and
  1190. not(tstoreddef(resulttype.def).is_fpuregable)) or
  1191. ((left.resulttype.def.deftype = floatdef) and
  1192. (resulttype.def.deftype <> floatdef)) then
  1193. make_not_regable(left);
  1194. { class to class or object to object, with checkobject support }
  1195. if (resulttype.def.deftype=objectdef) and
  1196. (left.resulttype.def.deftype=objectdef) then
  1197. begin
  1198. if (cs_check_object in aktlocalswitches) then
  1199. begin
  1200. if is_class_or_interface(resulttype.def) then
  1201. begin
  1202. { we can translate the typeconvnode to 'as' when
  1203. typecasting to a class or interface }
  1204. hp:=casnode.create(left,cloadvmtaddrnode.create(ctypenode.create(resulttype)));
  1205. left:=nil;
  1206. result:=hp;
  1207. exit;
  1208. end;
  1209. end
  1210. else
  1211. begin
  1212. { check if the types are related }
  1213. if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(resulttype.def)))) and
  1214. (not(tobjectdef(resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
  1215. CGMessage2(type_w_classes_not_related,left.resulttype.def.typename,resulttype.def.typename);
  1216. end;
  1217. end
  1218. else
  1219. begin
  1220. { only if the same size or formal def }
  1221. if not(
  1222. (left.resulttype.def.deftype=formaldef) or
  1223. (
  1224. not(is_open_array(left.resulttype.def)) and
  1225. (left.resulttype.def.size=resulttype.def.size)
  1226. ) or
  1227. (
  1228. is_void(left.resulttype.def) and
  1229. (left.nodetype=derefn)
  1230. )
  1231. ) then
  1232. CGMessage2(cg_e_illegal_type_conversion,left.resulttype.def.gettypename,resulttype.def.gettypename);
  1233. end;
  1234. end
  1235. else
  1236. IncompatibleTypes(left.resulttype.def,resulttype.def);
  1237. end;
  1238. else
  1239. internalerror(200211231);
  1240. end;
  1241. { Give hint for unportable code }
  1242. if ((left.resulttype.def.deftype=orddef) and
  1243. (resulttype.def.deftype in [pointerdef,procvardef,classrefdef])) or
  1244. ((resulttype.def.deftype=orddef) and
  1245. (left.resulttype.def.deftype in [pointerdef,procvardef,classrefdef])) then
  1246. CGMessage(cg_h_pointer_to_longint_conv_not_portable);
  1247. { Constant folding and other node transitions to
  1248. remove the typeconv node }
  1249. case left.nodetype of
  1250. niln :
  1251. begin
  1252. { nil to ordinal node }
  1253. if (resulttype.def.deftype=orddef) then
  1254. begin
  1255. hp:=cordconstnode.create(0,resulttype,true);
  1256. result:=hp;
  1257. exit;
  1258. end
  1259. else
  1260. { fold nil to any pointer type }
  1261. if (resulttype.def.deftype=pointerdef) then
  1262. begin
  1263. hp:=cnilnode.create;
  1264. hp.resulttype:=resulttype;
  1265. result:=hp;
  1266. exit;
  1267. end
  1268. else
  1269. { remove typeconv after niln, but not when the result is a
  1270. methodpointer. The typeconv of the methodpointer will then
  1271. take care of updateing size of niln to OS_64 }
  1272. if not((resulttype.def.deftype=procvardef) and
  1273. (po_methodpointer in tprocvardef(resulttype.def).procoptions)) then
  1274. begin
  1275. left.resulttype:=resulttype;
  1276. result:=left;
  1277. left:=nil;
  1278. exit;
  1279. end;
  1280. end;
  1281. ordconstn :
  1282. begin
  1283. { ordinal contants can be directly converted }
  1284. { but not char to char because it is a widechar to char or via versa }
  1285. { which needs extra code to do the code page transistion }
  1286. if is_ordinal(resulttype.def) and
  1287. not(convtype=tc_char_2_char) then
  1288. begin
  1289. { replace the resulttype and recheck the range }
  1290. left.resulttype:=resulttype;
  1291. testrange(left.resulttype.def,tordconstnode(left).value,(nf_explicit in flags));
  1292. result:=left;
  1293. left:=nil;
  1294. exit;
  1295. end;
  1296. end;
  1297. pointerconstn :
  1298. begin
  1299. { pointerconstn to any pointer is folded too }
  1300. if (resulttype.def.deftype=pointerdef) then
  1301. begin
  1302. left.resulttype:=resulttype;
  1303. result:=left;
  1304. left:=nil;
  1305. exit;
  1306. end
  1307. { constant pointer to ordinal }
  1308. else if is_ordinal(resulttype.def) then
  1309. begin
  1310. hp:=cordconstnode.create(tpointerconstnode(left).value,
  1311. resulttype,true);
  1312. result:=hp;
  1313. exit;
  1314. end;
  1315. end;
  1316. end;
  1317. { now call the resulttype helper to do constant folding }
  1318. result:=resulttype_call_helper(convtype);
  1319. end;
  1320. procedure Ttypeconvnode.mark_write;
  1321. begin
  1322. left.mark_write;
  1323. end;
  1324. function ttypeconvnode.first_cord_to_pointer : tnode;
  1325. begin
  1326. result:=nil;
  1327. internalerror(200104043);
  1328. end;
  1329. function ttypeconvnode.first_int_to_int : tnode;
  1330. begin
  1331. first_int_to_int:=nil;
  1332. if (left.expectloc<>LOC_REGISTER) and
  1333. not is_void(left.resulttype.def) and
  1334. (resulttype.def.size>left.resulttype.def.size) then
  1335. expectloc:=LOC_REGISTER
  1336. else
  1337. expectloc:=left.expectloc;
  1338. {$ifndef cpu64bit}
  1339. if is_64bit(resulttype.def) then
  1340. registersint:=max(registersint,2)
  1341. else
  1342. {$endif cpu64bit}
  1343. registersint:=max(registersint,1);
  1344. end;
  1345. function ttypeconvnode.first_cstring_to_pchar : tnode;
  1346. begin
  1347. first_cstring_to_pchar:=nil;
  1348. registersint:=1;
  1349. expectloc:=LOC_REGISTER;
  1350. end;
  1351. function ttypeconvnode.first_string_to_chararray : tnode;
  1352. begin
  1353. first_string_to_chararray:=nil;
  1354. expectloc:=left.expectloc;
  1355. end;
  1356. function ttypeconvnode.first_char_to_string : tnode;
  1357. begin
  1358. first_char_to_string:=nil;
  1359. expectloc:=LOC_REFERENCE;
  1360. end;
  1361. function ttypeconvnode.first_nothing : tnode;
  1362. begin
  1363. first_nothing:=nil;
  1364. end;
  1365. function ttypeconvnode.first_array_to_pointer : tnode;
  1366. begin
  1367. first_array_to_pointer:=nil;
  1368. if registersint<1 then
  1369. registersint:=1;
  1370. expectloc:=LOC_REGISTER;
  1371. end;
  1372. function ttypeconvnode.first_int_to_real: tnode;
  1373. var
  1374. fname: string[32];
  1375. typname : string[12];
  1376. begin
  1377. { Get the type name }
  1378. { Normally the typename should be one of the following:
  1379. single, double - carl
  1380. }
  1381. typname := lower(pbestrealtype^.def.gettypename);
  1382. { converting a 64bit integer to a float requires a helper }
  1383. if is_64bit(left.resulttype.def) then
  1384. begin
  1385. if is_signed(left.resulttype.def) then
  1386. fname := 'fpc_int64_to_'+typname
  1387. else
  1388. {$warning generic conversion from int to float does not support unsigned integers}
  1389. fname := 'fpc_int64_to_'+typname;
  1390. result := ccallnode.createintern(fname,ccallparanode.create(
  1391. left,nil));
  1392. left:=nil;
  1393. firstpass(result);
  1394. exit;
  1395. end
  1396. else
  1397. { other integers are supposed to be 32 bit }
  1398. begin
  1399. {$warning generic conversion from int to float does not support unsigned integers}
  1400. if is_signed(left.resulttype.def) then
  1401. fname := 'fpc_longint_to_'+typname
  1402. else
  1403. fname := 'fpc_longint_to_'+typname;
  1404. result := ccallnode.createintern(fname,ccallparanode.create(
  1405. left,nil));
  1406. left:=nil;
  1407. firstpass(result);
  1408. exit;
  1409. end;
  1410. end;
  1411. function ttypeconvnode.first_real_to_real : tnode;
  1412. begin
  1413. first_real_to_real:=nil;
  1414. { comp isn't a floating type }
  1415. if registersfpu<1 then
  1416. registersfpu:=1;
  1417. expectloc:=LOC_FPUREGISTER;
  1418. end;
  1419. function ttypeconvnode.first_pointer_to_array : tnode;
  1420. begin
  1421. first_pointer_to_array:=nil;
  1422. if registersint<1 then
  1423. registersint:=1;
  1424. expectloc:=LOC_REFERENCE;
  1425. end;
  1426. function ttypeconvnode.first_cchar_to_pchar : tnode;
  1427. begin
  1428. first_cchar_to_pchar:=nil;
  1429. internalerror(200104021);
  1430. end;
  1431. function ttypeconvnode.first_bool_to_int : tnode;
  1432. begin
  1433. first_bool_to_int:=nil;
  1434. { byte(boolean) or word(wordbool) or longint(longbool) must
  1435. be accepted for var parameters }
  1436. if (nf_explicit in flags) and
  1437. (left.resulttype.def.size=resulttype.def.size) and
  1438. (left.expectloc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  1439. exit;
  1440. { when converting to 64bit, first convert to a 32bit int and then }
  1441. { convert to a 64bit int (only necessary for 32bit processors) (JM) }
  1442. if resulttype.def.size > sizeof(aword) then
  1443. begin
  1444. result := ctypeconvnode.create_explicit(left,u32inttype);
  1445. result := ctypeconvnode.create(result,resulttype);
  1446. left := nil;
  1447. firstpass(result);
  1448. exit;
  1449. end;
  1450. expectloc:=LOC_REGISTER;
  1451. if registersint<1 then
  1452. registersint:=1;
  1453. end;
  1454. function ttypeconvnode.first_int_to_bool : tnode;
  1455. begin
  1456. first_int_to_bool:=nil;
  1457. { byte(boolean) or word(wordbool) or longint(longbool) must
  1458. be accepted for var parameters }
  1459. if (nf_explicit in flags) and
  1460. (left.resulttype.def.size=resulttype.def.size) and
  1461. (left.expectloc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
  1462. exit;
  1463. expectloc:=LOC_REGISTER;
  1464. { need if bool to bool !!
  1465. not very nice !!
  1466. insertypeconv(left,s32inttype);
  1467. left.explizit:=true;
  1468. firstpass(left); }
  1469. if registersint<1 then
  1470. registersint:=1;
  1471. end;
  1472. function ttypeconvnode.first_bool_to_bool : tnode;
  1473. begin
  1474. first_bool_to_bool:=nil;
  1475. expectloc:=LOC_REGISTER;
  1476. if registersint<1 then
  1477. registersint:=1;
  1478. end;
  1479. function ttypeconvnode.first_char_to_char : tnode;
  1480. begin
  1481. first_char_to_char:=first_int_to_int;
  1482. end;
  1483. function ttypeconvnode.first_proc_to_procvar : tnode;
  1484. begin
  1485. first_proc_to_procvar:=nil;
  1486. if assigned(tunarynode(left).left) then
  1487. begin
  1488. if (left.expectloc<>LOC_CREFERENCE) then
  1489. CGMessage(cg_e_illegal_expression);
  1490. registersint:=left.registersint;
  1491. expectloc:=left.expectloc
  1492. end
  1493. else
  1494. begin
  1495. registersint:=left.registersint;
  1496. if registersint<1 then
  1497. registersint:=1;
  1498. expectloc:=LOC_REGISTER;
  1499. end
  1500. end;
  1501. function ttypeconvnode.first_load_smallset : tnode;
  1502. var
  1503. srsym: ttypesym;
  1504. p: tcallparanode;
  1505. begin
  1506. if not searchsystype('FPC_SMALL_SET',srsym) then
  1507. internalerror(200108313);
  1508. p := ccallparanode.create(left,nil);
  1509. { reused }
  1510. left := nil;
  1511. { convert parameter explicitely to fpc_small_set }
  1512. p.left := ctypeconvnode.create_explicit(p.left,srsym.restype);
  1513. { create call, adjust resulttype }
  1514. result :=
  1515. ccallnode.createinternres('fpc_set_load_small',p,resulttype);
  1516. firstpass(result);
  1517. end;
  1518. function ttypeconvnode.first_ansistring_to_pchar : tnode;
  1519. begin
  1520. first_ansistring_to_pchar:=nil;
  1521. expectloc:=LOC_REGISTER;
  1522. if registersint<1 then
  1523. registersint:=1;
  1524. end;
  1525. function ttypeconvnode.first_arrayconstructor_to_set : tnode;
  1526. begin
  1527. first_arrayconstructor_to_set:=nil;
  1528. internalerror(200104022);
  1529. end;
  1530. function ttypeconvnode.first_class_to_intf : tnode;
  1531. begin
  1532. first_class_to_intf:=nil;
  1533. expectloc:=LOC_REGISTER;
  1534. if registersint<1 then
  1535. registersint:=1;
  1536. end;
  1537. function ttypeconvnode._first_int_to_int : tnode;
  1538. begin
  1539. result:=first_int_to_int;
  1540. end;
  1541. function ttypeconvnode._first_cstring_to_pchar : tnode;
  1542. begin
  1543. result:=first_cstring_to_pchar;
  1544. end;
  1545. function ttypeconvnode._first_string_to_chararray : tnode;
  1546. begin
  1547. result:=first_string_to_chararray;
  1548. end;
  1549. function ttypeconvnode._first_char_to_string : tnode;
  1550. begin
  1551. result:=first_char_to_string;
  1552. end;
  1553. function ttypeconvnode._first_nothing : tnode;
  1554. begin
  1555. result:=first_nothing;
  1556. end;
  1557. function ttypeconvnode._first_array_to_pointer : tnode;
  1558. begin
  1559. result:=first_array_to_pointer;
  1560. end;
  1561. function ttypeconvnode._first_int_to_real : tnode;
  1562. begin
  1563. result:=first_int_to_real;
  1564. end;
  1565. function ttypeconvnode._first_real_to_real : tnode;
  1566. begin
  1567. result:=first_real_to_real;
  1568. end;
  1569. function ttypeconvnode._first_pointer_to_array : tnode;
  1570. begin
  1571. result:=first_pointer_to_array;
  1572. end;
  1573. function ttypeconvnode._first_cchar_to_pchar : tnode;
  1574. begin
  1575. result:=first_cchar_to_pchar;
  1576. end;
  1577. function ttypeconvnode._first_bool_to_int : tnode;
  1578. begin
  1579. result:=first_bool_to_int;
  1580. end;
  1581. function ttypeconvnode._first_int_to_bool : tnode;
  1582. begin
  1583. result:=first_int_to_bool;
  1584. end;
  1585. function ttypeconvnode._first_bool_to_bool : tnode;
  1586. begin
  1587. result:=first_bool_to_bool;
  1588. end;
  1589. function ttypeconvnode._first_proc_to_procvar : tnode;
  1590. begin
  1591. result:=first_proc_to_procvar;
  1592. end;
  1593. function ttypeconvnode._first_load_smallset : tnode;
  1594. begin
  1595. result:=first_load_smallset;
  1596. end;
  1597. function ttypeconvnode._first_cord_to_pointer : tnode;
  1598. begin
  1599. result:=first_cord_to_pointer;
  1600. end;
  1601. function ttypeconvnode._first_ansistring_to_pchar : tnode;
  1602. begin
  1603. result:=first_ansistring_to_pchar;
  1604. end;
  1605. function ttypeconvnode._first_arrayconstructor_to_set : tnode;
  1606. begin
  1607. result:=first_arrayconstructor_to_set;
  1608. end;
  1609. function ttypeconvnode._first_class_to_intf : tnode;
  1610. begin
  1611. result:=first_class_to_intf;
  1612. end;
  1613. function ttypeconvnode._first_char_to_char : tnode;
  1614. begin
  1615. result:=first_char_to_char;
  1616. end;
  1617. function ttypeconvnode.first_call_helper(c : tconverttype) : tnode;
  1618. const
  1619. firstconvert : array[tconverttype] of pointer = (
  1620. @ttypeconvnode._first_nothing, {equal}
  1621. @ttypeconvnode._first_nothing, {not_possible}
  1622. nil, { removed in resulttype_string_to_string }
  1623. @ttypeconvnode._first_char_to_string,
  1624. @ttypeconvnode._first_nothing, { char_2_chararray, needs nothing extra }
  1625. nil, { removed in resulttype_chararray_to_string }
  1626. @ttypeconvnode._first_cchar_to_pchar,
  1627. @ttypeconvnode._first_cstring_to_pchar,
  1628. @ttypeconvnode._first_ansistring_to_pchar,
  1629. @ttypeconvnode._first_string_to_chararray,
  1630. nil, { removed in resulttype_chararray_to_string }
  1631. @ttypeconvnode._first_array_to_pointer,
  1632. @ttypeconvnode._first_pointer_to_array,
  1633. @ttypeconvnode._first_int_to_int,
  1634. @ttypeconvnode._first_int_to_bool,
  1635. @ttypeconvnode._first_bool_to_bool,
  1636. @ttypeconvnode._first_bool_to_int,
  1637. @ttypeconvnode._first_real_to_real,
  1638. @ttypeconvnode._first_int_to_real,
  1639. nil, { removed in resulttype_real_to_currency }
  1640. @ttypeconvnode._first_proc_to_procvar,
  1641. @ttypeconvnode._first_arrayconstructor_to_set,
  1642. @ttypeconvnode._first_load_smallset,
  1643. @ttypeconvnode._first_cord_to_pointer,
  1644. @ttypeconvnode._first_nothing,
  1645. @ttypeconvnode._first_nothing,
  1646. @ttypeconvnode._first_class_to_intf,
  1647. @ttypeconvnode._first_char_to_char,
  1648. @ttypeconvnode._first_nothing,
  1649. @ttypeconvnode._first_nothing,
  1650. nil,
  1651. nil,
  1652. nil,
  1653. nil,
  1654. nil
  1655. );
  1656. type
  1657. tprocedureofobject = function : tnode of object;
  1658. var
  1659. r : packed record
  1660. proc : pointer;
  1661. obj : pointer;
  1662. end;
  1663. begin
  1664. { this is a little bit dirty but it works }
  1665. { and should be quite portable too }
  1666. r.proc:=firstconvert[c];
  1667. r.obj:=self;
  1668. if not assigned(r.proc) then
  1669. internalerror(200312081);
  1670. first_call_helper:=tprocedureofobject(r){$ifdef FPC}(){$endif FPC}
  1671. end;
  1672. function ttypeconvnode.pass_1 : tnode;
  1673. begin
  1674. result:=nil;
  1675. firstpass(left);
  1676. if codegenerror then
  1677. exit;
  1678. { load the value_str from the left part }
  1679. registersint:=left.registersint;
  1680. registersfpu:=left.registersfpu;
  1681. {$ifdef SUPPORT_MMX}
  1682. registersmmx:=left.registersmmx;
  1683. {$endif}
  1684. expectloc:=left.expectloc;
  1685. if (nf_explicit in flags) or
  1686. (nf_absolute in flags) then
  1687. begin
  1688. { check if the result could be in a register }
  1689. if not(tstoreddef(resulttype.def).is_intregable) and
  1690. not(tstoreddef(resulttype.def).is_fpuregable) then
  1691. make_not_regable(left);
  1692. end;
  1693. result:=first_call_helper(convtype);
  1694. end;
  1695. function ttypeconvnode.docompare(p: tnode) : boolean;
  1696. begin
  1697. docompare :=
  1698. inherited docompare(p) and
  1699. (convtype = ttypeconvnode(p).convtype);
  1700. end;
  1701. procedure ttypeconvnode._second_int_to_int;
  1702. begin
  1703. second_int_to_int;
  1704. end;
  1705. procedure ttypeconvnode._second_string_to_string;
  1706. begin
  1707. second_string_to_string;
  1708. end;
  1709. procedure ttypeconvnode._second_cstring_to_pchar;
  1710. begin
  1711. second_cstring_to_pchar;
  1712. end;
  1713. procedure ttypeconvnode._second_string_to_chararray;
  1714. begin
  1715. second_string_to_chararray;
  1716. end;
  1717. procedure ttypeconvnode._second_array_to_pointer;
  1718. begin
  1719. second_array_to_pointer;
  1720. end;
  1721. procedure ttypeconvnode._second_pointer_to_array;
  1722. begin
  1723. second_pointer_to_array;
  1724. end;
  1725. procedure ttypeconvnode._second_chararray_to_string;
  1726. begin
  1727. second_chararray_to_string;
  1728. end;
  1729. procedure ttypeconvnode._second_char_to_string;
  1730. begin
  1731. second_char_to_string;
  1732. end;
  1733. procedure ttypeconvnode._second_int_to_real;
  1734. begin
  1735. second_int_to_real;
  1736. end;
  1737. procedure ttypeconvnode._second_real_to_real;
  1738. begin
  1739. second_real_to_real;
  1740. end;
  1741. procedure ttypeconvnode._second_cord_to_pointer;
  1742. begin
  1743. second_cord_to_pointer;
  1744. end;
  1745. procedure ttypeconvnode._second_proc_to_procvar;
  1746. begin
  1747. second_proc_to_procvar;
  1748. end;
  1749. procedure ttypeconvnode._second_bool_to_int;
  1750. begin
  1751. second_bool_to_int;
  1752. end;
  1753. procedure ttypeconvnode._second_int_to_bool;
  1754. begin
  1755. second_int_to_bool;
  1756. end;
  1757. procedure ttypeconvnode._second_bool_to_bool;
  1758. begin
  1759. second_bool_to_bool;
  1760. end;
  1761. procedure ttypeconvnode._second_load_smallset;
  1762. begin
  1763. second_load_smallset;
  1764. end;
  1765. procedure ttypeconvnode._second_ansistring_to_pchar;
  1766. begin
  1767. second_ansistring_to_pchar;
  1768. end;
  1769. procedure ttypeconvnode._second_class_to_intf;
  1770. begin
  1771. second_class_to_intf;
  1772. end;
  1773. procedure ttypeconvnode._second_char_to_char;
  1774. begin
  1775. second_char_to_char;
  1776. end;
  1777. procedure ttypeconvnode._second_nothing;
  1778. begin
  1779. second_nothing;
  1780. end;
  1781. procedure ttypeconvnode.second_call_helper(c : tconverttype);
  1782. {$ifdef fpc}
  1783. const
  1784. secondconvert : array[tconverttype] of pointer = (
  1785. @_second_nothing, {equal}
  1786. @_second_nothing, {not_possible}
  1787. @_second_nothing, {second_string_to_string, handled in resulttype pass }
  1788. @_second_char_to_string,
  1789. @_second_nothing, {char_to_charray}
  1790. @_second_nothing, { pchar_to_string, handled in resulttype pass }
  1791. @_second_nothing, {cchar_to_pchar}
  1792. @_second_cstring_to_pchar,
  1793. @_second_ansistring_to_pchar,
  1794. @_second_string_to_chararray,
  1795. @_second_nothing, { chararray_to_string, handled in resulttype pass }
  1796. @_second_array_to_pointer,
  1797. @_second_pointer_to_array,
  1798. @_second_int_to_int,
  1799. @_second_int_to_bool,
  1800. @_second_bool_to_bool,
  1801. @_second_bool_to_int,
  1802. @_second_real_to_real,
  1803. @_second_int_to_real,
  1804. @_second_nothing, { real_to_currency, handled in resulttype pass }
  1805. @_second_proc_to_procvar,
  1806. @_second_nothing, { arrayconstructor_to_set }
  1807. @_second_nothing, { second_load_smallset, handled in first pass }
  1808. @_second_cord_to_pointer,
  1809. @_second_nothing, { interface 2 string }
  1810. @_second_nothing, { interface 2 guid }
  1811. @_second_class_to_intf,
  1812. @_second_char_to_char,
  1813. @_second_nothing, { normal_2_smallset }
  1814. @_second_nothing, { dynarray_2_openarray }
  1815. @_second_nothing, { pwchar_2_string }
  1816. @_second_nothing, { variant_2_dynarray }
  1817. @_second_nothing, { dynarray_2_variant}
  1818. @_second_nothing, { variant_2_enum }
  1819. @_second_nothing { enum_2_variant }
  1820. );
  1821. type
  1822. tprocedureofobject = procedure of object;
  1823. var
  1824. r : packed record
  1825. proc : pointer;
  1826. obj : pointer;
  1827. end;
  1828. begin
  1829. { this is a little bit dirty but it works }
  1830. { and should be quite portable too }
  1831. r.proc:=secondconvert[c];
  1832. r.obj:=self;
  1833. tprocedureofobject(r)();
  1834. end;
  1835. {$else fpc}
  1836. begin
  1837. case c of
  1838. tc_equal,
  1839. tc_not_possible,
  1840. tc_string_2_string : second_nothing;
  1841. tc_char_2_string : second_char_to_string;
  1842. tc_char_2_chararray : second_nothing;
  1843. tc_pchar_2_string : second_nothing;
  1844. tc_cchar_2_pchar : second_nothing;
  1845. tc_cstring_2_pchar : second_cstring_to_pchar;
  1846. tc_ansistring_2_pchar : second_ansistring_to_pchar;
  1847. tc_string_2_chararray : second_string_to_chararray;
  1848. tc_chararray_2_string : second_nothing;
  1849. tc_array_2_pointer : second_array_to_pointer;
  1850. tc_pointer_2_array : second_pointer_to_array;
  1851. tc_int_2_int : second_int_to_int;
  1852. tc_int_2_bool : second_int_to_bool;
  1853. tc_bool_2_bool : second_bool_to_bool;
  1854. tc_bool_2_int : second_bool_to_int;
  1855. tc_real_2_real : second_real_to_real;
  1856. tc_int_2_real : second_int_to_real;
  1857. tc_real_2_currency : second_nothing;
  1858. tc_proc_2_procvar : second_proc_to_procvar;
  1859. tc_arrayconstructor_2_set : second_nothing;
  1860. tc_load_smallset : second_nothing;
  1861. tc_cord_2_pointer : second_cord_to_pointer;
  1862. tc_intf_2_string : second_nothing;
  1863. tc_intf_2_guid : second_nothing;
  1864. tc_class_2_intf : second_class_to_intf;
  1865. tc_char_2_char : second_char_to_char;
  1866. tc_normal_2_smallset : second_nothing;
  1867. tc_dynarray_2_openarray : second_nothing;
  1868. tc_pwchar_2_string : second_nothing;
  1869. tc_variant_2_dynarray : second_nothing;
  1870. tc_dynarray_2_variant : second_nothing;
  1871. else internalerror(2002101101);
  1872. end;
  1873. end;
  1874. {$endif fpc}
  1875. {*****************************************************************************
  1876. TISNODE
  1877. *****************************************************************************}
  1878. constructor tisnode.create(l,r : tnode);
  1879. begin
  1880. inherited create(isn,l,r);
  1881. end;
  1882. function tisnode.det_resulttype:tnode;
  1883. var
  1884. paras: tcallparanode;
  1885. begin
  1886. result:=nil;
  1887. resulttypepass(left);
  1888. resulttypepass(right);
  1889. set_varstate(left,vs_used,true);
  1890. set_varstate(right,vs_used,true);
  1891. if codegenerror then
  1892. exit;
  1893. if (right.resulttype.def.deftype=classrefdef) then
  1894. begin
  1895. { left must be a class }
  1896. if is_class(left.resulttype.def) then
  1897. begin
  1898. { the operands must be related }
  1899. if (not(tobjectdef(left.resulttype.def).is_related(
  1900. tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
  1901. (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
  1902. tobjectdef(left.resulttype.def)))) then
  1903. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,
  1904. tclassrefdef(right.resulttype.def).pointertype.def.typename);
  1905. end
  1906. else
  1907. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1908. { call fpc_do_is helper }
  1909. paras := ccallparanode.create(
  1910. left,
  1911. ccallparanode.create(
  1912. right,nil));
  1913. result := ccallnode.createintern('fpc_do_is',paras);
  1914. left := nil;
  1915. right := nil;
  1916. end
  1917. else if is_interface(right.resulttype.def) then
  1918. begin
  1919. { left is a class }
  1920. if is_class(left.resulttype.def) then
  1921. begin
  1922. { the operands must be related }
  1923. if not(assigned(tobjectdef(left.resulttype.def).implementedinterfaces) and
  1924. (tobjectdef(left.resulttype.def).implementedinterfaces.searchintf(right.resulttype.def)<>-1)) then
  1925. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  1926. end
  1927. { left is an interface }
  1928. else if is_interface(left.resulttype.def) then
  1929. begin
  1930. { the operands must be related }
  1931. if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(right.resulttype.def)))) and
  1932. (not(tobjectdef(right.resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
  1933. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  1934. end
  1935. else
  1936. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1937. { call fpc_do_is helper }
  1938. paras := ccallparanode.create(
  1939. left,
  1940. ccallparanode.create(
  1941. right,nil));
  1942. result := ccallnode.createintern('fpc_do_is',paras);
  1943. left := nil;
  1944. right := nil;
  1945. end
  1946. else
  1947. CGMessage1(type_e_class_or_interface_type_expected,right.resulttype.def.typename);
  1948. resulttype:=booltype;
  1949. end;
  1950. function tisnode.pass_1 : tnode;
  1951. begin
  1952. internalerror(200204254);
  1953. result:=nil;
  1954. end;
  1955. { dummy pass_2, it will never be called, but we need one since }
  1956. { you can't instantiate an abstract class }
  1957. procedure tisnode.pass_2;
  1958. begin
  1959. end;
  1960. {*****************************************************************************
  1961. TASNODE
  1962. *****************************************************************************}
  1963. constructor tasnode.create(l,r : tnode);
  1964. begin
  1965. inherited create(asn,l,r);
  1966. call := nil;
  1967. end;
  1968. destructor tasnode.destroy;
  1969. begin
  1970. call.free;
  1971. inherited destroy;
  1972. end;
  1973. function tasnode.det_resulttype:tnode;
  1974. var
  1975. hp : tnode;
  1976. begin
  1977. result:=nil;
  1978. resulttypepass(right);
  1979. resulttypepass(left);
  1980. set_varstate(right,vs_used,true);
  1981. set_varstate(left,vs_used,true);
  1982. if codegenerror then
  1983. exit;
  1984. if (right.resulttype.def.deftype=classrefdef) then
  1985. begin
  1986. { left must be a class }
  1987. if is_class(left.resulttype.def) then
  1988. begin
  1989. { the operands must be related }
  1990. if (not(tobjectdef(left.resulttype.def).is_related(
  1991. tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def)))) and
  1992. (not(tobjectdef(tclassrefdef(right.resulttype.def).pointertype.def).is_related(
  1993. tobjectdef(left.resulttype.def)))) then
  1994. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,
  1995. tclassrefdef(right.resulttype.def).pointertype.def.typename);
  1996. end
  1997. else
  1998. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  1999. resulttype:=tclassrefdef(right.resulttype.def).pointertype;
  2000. end
  2001. else if is_interface(right.resulttype.def) then
  2002. begin
  2003. { left is a class }
  2004. if is_class(left.resulttype.def) then
  2005. begin
  2006. { the operands must be related
  2007. no, because the class instance could be a child class of the current one which
  2008. implements additional interfaces (FK)
  2009. b:=false;
  2010. o:=tobjectdef(left.resulttype.def);
  2011. while assigned(o) do
  2012. begin
  2013. if assigned(o.implementedinterfaces) and
  2014. (o.implementedinterfaces.searchintf(right.resulttype.def)<>-1) then
  2015. begin
  2016. b:=true;
  2017. break;
  2018. end;
  2019. o:=o.childof;
  2020. end;
  2021. if not(b) then
  2022. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  2023. }
  2024. end
  2025. { left is an interface }
  2026. else if is_interface(left.resulttype.def) then
  2027. begin
  2028. { the operands must be related
  2029. we don't necessarily know how the both interfaces are implemented, so we can't do this check (FK)
  2030. if (not(tobjectdef(left.resulttype.def).is_related(tobjectdef(right.resulttype.def)))) and
  2031. (not(tobjectdef(right.resulttype.def).is_related(tobjectdef(left.resulttype.def)))) then
  2032. CGMessage2(type_e_classes_not_related,left.resulttype.def.typename,right.resulttype.def.typename);
  2033. }
  2034. end
  2035. else
  2036. CGMessage1(type_e_class_type_expected,left.resulttype.def.typename);
  2037. resulttype:=right.resulttype;
  2038. { load the GUID of the interface }
  2039. if (right.nodetype=typen) then
  2040. begin
  2041. if assigned(tobjectdef(right.resulttype.def).iidguid) then
  2042. begin
  2043. hp:=cguidconstnode.create(tobjectdef(right.resulttype.def).iidguid^);
  2044. right.free;
  2045. right:=hp;
  2046. end
  2047. else
  2048. internalerror(200206282);
  2049. resulttypepass(right);
  2050. end;
  2051. end
  2052. else
  2053. CGMessage1(type_e_class_or_interface_type_expected,right.resulttype.def.typename);
  2054. end;
  2055. function tasnode.getcopy: tnode;
  2056. begin
  2057. result := inherited getcopy;
  2058. if assigned(call) then
  2059. tasnode(result).call := call.getcopy
  2060. else
  2061. tasnode(result).call := nil;
  2062. end;
  2063. function tasnode.pass_1 : tnode;
  2064. var
  2065. procname: string;
  2066. begin
  2067. result:=nil;
  2068. if not assigned(call) then
  2069. begin
  2070. if is_class(left.resulttype.def) and
  2071. (right.resulttype.def.deftype=classrefdef) then
  2072. call := ccallnode.createinternres('fpc_do_as',
  2073. ccallparanode.create(left,ccallparanode.create(right,nil)),
  2074. resulttype)
  2075. else
  2076. begin
  2077. if is_class(left.resulttype.def) then
  2078. procname := 'fpc_class_as_intf'
  2079. else
  2080. procname := 'fpc_intf_as';
  2081. call := ccallnode.createinternres(procname,
  2082. ccallparanode.create(right,ccallparanode.create(left,nil)),
  2083. resulttype);
  2084. end;
  2085. left := nil;
  2086. right := nil;
  2087. firstpass(call);
  2088. if codegenerror then
  2089. exit;
  2090. expectloc:=call.expectloc;
  2091. registersint:=call.registersint;
  2092. registersfpu:=call.registersfpu;
  2093. {$ifdef SUPPORT_MMX}
  2094. registersmmx:=call.registersmmx;
  2095. {$endif SUPPORT_MMX}
  2096. end;
  2097. end;
  2098. begin
  2099. ctypeconvnode:=ttypeconvnode;
  2100. casnode:=tasnode;
  2101. cisnode:=tisnode;
  2102. end.
  2103. {
  2104. $Log$
  2105. Revision 1.145 2004-05-23 14:14:18 florian
  2106. + added set of widechar support (limited to 256 chars, is delphi compatible)
  2107. Revision 1.144 2004/04/29 19:56:37 daniel
  2108. * Prepare compiler infrastructure for multiple ansistring types
  2109. Revision 1.143 2004/03/23 22:34:49 peter
  2110. * constants ordinals now always have a type assigned
  2111. * integer constants have the smallest type, unsigned prefered over
  2112. signed
  2113. Revision 1.142 2004/03/18 16:19:03 peter
  2114. * fixed operator overload allowing for pointer-string
  2115. * replaced some type_e_mismatch with more informational messages
  2116. Revision 1.141 2004/02/21 16:03:10 florian
  2117. * message about illegal type conversion reports now the types
  2118. Revision 1.140 2004/02/20 21:55:59 peter
  2119. * procvar cleanup
  2120. Revision 1.139 2004/02/13 15:42:21 peter
  2121. * compare_defs_ext has now a options argument
  2122. * fixes for variants
  2123. Revision 1.138 2004/02/05 01:24:08 florian
  2124. * several fixes to compile x86-64 system
  2125. Revision 1.137 2004/02/04 22:15:15 daniel
  2126. * Rtti generation moved to ncgutil
  2127. * Assmtai usage of symsym removed
  2128. * operator overloading cleanup up
  2129. Revision 1.136 2004/02/03 22:32:54 peter
  2130. * renamed xNNbittype to xNNinttype
  2131. * renamed registers32 to registersint
  2132. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  2133. Revision 1.135 2004/01/26 16:12:27 daniel
  2134. * reginfo now also only allocated during register allocation
  2135. * third round of gdb cleanups: kick out most of concatstabto
  2136. Revision 1.134 2003/12/26 00:32:21 florian
  2137. + fpu<->mm register conversion
  2138. Revision 1.133 2003/12/22 23:11:15 peter
  2139. * fix rangecheck error
  2140. Revision 1.132 2003/12/08 22:35:28 peter
  2141. * again procvar fixes
  2142. Revision 1.131 2003/11/22 00:31:52 jonas
  2143. * fixed range error
  2144. Revision 1.130 2003/11/04 22:30:15 florian
  2145. + type cast variant<->enum
  2146. * cnv. node second pass uses now as well helper wrappers
  2147. Revision 1.129 2003/10/31 18:42:03 peter
  2148. * don't call proc_to_procvar for explicit typecasts
  2149. Revision 1.128 2003/10/29 22:01:20 florian
  2150. * fixed passing of dyn. arrays to open array parameters
  2151. Revision 1.127 2003/10/28 15:36:01 peter
  2152. * absolute to object field supported, fixes tb0458
  2153. Revision 1.126 2003/10/23 14:44:07 peter
  2154. * splitted buildderef and buildderefimpl to fix interface crc
  2155. calculation
  2156. Revision 1.125 2003/10/22 20:40:00 peter
  2157. * write derefdata in a separate ppu entry
  2158. Revision 1.124 2003/10/21 18:16:13 peter
  2159. * IncompatibleTypes() added that will include unit names when
  2160. the typenames are the same
  2161. Revision 1.123 2003/10/09 14:39:03 peter
  2162. * allow explicit typecasts from classrefdef, fixes 2728
  2163. Revision 1.122 2003/10/08 19:19:45 peter
  2164. * set_varstate cleanup
  2165. Revision 1.121 2003/10/07 14:30:27 peter
  2166. * fix 2720
  2167. Revision 1.120 2003/10/01 20:34:48 peter
  2168. * procinfo unit contains tprocinfo
  2169. * cginfo renamed to cgbase
  2170. * moved cgmessage to verbose
  2171. * fixed ppc and sparc compiles
  2172. Revision 1.119 2003/09/25 14:57:51 peter
  2173. * fix different expectloc
  2174. Revision 1.118 2003/09/06 22:27:08 florian
  2175. * fixed web bug 2669
  2176. * cosmetic fix in printnode
  2177. * tobjectdef.gettypename implemented
  2178. Revision 1.117 2003/09/03 15:55:01 peter
  2179. * NEWRA branch merged
  2180. Revision 1.116 2003/08/10 17:25:23 peter
  2181. * fixed some reported bugs
  2182. Revision 1.115 2003/06/05 20:05:55 peter
  2183. * removed changesettype because that will change the definition
  2184. of the setdef forever and can result in a different between
  2185. original interface and current implementation definition
  2186. Revision 1.114 2003/06/04 17:55:09 jonas
  2187. * disable fpuregable for fpu variables typecasted to non fpu-type
  2188. Revision 1.113 2003/06/04 17:29:01 jonas
  2189. * fixed void_to_(int,pointer) typeconversion
  2190. Revision 1.112 2003/06/03 21:05:48 peter
  2191. * fix check for procedure without parameters
  2192. * calling constructor as member will not allocate memory
  2193. Revision 1.111 2003/05/11 21:37:03 peter
  2194. * moved implicit exception frame from ncgutil to psub
  2195. * constructor/destructor helpers moved from cobj/ncgutil to psub
  2196. Revision 1.110 2003/05/09 17:47:02 peter
  2197. * self moved to hidden parameter
  2198. * removed hdisposen,hnewn,selfn
  2199. Revision 1.109 2003/04/27 11:21:33 peter
  2200. * aktprocdef renamed to current_procdef
  2201. * procinfo renamed to current_procinfo
  2202. * procinfo will now be stored in current_module so it can be
  2203. cleaned up properly
  2204. * gen_main_procsym changed to create_main_proc and release_main_proc
  2205. to also generate a tprocinfo structure
  2206. * fixed unit implicit initfinal
  2207. Revision 1.108 2003/04/23 20:16:04 peter
  2208. + added currency support based on int64
  2209. + is_64bit for use in cg units instead of is_64bitint
  2210. * removed cgmessage from n386add, replace with internalerrors
  2211. Revision 1.107 2003/04/23 13:13:08 peter
  2212. * fix checking of procdef type which was broken since loadn returned
  2213. pointertype for tp procvar
  2214. Revision 1.106 2003/04/23 10:10:07 peter
  2215. * expectloc fixes
  2216. Revision 1.105 2003/04/22 23:50:23 peter
  2217. * firstpass uses expectloc
  2218. * checks if there are differences between the expectloc and
  2219. location.loc from secondpass in EXTDEBUG
  2220. Revision 1.104 2003/04/22 09:52:30 peter
  2221. * do not convert procvars with void return to callnode
  2222. Revision 1.103 2003/03/17 18:54:23 peter
  2223. * fix missing self setting for method to procvar conversion in
  2224. tp_procvar mode
  2225. Revision 1.102 2003/02/15 22:15:57 carl
  2226. * generic conversaion routines only work on signed types
  2227. Revision 1.101 2003/01/16 22:13:52 peter
  2228. * convert_l3 convertlevel added. This level is used for conversions
  2229. where information can be lost like converting widestring->ansistring
  2230. or dword->byte
  2231. Revision 1.100 2003/01/15 01:44:32 peter
  2232. * merged methodpointer fixes from 1.0.x
  2233. Revision 1.99 2003/01/09 21:43:39 peter
  2234. * constant string conversion fixed, it's now equal to both
  2235. shortstring, ansistring and the typeconvnode will return
  2236. te_equal but still return convtype to change the constnode
  2237. Revision 1.98 2003/01/05 22:41:40 peter
  2238. * move code that checks for longint-pointer conversion hint
  2239. Revision 1.97 2003/01/03 12:15:56 daniel
  2240. * Removed ifdefs around notifications
  2241. ifdefs around for loop optimizations remain
  2242. Revision 1.96 2002/12/22 16:34:49 peter
  2243. * proc-procvar crash fixed (tw2277)
  2244. Revision 1.95 2002/12/20 16:01:26 peter
  2245. * don't allow class(classref) conversion
  2246. Revision 1.94 2002/12/05 14:27:26 florian
  2247. * some variant <-> dyn. array stuff
  2248. Revision 1.93 2002/11/30 10:45:14 carl
  2249. * fix bug with checking of duplicated items in sets (new sets bug only)
  2250. Revision 1.92 2002/11/27 19:43:21 carl
  2251. * updated notes and hints
  2252. Revision 1.91 2002/11/27 13:11:38 peter
  2253. * more currency fixes, taddcurr runs now successfull
  2254. Revision 1.90 2002/11/27 11:29:21 peter
  2255. * when converting from and to currency divide or multiple the
  2256. result by 10000
  2257. Revision 1.89 2002/11/25 17:43:18 peter
  2258. * splitted defbase in defutil,symutil,defcmp
  2259. * merged isconvertable and is_equal into compare_defs(_ext)
  2260. * made operator search faster by walking the list only once
  2261. Revision 1.88 2002/11/17 16:31:56 carl
  2262. * memory optimization (3-4%) : cleanup of tai fields,
  2263. cleanup of tdef and tsym fields.
  2264. * make it work for m68k
  2265. Revision 1.87 2002/10/10 16:07:57 florian
  2266. + several widestring/pwidechar related stuff added
  2267. Revision 1.86 2002/10/06 16:10:23 florian
  2268. * when compiling <interface> as <interface> we can't assume
  2269. anything about relation
  2270. Revision 1.85 2002/10/05 12:43:25 carl
  2271. * fixes for Delphi 6 compilation
  2272. (warning : Some features do not work under Delphi)
  2273. Revision 1.84 2002/10/02 20:23:50 florian
  2274. - removed the relation check for <class> as <interface> because we don't
  2275. know the runtime type of <class>! It could be a child class of the given type
  2276. which implements additional interfaces
  2277. Revision 1.83 2002/10/02 20:17:14 florian
  2278. + the as operator for <class> as <interface> has to check the parent classes as well
  2279. Revision 1.82 2002/09/30 07:00:47 florian
  2280. * fixes to common code to get the alpha compiler compiled applied
  2281. Revision 1.81 2002/09/16 14:11:13 peter
  2282. * add argument to equal_paras() to support default values or not
  2283. Revision 1.80 2002/09/07 20:40:23 carl
  2284. * cardinal -> longword
  2285. Revision 1.79 2002/09/07 15:25:03 peter
  2286. * old logs removed and tabs fixed
  2287. Revision 1.78 2002/09/07 12:16:04 carl
  2288. * second part bug report 1996 fix, testrange in cordconstnode
  2289. only called if option is set (also make parsing a tiny faster)
  2290. Revision 1.77 2002/09/05 05:56:07 jonas
  2291. - reverted my last commit, it was completely bogus :(
  2292. Revision 1.75 2002/09/02 19:24:42 peter
  2293. * array of char support for Str()
  2294. Revision 1.74 2002/09/01 08:01:16 daniel
  2295. * Removed sets from Tcallnode.det_resulttype
  2296. + Added read/write notifications of variables. These will be usefull
  2297. for providing information for several optimizations. For example
  2298. the value of the loop variable of a for loop does matter is the
  2299. variable is read after the for loop, but if it's no longer used
  2300. or written, it doesn't matter and this can be used to optimize
  2301. the loop code generation.
  2302. Revision 1.73 2002/08/23 16:14:49 peter
  2303. * tempgen cleanup
  2304. * tt_noreuse temp type added that will be used in genentrycode
  2305. Revision 1.72 2002/08/20 18:23:33 jonas
  2306. * the as node again uses a compilerproc
  2307. + (untested) support for interface "as" statements
  2308. Revision 1.71 2002/08/19 19:36:43 peter
  2309. * More fixes for cross unit inlining, all tnodes are now implemented
  2310. * Moved pocall_internconst to po_internconst because it is not a
  2311. calling type at all and it conflicted when inlining of these small
  2312. functions was requested
  2313. Revision 1.70 2002/08/17 09:23:36 florian
  2314. * first part of current_procinfo rewrite
  2315. Revision 1.69 2002/08/14 19:26:55 carl
  2316. + generic int_to_real type conversion
  2317. + generic unaryminus node
  2318. Revision 1.68 2002/08/11 16:08:55 florian
  2319. + support of explicit type case boolean->char
  2320. Revision 1.67 2002/08/11 15:28:00 florian
  2321. + support of explicit type case <any ordinal type>->pointer
  2322. (delphi mode only)
  2323. Revision 1.66 2002/08/09 07:33:01 florian
  2324. * a couple of interface related fixes
  2325. Revision 1.65 2002/07/29 21:23:42 florian
  2326. * more fixes for the ppc
  2327. + wrappers for the tcnvnode.first_* stuff introduced
  2328. Revision 1.64 2002/07/23 12:34:30 daniel
  2329. * Readded old set code. To use it define 'oldset'. Activated by default
  2330. for ppc.
  2331. Revision 1.63 2002/07/23 09:51:22 daniel
  2332. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2333. are worth comitting.
  2334. Revision 1.62 2002/07/22 11:48:04 daniel
  2335. * Sets are now internally sets.
  2336. Revision 1.61 2002/07/20 17:16:02 florian
  2337. + source code page support
  2338. Revision 1.60 2002/07/20 11:57:54 florian
  2339. * types.pas renamed to defbase.pas because D6 contains a types
  2340. unit so this would conflicts if D6 programms are compiled
  2341. + Willamette/SSE2 instructions to assembler added
  2342. Revision 1.59 2002/07/01 16:23:53 peter
  2343. * cg64 patch
  2344. * basics for currency
  2345. * asnode updates for class and interface (not finished)
  2346. Revision 1.58 2002/05/18 13:34:09 peter
  2347. * readded missing revisions
  2348. }