tccnv.pas 38 KB

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