tccnv.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  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_pchar_to_string(var p : ptree);
  444. begin
  445. p^.location.loc:=LOC_REFERENCE;
  446. end;
  447. procedure first_ansistring_to_pchar(var p : ptree);
  448. begin
  449. p^.location.loc:=LOC_REGISTER;
  450. if p^.registers32<1 then
  451. p^.registers32:=1;
  452. end;
  453. procedure first_arrayconstructor_to_set(var p:ptree);
  454. var
  455. hp : ptree;
  456. begin
  457. if p^.left^.treetype<>arrayconstructn then
  458. internalerror(5546);
  459. { remove typeconv node }
  460. hp:=p;
  461. p:=p^.left;
  462. putnode(hp);
  463. { create a set constructor tree }
  464. arrayconstructor_to_set(p);
  465. { now firstpass the set }
  466. firstpass(p);
  467. end;
  468. procedure firsttypeconv(var p : ptree);
  469. var
  470. hp : ptree;
  471. aprocdef : pprocdef;
  472. const
  473. firstconvert : array[tconverttype] of tfirstconvproc = (
  474. first_nothing, {equal}
  475. first_nothing, {not_possible}
  476. first_string_to_string,
  477. first_char_to_string,
  478. first_pchar_to_string,
  479. first_cchar_to_pchar,
  480. first_cstring_to_pchar,
  481. first_ansistring_to_pchar,
  482. first_string_to_chararray,
  483. first_chararray_to_string,
  484. first_array_to_pointer,
  485. first_pointer_to_array,
  486. first_int_to_int,
  487. first_int_to_bool,
  488. first_bool_to_bool,
  489. first_bool_to_int,
  490. first_real_to_real,
  491. first_int_to_real,
  492. first_int_to_fix,
  493. first_real_to_fix,
  494. first_fix_to_real,
  495. first_proc_to_procvar,
  496. first_arrayconstructor_to_set,
  497. first_load_smallset
  498. );
  499. begin
  500. aprocdef:=nil;
  501. { if explicite type cast, then run firstpass }
  502. if p^.explizit then
  503. firstpass(p^.left);
  504. if (p^.left^.treetype=typen) and (p^.left^.resulttype=generrordef) then
  505. begin
  506. codegenerror:=true;
  507. Message(parser_e_no_type_not_allowed_here);
  508. end;
  509. if codegenerror then
  510. begin
  511. p^.resulttype:=generrordef;
  512. exit;
  513. end;
  514. if not assigned(p^.left^.resulttype) then
  515. begin
  516. codegenerror:=true;
  517. internalerror(52349);
  518. exit;
  519. end;
  520. { load the value_str from the left part }
  521. p^.registers32:=p^.left^.registers32;
  522. p^.registersfpu:=p^.left^.registersfpu;
  523. {$ifdef SUPPORT_MMX}
  524. p^.registersmmx:=p^.left^.registersmmx;
  525. {$endif}
  526. set_location(p^.location,p^.left^.location);
  527. { remove obsolete type conversions }
  528. if is_equal(p^.left^.resulttype,p^.resulttype) then
  529. begin
  530. { becuase is_equal only checks the basetype for sets we need to
  531. check here if we are loading a smallset into a normalset }
  532. if (p^.resulttype^.deftype=setdef) and
  533. (p^.left^.resulttype^.deftype=setdef) and
  534. (psetdef(p^.resulttype)^.settype<>smallset) and
  535. (psetdef(p^.left^.resulttype)^.settype=smallset) then
  536. begin
  537. { try to define the set as a normalset if it's a constant set }
  538. if p^.left^.treetype=setconstn then
  539. begin
  540. p^.resulttype:=p^.left^.resulttype;
  541. psetdef(p^.resulttype)^.settype:=normset
  542. end
  543. else
  544. p^.convtyp:=tc_load_smallset;
  545. exit;
  546. end
  547. else
  548. begin
  549. hp:=p;
  550. p:=p^.left;
  551. p^.resulttype:=hp^.resulttype;
  552. putnode(hp);
  553. exit;
  554. end;
  555. end;
  556. aprocdef:=assignment_overloaded(p^.left^.resulttype,p^.resulttype);
  557. if assigned(aprocdef) then
  558. begin
  559. procinfo.flags:=procinfo.flags or pi_do_call;
  560. hp:=gencallnode(overloaded_operators[_assignment],nil);
  561. { tell explicitly which def we must use !! (PM) }
  562. hp^.procdefinition:=aprocdef;
  563. hp^.left:=gencallparanode(p^.left,nil);
  564. putnode(p);
  565. p:=hp;
  566. firstpass(p);
  567. exit;
  568. end;
  569. if isconvertable(p^.left^.resulttype,p^.resulttype,p^.convtyp,p^.left^.treetype,p^.explizit)=0 then
  570. begin
  571. {Procedures have a resulttype of voiddef and functions of their
  572. own resulttype. They will therefore always be incompatible with
  573. a procvar. Because isconvertable cannot check for procedures we
  574. use an extra check for them.}
  575. if (m_tp_procvar in aktmodeswitches) then
  576. begin
  577. if (p^.resulttype^.deftype=procvardef) and
  578. (is_procsym_load(p^.left) or is_procsym_call(p^.left)) then
  579. begin
  580. if is_procsym_call(p^.left) then
  581. begin
  582. {if p^.left^.right=nil then
  583. begin}
  584. if (p^.left^.symtableprocentry^.owner^.symtabletype=objectsymtable){ and
  585. (pobjectdef(p^.left^.symtableprocentry^.owner^.defowner)^.is_class) }then
  586. hp:=genloadmethodcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc,
  587. getcopy(p^.left^.methodpointer))
  588. else
  589. hp:=genloadcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc);
  590. disposetree(p^.left);
  591. firstpass(hp);
  592. p^.left:=hp;
  593. aprocdef:=pprocdef(p^.left^.resulttype);
  594. (* end
  595. else
  596. begin
  597. p^.left^.right^.treetype:=loadn;
  598. p^.left^.right^.symtableentry:=p^.left^.right^.symtableentry;
  599. P^.left^.right^.resulttype:=pvarsym(p^.left^.symtableentry)^.definition;
  600. hp:=p^.left^.right;
  601. putnode(p^.left);
  602. p^.left:=hp;
  603. { should we do that ? }
  604. firstpass(p^.left);
  605. if not is_equal(p^.left^.resulttype,p^.resulttype) then
  606. begin
  607. CGMessage(type_e_mismatch);
  608. exit;
  609. end
  610. else
  611. begin
  612. hp:=p;
  613. p:=p^.left;
  614. p^.resulttype:=hp^.resulttype;
  615. putnode(hp);
  616. exit;
  617. end;
  618. end; *)
  619. end
  620. else
  621. begin
  622. if (p^.left^.treetype<>addrn) then
  623. aprocdef:=pprocsym(p^.left^.symtableentry)^.definition;
  624. end;
  625. p^.convtyp:=tc_proc_2_procvar;
  626. { Now check if the procedure we are going to assign to
  627. the procvar, is compatible with the procvar's type }
  628. if assigned(aprocdef) then
  629. begin
  630. if not proc_to_procvar_equal(aprocdef,pprocvardef(p^.resulttype)) then
  631. CGMessage2(type_e_incompatible_types,aprocdef^.typename,p^.resulttype^.typename);
  632. firstconvert[p^.convtyp](p);
  633. end
  634. else
  635. CGMessage2(type_e_incompatible_types,p^.left^.resulttype^.typename,p^.resulttype^.typename);
  636. exit;
  637. end;
  638. end;
  639. if p^.explizit then
  640. begin
  641. { check if the result could be in a register }
  642. if not(p^.resulttype^.is_intregable) and
  643. not(p^.resulttype^.is_fpuregable) then
  644. make_not_regable(p^.left);
  645. { boolean to byte are special because the
  646. location can be different }
  647. if is_integer(p^.resulttype) and
  648. is_boolean(p^.left^.resulttype) then
  649. begin
  650. p^.convtyp:=tc_bool_2_int;
  651. firstconvert[p^.convtyp](p);
  652. exit;
  653. end;
  654. { ansistring to pchar }
  655. if is_pchar(p^.resulttype) and
  656. is_ansistring(p^.left^.resulttype) then
  657. begin
  658. p^.convtyp:=tc_ansistring_2_pchar;
  659. firstconvert[p^.convtyp](p);
  660. exit;
  661. end;
  662. { do common tc_equal cast }
  663. p^.convtyp:=tc_equal;
  664. { enum to ordinal will always be s32bit }
  665. if (p^.left^.resulttype^.deftype=enumdef) and
  666. is_ordinal(p^.resulttype) then
  667. begin
  668. if p^.left^.treetype=ordconstn then
  669. begin
  670. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  671. disposetree(p);
  672. firstpass(hp);
  673. p:=hp;
  674. exit;
  675. end
  676. else
  677. begin
  678. if isconvertable(s32bitdef,p^.resulttype,p^.convtyp,ordconstn,false)=0 then
  679. CGMessage(cg_e_illegal_type_conversion);
  680. end;
  681. end
  682. { ordinal to enumeration }
  683. else
  684. if (p^.resulttype^.deftype=enumdef) and
  685. is_ordinal(p^.left^.resulttype) then
  686. begin
  687. if p^.left^.treetype=ordconstn then
  688. begin
  689. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  690. disposetree(p);
  691. firstpass(hp);
  692. p:=hp;
  693. exit;
  694. end
  695. else
  696. begin
  697. if IsConvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn,false)=0 then
  698. CGMessage(cg_e_illegal_type_conversion);
  699. end;
  700. end
  701. {Are we typecasting an ordconst to a char?}
  702. else
  703. if is_char(p^.resulttype) and
  704. is_ordinal(p^.left^.resulttype) then
  705. begin
  706. if p^.left^.treetype=ordconstn then
  707. begin
  708. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  709. firstpass(hp);
  710. disposetree(p);
  711. p:=hp;
  712. exit;
  713. end
  714. else
  715. begin
  716. { this is wrong because it converts to a 4 byte long var !!
  717. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn nur Dummy ) then }
  718. if IsConvertable(p^.left^.resulttype,u8bitdef,p^.convtyp,ordconstn,false)=0 then
  719. CGMessage(cg_e_illegal_type_conversion);
  720. end;
  721. end
  722. { only if the same size or formal def }
  723. { why do we allow typecasting of voiddef ?? (PM) }
  724. else
  725. begin
  726. if not(
  727. (p^.left^.resulttype^.deftype=formaldef) or
  728. (p^.left^.resulttype^.size=p^.resulttype^.size) or
  729. (is_equal(p^.left^.resulttype,voiddef) and
  730. (p^.left^.treetype=derefn))
  731. ) then
  732. CGMessage(cg_e_illegal_type_conversion);
  733. if ((p^.left^.resulttype^.deftype=orddef) and
  734. (p^.resulttype^.deftype=pointerdef)) or
  735. ((p^.resulttype^.deftype=orddef) and
  736. (p^.left^.resulttype^.deftype=pointerdef))
  737. {$ifdef extdebug}and (p^.firstpasscount=0){$endif} then
  738. CGMessage(cg_d_pointer_to_longint_conv_not_portable);
  739. end;
  740. { the conversion into a strutured type is only }
  741. { possible, if the source is no register }
  742. if ((p^.resulttype^.deftype in [recorddef,stringdef,arraydef]) or
  743. ((p^.resulttype^.deftype=objectdef) and not(pobjectdef(p^.resulttype)^.is_class))
  744. ) and (p^.left^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
  745. it also works if the assignment is overloaded
  746. YES but this code is not executed if assignment is overloaded (PM)
  747. not assigned(assignment_overloaded(p^.left^.resulttype,p^.resulttype))} then
  748. CGMessage(cg_e_illegal_type_conversion);
  749. end
  750. else
  751. CGMessage2(type_e_incompatible_types,p^.left^.resulttype^.typename,p^.resulttype^.typename);
  752. end;
  753. { tp7 procvar support, when right is not a procvardef and we got a
  754. loadn of a procvar then convert to a calln, the check for the
  755. result is already done in is_convertible, also no conflict with
  756. @procvar is here because that has an extra addrn }
  757. if (m_tp_procvar in aktmodeswitches) and
  758. (p^.resulttype^.deftype<>procvardef) and
  759. (p^.left^.resulttype^.deftype=procvardef) and
  760. (p^.left^.treetype=loadn) then
  761. begin
  762. hp:=gencallnode(nil,nil);
  763. hp^.right:=p^.left;
  764. firstpass(hp);
  765. p^.left:=hp;
  766. end;
  767. { ordinal contants can be directly converted }
  768. { but not int64/qword }
  769. if (p^.left^.treetype=ordconstn) and is_ordinal(p^.resulttype) and
  770. not(is_64bitint(p^.resulttype)) then
  771. begin
  772. { range checking is done in genordinalconstnode (PFV) }
  773. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  774. disposetree(p);
  775. firstpass(hp);
  776. p:=hp;
  777. exit;
  778. end;
  779. if p^.convtyp<>tc_equal then
  780. firstconvert[p^.convtyp](p);
  781. end;
  782. {*****************************************************************************
  783. FirstIs
  784. *****************************************************************************}
  785. procedure firstis(var p : ptree);
  786. var
  787. Store_valid : boolean;
  788. begin
  789. Store_valid:=Must_be_valid;
  790. Must_be_valid:=true;
  791. firstpass(p^.left);
  792. firstpass(p^.right);
  793. Must_be_valid:=Store_valid;
  794. if codegenerror then
  795. exit;
  796. if (p^.right^.resulttype^.deftype<>classrefdef) then
  797. CGMessage(type_e_mismatch);
  798. left_right_max(p);
  799. { left must be a class }
  800. if (p^.left^.resulttype^.deftype<>objectdef) or
  801. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  802. CGMessage(type_e_mismatch);
  803. { the operands must be related }
  804. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  805. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  806. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.is_related(
  807. pobjectdef(p^.left^.resulttype)))) then
  808. CGMessage(type_e_mismatch);
  809. p^.location.loc:=LOC_FLAGS;
  810. p^.resulttype:=booldef;
  811. end;
  812. {*****************************************************************************
  813. FirstAs
  814. *****************************************************************************}
  815. procedure firstas(var p : ptree);
  816. var
  817. Store_valid : boolean;
  818. begin
  819. Store_valid:=Must_be_valid;
  820. Must_be_valid:=true;
  821. firstpass(p^.right);
  822. firstpass(p^.left);
  823. Must_be_valid:=Store_valid;
  824. if codegenerror then
  825. exit;
  826. if (p^.right^.resulttype^.deftype<>classrefdef) then
  827. CGMessage(type_e_mismatch);
  828. left_right_max(p);
  829. { left must be a class }
  830. if (p^.left^.resulttype^.deftype<>objectdef) or
  831. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  832. CGMessage(type_e_mismatch);
  833. { the operands must be related }
  834. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  835. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  836. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.is_related(
  837. pobjectdef(p^.left^.resulttype)))) then
  838. CGMessage(type_e_mismatch);
  839. set_location(p^.location,p^.left^.location);
  840. p^.resulttype:=pclassrefdef(p^.right^.resulttype)^.definition;
  841. end;
  842. end.
  843. {
  844. $Log$
  845. Revision 1.48 1999-09-17 17:14:12 peter
  846. * @procvar fixes for tp mode
  847. * @<id>:= gives now an error
  848. Revision 1.47 1999/09/11 09:08:34 florian
  849. * fixed bug 596
  850. * fixed some problems with procedure variables and procedures of object,
  851. especially in TP mode. Procedure of object doesn't apply only to classes,
  852. it is also allowed for objects !!
  853. Revision 1.46 1999/08/13 15:43:59 peter
  854. * fixed proc->procvar conversion for tp_procvar mode, it now uses
  855. also the genload(method)call() function
  856. Revision 1.45 1999/08/07 14:21:04 florian
  857. * some small problems fixed
  858. Revision 1.44 1999/08/04 13:03:14 jonas
  859. * all tokens now start with an underscore
  860. * PowerPC compiles!!
  861. Revision 1.43 1999/08/04 00:23:36 florian
  862. * renamed i386asm and i386base to cpuasm and cpubase
  863. Revision 1.42 1999/08/03 22:03:28 peter
  864. * moved bitmask constants to sets
  865. * some other type/const renamings
  866. Revision 1.41 1999/06/30 22:16:23 florian
  867. * use of is_ordinal checked: often a qword/int64 isn't allowed (case/for ...)
  868. * small qword problems fixed
  869. Revision 1.40 1999/06/28 22:29:21 florian
  870. * qword division fixed
  871. + code for qword/int64 type casting added:
  872. range checking isn't implemented yet
  873. Revision 1.39 1999/06/28 19:30:07 peter
  874. * merged
  875. Revision 1.35.2.5 1999/06/28 19:07:47 peter
  876. * remove cstring->string typeconvs after updating cstringn
  877. Revision 1.35.2.4 1999/06/28 00:33:50 pierre
  878. * better error position bug0269
  879. Revision 1.35.2.3 1999/06/17 12:51:48 pierre
  880. * changed is_assignment_overloaded into
  881. function assignment_overloaded : pprocdef
  882. to allow overloading of assignment with only different result type
  883. Revision 1.35.2.2 1999/06/15 18:54:53 peter
  884. * more procvar fixes
  885. Revision 1.35.2.1 1999/06/13 22:39:19 peter
  886. * use proc_to_procvar_equal
  887. Revision 1.35 1999/06/02 22:44:24 pierre
  888. * previous wrong log corrected
  889. Revision 1.34 1999/06/02 22:25:54 pierre
  890. * changed $ifdef FPC @ into $ifndef TP
  891. + debug note about longint to pointer conversion
  892. Revision 1.33 1999/05/27 19:45:15 peter
  893. * removed oldasm
  894. * plabel -> pasmlabel
  895. * -a switches to source writing automaticly
  896. * assembler readers OOPed
  897. * asmsymbol automaticly external
  898. * jumptables and other label fixes for asm readers
  899. Revision 1.32 1999/05/20 14:58:28 peter
  900. * fixed arrayconstruct->set conversion which didn't work for enum sets
  901. Revision 1.31 1999/05/13 21:59:52 peter
  902. * removed oldppu code
  903. * warning if objpas is loaded from uses
  904. * first things for new deref writing
  905. Revision 1.30 1999/05/12 00:20:00 peter
  906. * removed R_DEFAULT_SEG
  907. * uniform float names
  908. Revision 1.29 1999/05/09 11:37:05 peter
  909. * fixed order of arguments for incompatible types message
  910. Revision 1.28 1999/05/06 09:05:34 peter
  911. * generic write_float and str_float
  912. * fixed constant float conversions
  913. Revision 1.27 1999/05/01 13:24:48 peter
  914. * merged nasm compiler
  915. * old asm moved to oldasm/
  916. Revision 1.26 1999/04/26 13:31:58 peter
  917. * release storenumber,double_checksum
  918. Revision 1.25 1999/04/22 10:49:09 peter
  919. * fixed pchar to string location
  920. Revision 1.24 1999/04/21 09:44:01 peter
  921. * storenumber works
  922. * fixed some typos in double_checksum
  923. + incompatible types type1 and type2 message (with storenumber)
  924. Revision 1.23 1999/04/15 08:56:24 peter
  925. * fixed bool-bool conversion
  926. Revision 1.22 1999/04/08 09:47:31 pierre
  927. * warn if uninitilized local vars are used in IS or AS statements
  928. Revision 1.21 1999/03/06 17:25:20 peter
  929. * moved comp<->real warning so it doesn't occure everytime that
  930. isconvertable is called with
  931. Revision 1.20 1999/03/02 18:24:23 peter
  932. * fixed overloading of array of char
  933. Revision 1.19 1999/02/22 02:15:46 peter
  934. * updates for ag386bin
  935. Revision 1.18 1999/01/27 14:56:57 pierre
  936. * typo error corrected solves bug0190 and bug0204
  937. Revision 1.17 1999/01/27 14:15:25 pierre
  938. * bug0209 corrected (introduce while solving other bool to int related bugs)
  939. Revision 1.16 1999/01/27 13:02:21 pierre
  940. boolean to int conversion problems bug0205 bug0208
  941. Revision 1.15 1999/01/27 00:13:57 florian
  942. * "procedure of object"-stuff fixed
  943. Revision 1.14 1999/01/19 12:17:45 peter
  944. * removed rangecheck warning which was shown twice
  945. Revision 1.13 1998/12/30 22:13:47 peter
  946. * if explicit cnv then also handle the ordinal consts direct
  947. Revision 1.12 1998/12/11 00:03:53 peter
  948. + globtype,tokens,version unit splitted from globals
  949. Revision 1.11 1998/12/04 10:18:12 florian
  950. * some stuff for procedures of object added
  951. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  952. Revision 1.10 1998/11/29 12:40:24 peter
  953. * newcnv -> not oldcnv
  954. Revision 1.9 1998/11/26 13:10:43 peter
  955. * new int - int conversion -dNEWCNV
  956. * some function renamings
  957. Revision 1.8 1998/11/05 12:03:03 peter
  958. * released useansistring
  959. * removed -Sv, its now available in fpc modes
  960. Revision 1.7 1998/10/23 11:58:27 florian
  961. * better code generation for s:=s+[b] if b is in the range of
  962. a small set and s is also a small set
  963. Revision 1.6 1998/10/21 15:12:58 pierre
  964. * bug fix for IOCHECK inside a procedure with iocheck modifier
  965. * removed the GPF for unexistant overloading
  966. (firstcall was called with procedinition=nil !)
  967. * changed typen to what Florian proposed
  968. gentypenode(p : pdef) sets the typenodetype field
  969. and resulttype is only set if inside bt_type block !
  970. Revision 1.5 1998/10/07 10:38:55 peter
  971. * forgot a firstpass in arrayconstruct2set
  972. Revision 1.4 1998/10/05 21:33:32 peter
  973. * fixed 161,165,166,167,168
  974. Revision 1.3 1998/09/27 10:16:26 florian
  975. * type casts pchar<->ansistring fixed
  976. * ansistring[..] calls does now an unique call
  977. Revision 1.2 1998/09/24 23:49:22 peter
  978. + aktmodeswitches
  979. Revision 1.1 1998/09/23 20:42:24 peter
  980. * splitted pass_1
  981. }