tccnv.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. {$ifdef TP}
  19. {$E+,F+,N+,D+,L+,Y+}
  20. {$endif}
  21. unit tccnv;
  22. interface
  23. uses
  24. tree;
  25. procedure arrayconstructor_to_set(var p:ptree);
  26. procedure firsttypeconv(var p : ptree);
  27. procedure firstas(var p : ptree);
  28. procedure firstis(var p : ptree);
  29. implementation
  30. uses
  31. globtype,systems,tokens,
  32. cobjects,verbose,globals,
  33. symconst,symtable,aasm,types,
  34. {$ifdef newcg}
  35. cgbase,
  36. {$else newcg}
  37. hcodegen,
  38. {$endif newcg}
  39. htypechk,pass_1,cpubase;
  40. {*****************************************************************************
  41. Array constructor to Set Conversion
  42. *****************************************************************************}
  43. procedure arrayconstructor_to_set(var p:ptree);
  44. var
  45. constp,
  46. buildp,
  47. p2,p3,p4 : ptree;
  48. pd : pdef;
  49. constset : pconstset;
  50. constsetlo,
  51. constsethi : longint;
  52. procedure update_constsethi(p:pdef);
  53. begin
  54. if ((p^.deftype=orddef) and
  55. (porddef(p)^.high>constsethi)) then
  56. begin
  57. constsethi:=porddef(p)^.high;
  58. if pd=nil then
  59. begin
  60. if (constsethi>255) or
  61. (porddef(p)^.low<0) then
  62. pd:=u8bitdef
  63. else
  64. pd:=p;
  65. end;
  66. if constsethi>255 then
  67. constsethi:=255;
  68. end
  69. else if ((p^.deftype=enumdef) and
  70. (penumdef(p)^.max>constsethi)) then
  71. begin
  72. if pd=nil then
  73. pd:=p;
  74. constsethi:=penumdef(p)^.max;
  75. end;
  76. end;
  77. procedure do_set(pos : longint);
  78. var
  79. mask,l : longint;
  80. begin
  81. if (pos>255) or (pos<0) then
  82. Message(parser_e_illegal_set_expr);
  83. if pos>constsethi then
  84. constsethi:=pos;
  85. if pos<constsetlo then
  86. constsetlo:=pos;
  87. l:=pos shr 3;
  88. mask:=1 shl (pos mod 8);
  89. { do we allow the same twice }
  90. if (constset^[l] and mask)<>0 then
  91. Message(parser_e_illegal_set_expr);
  92. constset^[l]:=constset^[l] or mask;
  93. end;
  94. var
  95. l : longint;
  96. lr,hr : longint;
  97. begin
  98. new(constset);
  99. FillChar(constset^,sizeof(constset^),0);
  100. pd:=nil;
  101. constsetlo:=0;
  102. constsethi:=0;
  103. constp:=gensinglenode(setconstn,nil);
  104. constp^.value_set:=constset;
  105. buildp:=constp;
  106. if assigned(p^.left) then
  107. begin
  108. while assigned(p) do
  109. begin
  110. p4:=nil; { will contain the tree to create the set }
  111. { split a range into p2 and p3 }
  112. if p^.left^.treetype=arrayconstructrangen then
  113. begin
  114. p2:=p^.left^.left;
  115. p3:=p^.left^.right;
  116. { node is not used anymore }
  117. putnode(p^.left);
  118. end
  119. else
  120. begin
  121. p2:=p^.left;
  122. p3:=nil;
  123. end;
  124. firstpass(p2);
  125. if assigned(p3) then
  126. firstpass(p3);
  127. if codegenerror then
  128. break;
  129. case p2^.resulttype^.deftype of
  130. enumdef,
  131. orddef:
  132. begin
  133. getrange(p2^.resulttype,lr,hr);
  134. if assigned(p3) then
  135. begin
  136. { this isn't good, you'll get problems with
  137. type t010 = 0..10;
  138. ts = set of t010;
  139. var s : ts;b : t010
  140. begin s:=[1,2,b]; end.
  141. if is_integer(p3^.resulttype) then
  142. begin
  143. p3:=gentypeconvnode(p3,u8bitdef);
  144. firstpass(p3);
  145. end;
  146. }
  147. if assigned(pd) and not(is_equal(pd,p3^.resulttype)) then
  148. begin
  149. aktfilepos:=p3^.fileinfo;
  150. CGMessage(type_e_typeconflict_in_set);
  151. end
  152. else
  153. begin
  154. if (p2^.treetype=ordconstn) and (p3^.treetype=ordconstn) then
  155. begin
  156. if not(is_integer(p3^.resulttype)) then
  157. pd:=p3^.resulttype
  158. else
  159. begin
  160. p3:=gentypeconvnode(p3,u8bitdef);
  161. p2:=gentypeconvnode(p2,u8bitdef);
  162. firstpass(p2);
  163. firstpass(p3);
  164. end;
  165. for l:=p2^.value to p3^.value do
  166. do_set(l);
  167. disposetree(p3);
  168. disposetree(p2);
  169. end
  170. else
  171. begin
  172. update_constsethi(p2^.resulttype);
  173. p2:=gentypeconvnode(p2,pd);
  174. firstpass(p2);
  175. update_constsethi(p3^.resulttype);
  176. p3:=gentypeconvnode(p3,pd);
  177. firstpass(p3);
  178. if assigned(pd) then
  179. p3:=gentypeconvnode(p3,pd)
  180. else
  181. p3:=gentypeconvnode(p3,u8bitdef);
  182. firstpass(p3);
  183. p4:=gennode(setelementn,p2,p3);
  184. end;
  185. end;
  186. end
  187. else
  188. begin
  189. { Single value }
  190. if p2^.treetype=ordconstn then
  191. begin
  192. if not(is_integer(p2^.resulttype)) then
  193. update_constsethi(p2^.resulttype)
  194. else
  195. begin
  196. p2:=gentypeconvnode(p2,u8bitdef);
  197. firstpass(p2);
  198. end;
  199. do_set(p2^.value);
  200. disposetree(p2);
  201. end
  202. else
  203. begin
  204. update_constsethi(p2^.resulttype);
  205. if assigned(pd) then
  206. p2:=gentypeconvnode(p2,pd)
  207. else
  208. p2:=gentypeconvnode(p2,u8bitdef);
  209. firstpass(p2);
  210. p4:=gennode(setelementn,p2,nil);
  211. end;
  212. end;
  213. end;
  214. stringdef : begin
  215. { if we've already set elements which are constants }
  216. { throw an error }
  217. if ((pd=nil) and assigned(buildp)) or
  218. not(is_equal(pd,cchardef)) then
  219. CGMessage(type_e_typeconflict_in_set)
  220. else
  221. for l:=1 to length(pstring(p2^.value_str)^) do
  222. do_set(ord(pstring(p2^.value_str)^[l]));
  223. if pd=nil then
  224. pd:=cchardef;
  225. disposetree(p2);
  226. end;
  227. else
  228. CGMessage(type_e_ordinal_expr_expected);
  229. end;
  230. { insert the set creation tree }
  231. if assigned(p4) then
  232. buildp:=gennode(addn,buildp,p4);
  233. { load next and dispose current node }
  234. p2:=p;
  235. p:=p^.right;
  236. putnode(p2);
  237. end;
  238. if (pd=nil) then
  239. begin
  240. pd:=u8bitdef;
  241. constsethi:=255;
  242. end;
  243. end
  244. else
  245. begin
  246. { empty set [], only remove node }
  247. putnode(p);
  248. end;
  249. { set the initial set type }
  250. constp^.resulttype:=new(psetdef,init(pd,constsethi));
  251. { set the new tree }
  252. p:=buildp;
  253. end;
  254. {*****************************************************************************
  255. FirstTypeConv
  256. *****************************************************************************}
  257. type
  258. tfirstconvproc = procedure(var p : ptree);
  259. procedure first_int_to_int(var p : ptree);
  260. begin
  261. if (p^.left^.location.loc<>LOC_REGISTER) and
  262. (p^.resulttype^.size>p^.left^.resulttype^.size) then
  263. p^.location.loc:=LOC_REGISTER;
  264. if is_64bitint(p^.resulttype) then
  265. p^.registers32:=max(p^.registers32,2)
  266. else
  267. p^.registers32:=max(p^.registers32,1);
  268. end;
  269. procedure first_cstring_to_pchar(var p : ptree);
  270. begin
  271. p^.registers32:=1;
  272. p^.location.loc:=LOC_REGISTER;
  273. end;
  274. procedure first_string_to_chararray(var p : ptree);
  275. begin
  276. p^.registers32:=1;
  277. p^.location.loc:=LOC_REGISTER;
  278. end;
  279. procedure first_string_to_string(var p : ptree);
  280. var
  281. hp : ptree;
  282. begin
  283. if pstringdef(p^.resulttype)^.string_typ<>
  284. pstringdef(p^.left^.resulttype)^.string_typ then
  285. begin
  286. if p^.left^.treetype=stringconstn then
  287. begin
  288. p^.left^.stringtype:=pstringdef(p^.resulttype)^.string_typ;
  289. p^.left^.resulttype:=p^.resulttype;
  290. { remove typeconv node }
  291. hp:=p;
  292. p:=p^.left;
  293. putnode(hp);
  294. exit;
  295. end
  296. else
  297. procinfo^.flags:=procinfo^.flags or pi_do_call;
  298. end;
  299. { for simplicity lets first keep all ansistrings
  300. as LOC_MEM, could also become LOC_REGISTER }
  301. if pstringdef(p^.resulttype)^.string_typ in [st_ansistring,st_widestring] then
  302. { we may use ansistrings so no fast exit here }
  303. procinfo^.no_fast_exit:=true;
  304. p^.location.loc:=LOC_MEM;
  305. end;
  306. procedure first_char_to_string(var p : ptree);
  307. var
  308. hp : ptree;
  309. begin
  310. if p^.left^.treetype=ordconstn then
  311. begin
  312. hp:=genstringconstnode(chr(p^.left^.value),st_default);
  313. hp^.stringtype:=pstringdef(p^.resulttype)^.string_typ;
  314. firstpass(hp);
  315. disposetree(p);
  316. p:=hp;
  317. end
  318. else
  319. p^.location.loc:=LOC_MEM;
  320. end;
  321. procedure first_nothing(var p : ptree);
  322. begin
  323. p^.location.loc:=LOC_MEM;
  324. end;
  325. procedure first_array_to_pointer(var p : ptree);
  326. begin
  327. if p^.registers32<1 then
  328. p^.registers32:=1;
  329. p^.location.loc:=LOC_REGISTER;
  330. end;
  331. procedure first_int_to_real(var p : ptree);
  332. var
  333. t : ptree;
  334. begin
  335. if p^.left^.treetype=ordconstn then
  336. begin
  337. t:=genrealconstnode(p^.left^.value,pfloatdef(p^.resulttype));
  338. firstpass(t);
  339. disposetree(p);
  340. p:=t;
  341. exit;
  342. end;
  343. if p^.registersfpu<1 then
  344. p^.registersfpu:=1;
  345. p^.location.loc:=LOC_FPU;
  346. end;
  347. procedure first_int_to_fix(var p : ptree);
  348. var
  349. t : ptree;
  350. begin
  351. if p^.left^.treetype=ordconstn then
  352. begin
  353. t:=genfixconstnode(p^.left^.value shl 16,p^.resulttype);
  354. firstpass(t);
  355. disposetree(p);
  356. p:=t;
  357. exit;
  358. end;
  359. if p^.registers32<1 then
  360. p^.registers32:=1;
  361. p^.location.loc:=LOC_REGISTER;
  362. end;
  363. procedure first_real_to_fix(var p : ptree);
  364. var
  365. t : ptree;
  366. begin
  367. if p^.left^.treetype=fixconstn then
  368. begin
  369. t:=genfixconstnode(round(p^.left^.value_real*65536),p^.resulttype);
  370. firstpass(t);
  371. disposetree(p);
  372. p:=t;
  373. exit;
  374. end;
  375. { at least one fpu and int register needed }
  376. if p^.registers32<1 then
  377. p^.registers32:=1;
  378. if p^.registersfpu<1 then
  379. p^.registersfpu:=1;
  380. p^.location.loc:=LOC_REGISTER;
  381. end;
  382. procedure first_fix_to_real(var p : ptree);
  383. var
  384. t : ptree;
  385. begin
  386. if p^.left^.treetype=fixconstn then
  387. begin
  388. t:=genrealconstnode(round(p^.left^.value_fix/65536.0),p^.resulttype);
  389. firstpass(t);
  390. disposetree(p);
  391. p:=t;
  392. exit;
  393. end;
  394. if p^.registersfpu<1 then
  395. p^.registersfpu:=1;
  396. p^.location.loc:=LOC_FPU;
  397. end;
  398. procedure first_real_to_real(var p : ptree);
  399. var
  400. t : ptree;
  401. begin
  402. if p^.left^.treetype=realconstn then
  403. begin
  404. t:=genrealconstnode(p^.left^.value_real,p^.resulttype);
  405. firstpass(t);
  406. disposetree(p);
  407. p:=t;
  408. exit;
  409. end;
  410. { comp isn't a floating type }
  411. {$ifdef i386}
  412. if (pfloatdef(p^.resulttype)^.typ=s64comp) and
  413. (pfloatdef(p^.left^.resulttype)^.typ<>s64comp) and
  414. not (p^.explizit) then
  415. CGMessage(type_w_convert_real_2_comp);
  416. {$endif}
  417. if p^.registersfpu<1 then
  418. p^.registersfpu:=1;
  419. p^.location.loc:=LOC_FPU;
  420. end;
  421. procedure first_pointer_to_array(var p : ptree);
  422. begin
  423. if p^.registers32<1 then
  424. p^.registers32:=1;
  425. p^.location.loc:=LOC_REFERENCE;
  426. end;
  427. procedure first_chararray_to_string(var p : ptree);
  428. begin
  429. { the only important information is the location of the }
  430. { result }
  431. { other stuff is done by firsttypeconv }
  432. p^.location.loc:=LOC_MEM;
  433. end;
  434. procedure first_cchar_to_pchar(var p : ptree);
  435. begin
  436. p^.left:=gentypeconvnode(p^.left,cshortstringdef);
  437. { convert constant char to constant string }
  438. firstpass(p^.left);
  439. { evalute tree }
  440. firstpass(p);
  441. end;
  442. procedure first_bool_to_int(var p : ptree);
  443. begin
  444. { byte(boolean) or word(wordbool) or longint(longbool) must
  445. be accepted for var parameters }
  446. if (p^.explizit) and
  447. (p^.left^.resulttype^.size=p^.resulttype^.size) and
  448. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  449. exit;
  450. p^.location.loc:=LOC_REGISTER;
  451. if p^.registers32<1 then
  452. p^.registers32:=1;
  453. end;
  454. procedure first_int_to_bool(var p : ptree);
  455. begin
  456. { byte(boolean) or word(wordbool) or longint(longbool) must
  457. be accepted for var parameters }
  458. if (p^.explizit) and
  459. (p^.left^.resulttype^.size=p^.resulttype^.size) and
  460. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  461. exit;
  462. p^.location.loc:=LOC_REGISTER;
  463. { need if bool to bool !!
  464. not very nice !!
  465. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  466. p^.left^.explizit:=true;
  467. firstpass(p^.left); }
  468. if p^.registers32<1 then
  469. p^.registers32:=1;
  470. end;
  471. procedure first_bool_to_bool(var p : ptree);
  472. begin
  473. p^.location.loc:=LOC_REGISTER;
  474. if p^.registers32<1 then
  475. p^.registers32:=1;
  476. end;
  477. procedure first_proc_to_procvar(var p : ptree);
  478. begin
  479. { hmmm, I'am not sure if that is necessary (FK) }
  480. firstpass(p^.left);
  481. if codegenerror then
  482. exit;
  483. if (p^.left^.location.loc<>LOC_REFERENCE) then
  484. CGMessage(cg_e_illegal_expression);
  485. p^.registers32:=p^.left^.registers32;
  486. if p^.registers32<1 then
  487. p^.registers32:=1;
  488. p^.location.loc:=LOC_REGISTER;
  489. end;
  490. procedure first_load_smallset(var p : ptree);
  491. begin
  492. end;
  493. procedure first_cord_to_pointer(var p : ptree);
  494. var
  495. t : ptree;
  496. begin
  497. if p^.left^.treetype=ordconstn then
  498. begin
  499. t:=genpointerconstnode(p^.left^.value,p^.resulttype);
  500. firstpass(t);
  501. disposetree(p);
  502. p:=t;
  503. exit;
  504. end
  505. else
  506. internalerror(432472389);
  507. end;
  508. procedure first_pchar_to_string(var p : ptree);
  509. begin
  510. p^.location.loc:=LOC_REFERENCE;
  511. end;
  512. procedure first_ansistring_to_pchar(var p : ptree);
  513. begin
  514. p^.location.loc:=LOC_REGISTER;
  515. if p^.registers32<1 then
  516. p^.registers32:=1;
  517. end;
  518. procedure first_arrayconstructor_to_set(var p:ptree);
  519. var
  520. hp : ptree;
  521. begin
  522. if p^.left^.treetype<>arrayconstructn then
  523. internalerror(5546);
  524. { remove typeconv node }
  525. hp:=p;
  526. p:=p^.left;
  527. putnode(hp);
  528. { create a set constructor tree }
  529. arrayconstructor_to_set(p);
  530. { now firstpass the set }
  531. firstpass(p);
  532. end;
  533. procedure firsttypeconv(var p : ptree);
  534. var
  535. hp : ptree;
  536. aprocdef : pprocdef;
  537. const
  538. firstconvert : array[tconverttype] of tfirstconvproc = (
  539. first_nothing, {equal}
  540. first_nothing, {not_possible}
  541. first_string_to_string,
  542. first_char_to_string,
  543. first_pchar_to_string,
  544. first_cchar_to_pchar,
  545. first_cstring_to_pchar,
  546. first_ansistring_to_pchar,
  547. first_string_to_chararray,
  548. first_chararray_to_string,
  549. first_array_to_pointer,
  550. first_pointer_to_array,
  551. first_int_to_int,
  552. first_int_to_bool,
  553. first_bool_to_bool,
  554. first_bool_to_int,
  555. first_real_to_real,
  556. first_int_to_real,
  557. first_int_to_fix,
  558. first_real_to_fix,
  559. first_fix_to_real,
  560. first_proc_to_procvar,
  561. first_arrayconstructor_to_set,
  562. first_load_smallset,
  563. first_cord_to_pointer
  564. );
  565. begin
  566. aprocdef:=nil;
  567. { if explicite type cast, then run firstpass }
  568. if (p^.explizit) or not assigned(p^.left^.resulttype) then
  569. firstpass(p^.left);
  570. if (p^.left^.treetype=typen) and (p^.left^.resulttype=generrordef) then
  571. begin
  572. codegenerror:=true;
  573. Message(parser_e_no_type_not_allowed_here);
  574. end;
  575. if codegenerror then
  576. begin
  577. p^.resulttype:=generrordef;
  578. exit;
  579. end;
  580. if not assigned(p^.left^.resulttype) then
  581. begin
  582. codegenerror:=true;
  583. internalerror(52349);
  584. exit;
  585. end;
  586. { load the value_str from the left part }
  587. p^.registers32:=p^.left^.registers32;
  588. p^.registersfpu:=p^.left^.registersfpu;
  589. {$ifdef SUPPORT_MMX}
  590. p^.registersmmx:=p^.left^.registersmmx;
  591. {$endif}
  592. set_location(p^.location,p^.left^.location);
  593. { remove obsolete type conversions }
  594. if is_equal(p^.left^.resulttype,p^.resulttype) then
  595. begin
  596. { becuase is_equal only checks the basetype for sets we need to
  597. check here if we are loading a smallset into a normalset }
  598. if (p^.resulttype^.deftype=setdef) and
  599. (p^.left^.resulttype^.deftype=setdef) and
  600. (psetdef(p^.resulttype)^.settype<>smallset) and
  601. (psetdef(p^.left^.resulttype)^.settype=smallset) then
  602. begin
  603. { try to define the set as a normalset if it's a constant set }
  604. if p^.left^.treetype=setconstn then
  605. begin
  606. p^.resulttype:=p^.left^.resulttype;
  607. psetdef(p^.resulttype)^.settype:=normset
  608. end
  609. else
  610. p^.convtyp:=tc_load_smallset;
  611. exit;
  612. end
  613. else
  614. begin
  615. hp:=p;
  616. p:=p^.left;
  617. p^.resulttype:=hp^.resulttype;
  618. putnode(hp);
  619. exit;
  620. end;
  621. end;
  622. aprocdef:=assignment_overloaded(p^.left^.resulttype,p^.resulttype);
  623. if assigned(aprocdef) then
  624. begin
  625. procinfo^.flags:=procinfo^.flags or pi_do_call;
  626. hp:=gencallnode(overloaded_operators[_assignment],nil);
  627. { tell explicitly which def we must use !! (PM) }
  628. hp^.procdefinition:=aprocdef;
  629. hp^.left:=gencallparanode(p^.left,nil);
  630. putnode(p);
  631. p:=hp;
  632. firstpass(p);
  633. exit;
  634. end;
  635. if isconvertable(p^.left^.resulttype,p^.resulttype,p^.convtyp,p^.left^.treetype,p^.explizit)=0 then
  636. begin
  637. {Procedures have a resulttype of voiddef and functions of their
  638. own resulttype. They will therefore always be incompatible with
  639. a procvar. Because isconvertable cannot check for procedures we
  640. use an extra check for them.}
  641. if (m_tp_procvar in aktmodeswitches) then
  642. begin
  643. if (p^.resulttype^.deftype=procvardef) and
  644. (is_procsym_load(p^.left) or is_procsym_call(p^.left)) then
  645. begin
  646. if is_procsym_call(p^.left) then
  647. begin
  648. {if p^.left^.right=nil then
  649. begin}
  650. if (p^.left^.symtableprocentry^.owner^.symtabletype=objectsymtable){ and
  651. (pobjectdef(p^.left^.symtableprocentry^.owner^.defowner)^.is_class) }then
  652. hp:=genloadmethodcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc,
  653. getcopy(p^.left^.methodpointer))
  654. else
  655. hp:=genloadcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc);
  656. disposetree(p^.left);
  657. firstpass(hp);
  658. p^.left:=hp;
  659. aprocdef:=pprocdef(p^.left^.resulttype);
  660. (* end
  661. else
  662. begin
  663. p^.left^.right^.treetype:=loadn;
  664. p^.left^.right^.symtableentry:=p^.left^.right^.symtableentry;
  665. P^.left^.right^.resulttype:=pvarsym(p^.left^.symtableentry)^.definition;
  666. hp:=p^.left^.right;
  667. putnode(p^.left);
  668. p^.left:=hp;
  669. { should we do that ? }
  670. firstpass(p^.left);
  671. if not is_equal(p^.left^.resulttype,p^.resulttype) then
  672. begin
  673. CGMessage(type_e_mismatch);
  674. exit;
  675. end
  676. else
  677. begin
  678. hp:=p;
  679. p:=p^.left;
  680. p^.resulttype:=hp^.resulttype;
  681. putnode(hp);
  682. exit;
  683. end;
  684. end; *)
  685. end
  686. else
  687. begin
  688. if (p^.left^.treetype<>addrn) then
  689. aprocdef:=pprocsym(p^.left^.symtableentry)^.definition;
  690. end;
  691. p^.convtyp:=tc_proc_2_procvar;
  692. { Now check if the procedure we are going to assign to
  693. the procvar, is compatible with the procvar's type }
  694. if assigned(aprocdef) then
  695. begin
  696. if not proc_to_procvar_equal(aprocdef,pprocvardef(p^.resulttype)) then
  697. CGMessage2(type_e_incompatible_types,aprocdef^.typename,p^.resulttype^.typename);
  698. firstconvert[p^.convtyp](p);
  699. end
  700. else
  701. CGMessage2(type_e_incompatible_types,p^.left^.resulttype^.typename,p^.resulttype^.typename);
  702. exit;
  703. end;
  704. end;
  705. if p^.explizit then
  706. begin
  707. { check if the result could be in a register }
  708. if not(p^.resulttype^.is_intregable) and
  709. not(p^.resulttype^.is_fpuregable) then
  710. make_not_regable(p^.left);
  711. { boolean to byte are special because the
  712. location can be different }
  713. if is_integer(p^.resulttype) and
  714. is_boolean(p^.left^.resulttype) then
  715. begin
  716. p^.convtyp:=tc_bool_2_int;
  717. firstconvert[p^.convtyp](p);
  718. exit;
  719. end;
  720. { ansistring to pchar }
  721. if is_pchar(p^.resulttype) and
  722. is_ansistring(p^.left^.resulttype) then
  723. begin
  724. p^.convtyp:=tc_ansistring_2_pchar;
  725. firstconvert[p^.convtyp](p);
  726. exit;
  727. end;
  728. { do common tc_equal cast }
  729. p^.convtyp:=tc_equal;
  730. { enum to ordinal will always be s32bit }
  731. if (p^.left^.resulttype^.deftype=enumdef) and
  732. is_ordinal(p^.resulttype) then
  733. begin
  734. if p^.left^.treetype=ordconstn then
  735. begin
  736. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  737. disposetree(p);
  738. firstpass(hp);
  739. p:=hp;
  740. exit;
  741. end
  742. else
  743. begin
  744. if isconvertable(s32bitdef,p^.resulttype,p^.convtyp,ordconstn,false)=0 then
  745. CGMessage(cg_e_illegal_type_conversion);
  746. end;
  747. end
  748. { ordinal to enumeration }
  749. else
  750. if (p^.resulttype^.deftype=enumdef) and
  751. is_ordinal(p^.left^.resulttype) then
  752. begin
  753. if p^.left^.treetype=ordconstn then
  754. begin
  755. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  756. disposetree(p);
  757. firstpass(hp);
  758. p:=hp;
  759. exit;
  760. end
  761. else
  762. begin
  763. if IsConvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn,false)=0 then
  764. CGMessage(cg_e_illegal_type_conversion);
  765. end;
  766. end
  767. { nil to ordinal node }
  768. else if is_ordinal(p^.resulttype) and
  769. (p^.left^.treetype=niln) then
  770. begin
  771. hp:=genordinalconstnode(0,p^.resulttype);
  772. firstpass(hp);
  773. disposetree(p);
  774. p:=hp;
  775. exit;
  776. end
  777. {Are we typecasting an ordconst to a char?}
  778. else
  779. if is_char(p^.resulttype) and
  780. is_ordinal(p^.left^.resulttype) then
  781. begin
  782. if p^.left^.treetype=ordconstn then
  783. begin
  784. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  785. firstpass(hp);
  786. disposetree(p);
  787. p:=hp;
  788. exit;
  789. end
  790. else
  791. begin
  792. { this is wrong because it converts to a 4 byte long var !!
  793. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn nur Dummy ) then }
  794. if IsConvertable(p^.left^.resulttype,u8bitdef,p^.convtyp,ordconstn,false)=0 then
  795. CGMessage(cg_e_illegal_type_conversion);
  796. end;
  797. end
  798. { only if the same size or formal def }
  799. { why do we allow typecasting of voiddef ?? (PM) }
  800. else
  801. begin
  802. if not(
  803. (p^.left^.resulttype^.deftype=formaldef) or
  804. (p^.left^.resulttype^.size=p^.resulttype^.size) or
  805. (is_equal(p^.left^.resulttype,voiddef) and
  806. (p^.left^.treetype=derefn))
  807. ) then
  808. CGMessage(cg_e_illegal_type_conversion);
  809. if ((p^.left^.resulttype^.deftype=orddef) and
  810. (p^.resulttype^.deftype=pointerdef)) or
  811. ((p^.resulttype^.deftype=orddef) and
  812. (p^.left^.resulttype^.deftype=pointerdef))
  813. {$ifdef extdebug}and (p^.firstpasscount=0){$endif} then
  814. CGMessage(cg_d_pointer_to_longint_conv_not_portable);
  815. end;
  816. { the conversion into a strutured type is only }
  817. { possible, if the source is no register }
  818. if ((p^.resulttype^.deftype in [recorddef,stringdef,arraydef]) or
  819. ((p^.resulttype^.deftype=objectdef) and not(pobjectdef(p^.resulttype)^.is_class))
  820. ) and (p^.left^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
  821. it also works if the assignment is overloaded
  822. YES but this code is not executed if assignment is overloaded (PM)
  823. not assigned(assignment_overloaded(p^.left^.resulttype,p^.resulttype))} then
  824. CGMessage(cg_e_illegal_type_conversion);
  825. end
  826. else
  827. CGMessage2(type_e_incompatible_types,p^.left^.resulttype^.typename,p^.resulttype^.typename);
  828. end;
  829. { tp7 procvar support, when right is not a procvardef and we got a
  830. loadn of a procvar then convert to a calln, the check for the
  831. result is already done in is_convertible, also no conflict with
  832. @procvar is here because that has an extra addrn }
  833. if (m_tp_procvar in aktmodeswitches) and
  834. (p^.resulttype^.deftype<>procvardef) and
  835. (p^.left^.resulttype^.deftype=procvardef) and
  836. (p^.left^.treetype=loadn) then
  837. begin
  838. hp:=gencallnode(nil,nil);
  839. hp^.right:=p^.left;
  840. firstpass(hp);
  841. p^.left:=hp;
  842. end;
  843. { ordinal contants can be directly converted }
  844. { but not int64/qword }
  845. if (p^.left^.treetype=ordconstn) and is_ordinal(p^.resulttype) and
  846. not(is_64bitint(p^.resulttype)) then
  847. begin
  848. { range checking is done in genordinalconstnode (PFV) }
  849. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  850. disposetree(p);
  851. firstpass(hp);
  852. p:=hp;
  853. exit;
  854. end;
  855. if p^.convtyp<>tc_equal then
  856. firstconvert[p^.convtyp](p);
  857. end;
  858. {*****************************************************************************
  859. FirstIs
  860. *****************************************************************************}
  861. procedure firstis(var p : ptree);
  862. begin
  863. firstpass(p^.left);
  864. set_varstate(p^.left,true);
  865. firstpass(p^.right);
  866. set_varstate(p^.right,true);
  867. if codegenerror then
  868. exit;
  869. if (p^.right^.resulttype^.deftype<>classrefdef) then
  870. CGMessage(type_e_mismatch);
  871. left_right_max(p);
  872. { left must be a class }
  873. if (p^.left^.resulttype^.deftype<>objectdef) or
  874. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  875. CGMessage(type_e_mismatch);
  876. { the operands must be related }
  877. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  878. pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)))) and
  879. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)^.is_related(
  880. pobjectdef(p^.left^.resulttype)))) then
  881. CGMessage(type_e_mismatch);
  882. p^.location.loc:=LOC_FLAGS;
  883. p^.resulttype:=booldef;
  884. end;
  885. {*****************************************************************************
  886. FirstAs
  887. *****************************************************************************}
  888. procedure firstas(var p : ptree);
  889. begin
  890. firstpass(p^.right);
  891. set_varstate(p^.right,true);
  892. firstpass(p^.left);
  893. set_varstate(p^.left,true);
  894. if codegenerror then
  895. exit;
  896. if (p^.right^.resulttype^.deftype<>classrefdef) then
  897. CGMessage(type_e_mismatch);
  898. left_right_max(p);
  899. { left must be a class }
  900. if (p^.left^.resulttype^.deftype<>objectdef) or
  901. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  902. CGMessage(type_e_mismatch);
  903. { the operands must be related }
  904. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  905. pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)))) and
  906. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)^.is_related(
  907. pobjectdef(p^.left^.resulttype)))) then
  908. CGMessage(type_e_mismatch);
  909. set_location(p^.location,p^.left^.location);
  910. p^.resulttype:=pclassrefdef(p^.right^.resulttype)^.pointertype.def;
  911. end;
  912. end.
  913. {
  914. $Log$
  915. Revision 1.61 2000-02-14 18:12:50 florian
  916. * fixed set problem s:=[<word>];
  917. Revision 1.60 2000/02/13 22:46:28 florian
  918. * fixed an internalerror with writeln
  919. * fixed arrayconstructor_to_set to force the generation of better code
  920. and added a more strict type checking
  921. Revision 1.59 2000/02/09 13:23:07 peter
  922. * log truncated
  923. Revision 1.58 2000/01/09 23:16:07 peter
  924. * added st_default stringtype
  925. * genstringconstnode extended with stringtype parameter using st_default
  926. will do the old behaviour
  927. Revision 1.57 2000/01/07 01:14:44 peter
  928. * updated copyright to 2000
  929. Revision 1.56 1999/12/19 12:08:27 florian
  930. * bug reported by Alex S. fixed: it wasn't possible to type cast nil in const
  931. declarations: const l = longint(nil);
  932. Revision 1.55 1999/12/09 23:18:04 pierre
  933. * no_fast_exit if procedure contains implicit termination code
  934. Revision 1.54 1999/11/30 10:40:57 peter
  935. + ttype, tsymlist
  936. Revision 1.53 1999/11/18 15:34:49 pierre
  937. * Notes/Hints for local syms changed to
  938. Set_varstate function
  939. Revision 1.52 1999/11/06 14:34:29 peter
  940. * truncated log to 20 revs
  941. Revision 1.51 1999/11/05 13:15:00 florian
  942. * some fixes to get the new cg compiling again
  943. Revision 1.50 1999/09/27 23:45:00 peter
  944. * procinfo is now a pointer
  945. * support for result setting in sub procedure
  946. Revision 1.49 1999/09/26 21:30:22 peter
  947. + constant pointer support which can happend with typecasting like
  948. const p=pointer(1)
  949. * better procvar parsing in typed consts
  950. Revision 1.48 1999/09/17 17:14:12 peter
  951. * @procvar fixes for tp mode
  952. * @<id>:= gives now an error
  953. Revision 1.47 1999/09/11 09:08:34 florian
  954. * fixed bug 596
  955. * fixed some problems with procedure variables and procedures of object,
  956. especially in TP mode. Procedure of object doesn't apply only to classes,
  957. it is also allowed for objects !!
  958. Revision 1.46 1999/08/13 15:43:59 peter
  959. * fixed proc->procvar conversion for tp_procvar mode, it now uses
  960. also the genload(method)call() function
  961. Revision 1.45 1999/08/07 14:21:04 florian
  962. * some small problems fixed
  963. Revision 1.44 1999/08/04 13:03:14 jonas
  964. * all tokens now start with an underscore
  965. * PowerPC compiles!!
  966. Revision 1.43 1999/08/04 00:23:36 florian
  967. * renamed i386asm and i386base to cpuasm and cpubase
  968. Revision 1.42 1999/08/03 22:03:28 peter
  969. * moved bitmask constants to sets
  970. * some other type/const renamings
  971. }