tccnv.pas 34 KB

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