tccnv.pas 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Type checking and register allocation for type converting nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {$ifdef TP}
  19. {$E+,F+,N+,D+,L+,Y+}
  20. {$endif}
  21. unit tccnv;
  22. interface
  23. uses
  24. tree;
  25. procedure arrayconstructor_to_set(var p:ptree);
  26. procedure firsttypeconv(var p : ptree);
  27. procedure firstas(var p : ptree);
  28. procedure firstis(var p : ptree);
  29. implementation
  30. uses
  31. globtype,systems,tokens,
  32. cobjects,verbose,globals,
  33. symconst,symtable,aasm,types,
  34. {$ifdef newcg}
  35. cgbase,
  36. {$else newcg}
  37. hcodegen,
  38. {$endif newcg}
  39. htypechk,pass_1,cpubase;
  40. {*****************************************************************************
  41. Array constructor to Set Conversion
  42. *****************************************************************************}
  43. procedure arrayconstructor_to_set(var p:ptree);
  44. var
  45. constp,
  46. buildp,
  47. p2,p3,p4 : ptree;
  48. pd : pdef;
  49. constset : pconstset;
  50. constsetlo,
  51. constsethi : longint;
  52. procedure update_constsethi(p:pdef);
  53. begin
  54. if ((p^.deftype=orddef) and
  55. (porddef(p)^.high>constsethi)) then
  56. 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. if pstringdef(p^.resulttype)^.string_typ in [st_ansistring,st_widestring] then
  260. { we may use ansistrings so no fast exit here }
  261. procinfo^.no_fast_exit:=true;
  262. p^.location.loc:=LOC_MEM;
  263. end;
  264. procedure first_char_to_string(var p : ptree);
  265. var
  266. hp : ptree;
  267. begin
  268. if p^.left^.treetype=ordconstn then
  269. begin
  270. hp:=genstringconstnode(chr(p^.left^.value));
  271. hp^.stringtype:=pstringdef(p^.resulttype)^.string_typ;
  272. firstpass(hp);
  273. disposetree(p);
  274. p:=hp;
  275. end
  276. else
  277. p^.location.loc:=LOC_MEM;
  278. end;
  279. procedure first_nothing(var p : ptree);
  280. begin
  281. p^.location.loc:=LOC_MEM;
  282. end;
  283. procedure first_array_to_pointer(var p : ptree);
  284. begin
  285. if p^.registers32<1 then
  286. p^.registers32:=1;
  287. p^.location.loc:=LOC_REGISTER;
  288. end;
  289. procedure first_int_to_real(var p : ptree);
  290. var
  291. t : ptree;
  292. begin
  293. if p^.left^.treetype=ordconstn then
  294. begin
  295. t:=genrealconstnode(p^.left^.value,pfloatdef(p^.resulttype));
  296. firstpass(t);
  297. disposetree(p);
  298. p:=t;
  299. exit;
  300. end;
  301. if p^.registersfpu<1 then
  302. p^.registersfpu:=1;
  303. p^.location.loc:=LOC_FPU;
  304. end;
  305. procedure first_int_to_fix(var p : ptree);
  306. var
  307. t : ptree;
  308. begin
  309. if p^.left^.treetype=ordconstn then
  310. begin
  311. t:=genfixconstnode(p^.left^.value shl 16,p^.resulttype);
  312. firstpass(t);
  313. disposetree(p);
  314. p:=t;
  315. exit;
  316. end;
  317. if p^.registers32<1 then
  318. p^.registers32:=1;
  319. p^.location.loc:=LOC_REGISTER;
  320. end;
  321. procedure first_real_to_fix(var p : ptree);
  322. var
  323. t : ptree;
  324. begin
  325. if p^.left^.treetype=fixconstn then
  326. begin
  327. t:=genfixconstnode(round(p^.left^.value_real*65536),p^.resulttype);
  328. firstpass(t);
  329. disposetree(p);
  330. p:=t;
  331. exit;
  332. end;
  333. { at least one fpu and int register needed }
  334. if p^.registers32<1 then
  335. p^.registers32:=1;
  336. if p^.registersfpu<1 then
  337. p^.registersfpu:=1;
  338. p^.location.loc:=LOC_REGISTER;
  339. end;
  340. procedure first_fix_to_real(var p : ptree);
  341. var
  342. t : ptree;
  343. begin
  344. if p^.left^.treetype=fixconstn then
  345. begin
  346. t:=genrealconstnode(round(p^.left^.value_fix/65536.0),p^.resulttype);
  347. firstpass(t);
  348. disposetree(p);
  349. p:=t;
  350. exit;
  351. end;
  352. if p^.registersfpu<1 then
  353. p^.registersfpu:=1;
  354. p^.location.loc:=LOC_FPU;
  355. end;
  356. procedure first_real_to_real(var p : ptree);
  357. var
  358. t : ptree;
  359. begin
  360. if p^.left^.treetype=realconstn then
  361. begin
  362. t:=genrealconstnode(p^.left^.value_real,p^.resulttype);
  363. firstpass(t);
  364. disposetree(p);
  365. p:=t;
  366. exit;
  367. end;
  368. { comp isn't a floating type }
  369. {$ifdef i386}
  370. if (pfloatdef(p^.resulttype)^.typ=s64comp) and
  371. (pfloatdef(p^.left^.resulttype)^.typ<>s64comp) and
  372. not (p^.explizit) then
  373. CGMessage(type_w_convert_real_2_comp);
  374. {$endif}
  375. if p^.registersfpu<1 then
  376. p^.registersfpu:=1;
  377. p^.location.loc:=LOC_FPU;
  378. end;
  379. procedure first_pointer_to_array(var p : ptree);
  380. begin
  381. if p^.registers32<1 then
  382. p^.registers32:=1;
  383. p^.location.loc:=LOC_REFERENCE;
  384. end;
  385. procedure first_chararray_to_string(var p : ptree);
  386. begin
  387. { the only important information is the location of the }
  388. { result }
  389. { other stuff is done by firsttypeconv }
  390. p^.location.loc:=LOC_MEM;
  391. end;
  392. procedure first_cchar_to_pchar(var p : ptree);
  393. begin
  394. p^.left:=gentypeconvnode(p^.left,cshortstringdef);
  395. { convert constant char to constant string }
  396. firstpass(p^.left);
  397. { evalute tree }
  398. firstpass(p);
  399. end;
  400. procedure first_bool_to_int(var p : ptree);
  401. begin
  402. { byte(boolean) or word(wordbool) or longint(longbool) must
  403. be accepted for var parameters }
  404. if (p^.explizit) and
  405. (p^.left^.resulttype^.size=p^.resulttype^.size) and
  406. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  407. exit;
  408. p^.location.loc:=LOC_REGISTER;
  409. if p^.registers32<1 then
  410. p^.registers32:=1;
  411. end;
  412. procedure first_int_to_bool(var p : ptree);
  413. begin
  414. { byte(boolean) or word(wordbool) or longint(longbool) must
  415. be accepted for var parameters }
  416. if (p^.explizit) and
  417. (p^.left^.resulttype^.size=p^.resulttype^.size) and
  418. (p^.left^.location.loc in [LOC_REFERENCE,LOC_MEM,LOC_CREGISTER]) then
  419. exit;
  420. p^.location.loc:=LOC_REGISTER;
  421. { need if bool to bool !!
  422. not very nice !!
  423. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  424. p^.left^.explizit:=true;
  425. firstpass(p^.left); }
  426. if p^.registers32<1 then
  427. p^.registers32:=1;
  428. end;
  429. procedure first_bool_to_bool(var p : ptree);
  430. begin
  431. p^.location.loc:=LOC_REGISTER;
  432. if p^.registers32<1 then
  433. p^.registers32:=1;
  434. end;
  435. procedure first_proc_to_procvar(var p : ptree);
  436. begin
  437. { hmmm, I'am not sure if that is necessary (FK) }
  438. firstpass(p^.left);
  439. if codegenerror then
  440. exit;
  441. if (p^.left^.location.loc<>LOC_REFERENCE) then
  442. CGMessage(cg_e_illegal_expression);
  443. p^.registers32:=p^.left^.registers32;
  444. if p^.registers32<1 then
  445. p^.registers32:=1;
  446. p^.location.loc:=LOC_REGISTER;
  447. end;
  448. procedure first_load_smallset(var p : ptree);
  449. begin
  450. end;
  451. procedure first_cord_to_pointer(var p : ptree);
  452. var
  453. t : ptree;
  454. begin
  455. if p^.left^.treetype=ordconstn then
  456. begin
  457. t:=genpointerconstnode(p^.left^.value,p^.resulttype);
  458. firstpass(t);
  459. disposetree(p);
  460. p:=t;
  461. exit;
  462. end
  463. else
  464. internalerror(432472389);
  465. end;
  466. procedure first_pchar_to_string(var p : ptree);
  467. begin
  468. p^.location.loc:=LOC_REFERENCE;
  469. end;
  470. procedure first_ansistring_to_pchar(var p : ptree);
  471. begin
  472. p^.location.loc:=LOC_REGISTER;
  473. if p^.registers32<1 then
  474. p^.registers32:=1;
  475. end;
  476. procedure first_arrayconstructor_to_set(var p:ptree);
  477. var
  478. hp : ptree;
  479. begin
  480. if p^.left^.treetype<>arrayconstructn then
  481. internalerror(5546);
  482. { remove typeconv node }
  483. hp:=p;
  484. p:=p^.left;
  485. putnode(hp);
  486. { create a set constructor tree }
  487. arrayconstructor_to_set(p);
  488. { now firstpass the set }
  489. firstpass(p);
  490. end;
  491. procedure firsttypeconv(var p : ptree);
  492. var
  493. hp : ptree;
  494. aprocdef : pprocdef;
  495. const
  496. firstconvert : array[tconverttype] of tfirstconvproc = (
  497. first_nothing, {equal}
  498. first_nothing, {not_possible}
  499. first_string_to_string,
  500. first_char_to_string,
  501. first_pchar_to_string,
  502. first_cchar_to_pchar,
  503. first_cstring_to_pchar,
  504. first_ansistring_to_pchar,
  505. first_string_to_chararray,
  506. first_chararray_to_string,
  507. first_array_to_pointer,
  508. first_pointer_to_array,
  509. first_int_to_int,
  510. first_int_to_bool,
  511. first_bool_to_bool,
  512. first_bool_to_int,
  513. first_real_to_real,
  514. first_int_to_real,
  515. first_int_to_fix,
  516. first_real_to_fix,
  517. first_fix_to_real,
  518. first_proc_to_procvar,
  519. first_arrayconstructor_to_set,
  520. first_load_smallset,
  521. first_cord_to_pointer
  522. );
  523. begin
  524. aprocdef:=nil;
  525. { if explicite type cast, then run firstpass }
  526. if (p^.explizit) or not assigned(p^.left^.resulttype) then
  527. firstpass(p^.left);
  528. if (p^.left^.treetype=typen) and (p^.left^.resulttype=generrordef) then
  529. begin
  530. codegenerror:=true;
  531. Message(parser_e_no_type_not_allowed_here);
  532. end;
  533. if codegenerror then
  534. begin
  535. p^.resulttype:=generrordef;
  536. exit;
  537. end;
  538. if not assigned(p^.left^.resulttype) then
  539. begin
  540. codegenerror:=true;
  541. internalerror(52349);
  542. exit;
  543. end;
  544. { load the value_str from the left part }
  545. p^.registers32:=p^.left^.registers32;
  546. p^.registersfpu:=p^.left^.registersfpu;
  547. {$ifdef SUPPORT_MMX}
  548. p^.registersmmx:=p^.left^.registersmmx;
  549. {$endif}
  550. set_location(p^.location,p^.left^.location);
  551. { remove obsolete type conversions }
  552. if is_equal(p^.left^.resulttype,p^.resulttype) then
  553. begin
  554. { becuase is_equal only checks the basetype for sets we need to
  555. check here if we are loading a smallset into a normalset }
  556. if (p^.resulttype^.deftype=setdef) and
  557. (p^.left^.resulttype^.deftype=setdef) and
  558. (psetdef(p^.resulttype)^.settype<>smallset) and
  559. (psetdef(p^.left^.resulttype)^.settype=smallset) then
  560. begin
  561. { try to define the set as a normalset if it's a constant set }
  562. if p^.left^.treetype=setconstn then
  563. begin
  564. p^.resulttype:=p^.left^.resulttype;
  565. psetdef(p^.resulttype)^.settype:=normset
  566. end
  567. else
  568. p^.convtyp:=tc_load_smallset;
  569. exit;
  570. end
  571. else
  572. begin
  573. hp:=p;
  574. p:=p^.left;
  575. p^.resulttype:=hp^.resulttype;
  576. putnode(hp);
  577. exit;
  578. end;
  579. end;
  580. aprocdef:=assignment_overloaded(p^.left^.resulttype,p^.resulttype);
  581. if assigned(aprocdef) then
  582. begin
  583. procinfo^.flags:=procinfo^.flags or pi_do_call;
  584. hp:=gencallnode(overloaded_operators[_assignment],nil);
  585. { tell explicitly which def we must use !! (PM) }
  586. hp^.procdefinition:=aprocdef;
  587. hp^.left:=gencallparanode(p^.left,nil);
  588. putnode(p);
  589. p:=hp;
  590. firstpass(p);
  591. exit;
  592. end;
  593. if isconvertable(p^.left^.resulttype,p^.resulttype,p^.convtyp,p^.left^.treetype,p^.explizit)=0 then
  594. begin
  595. {Procedures have a resulttype of voiddef and functions of their
  596. own resulttype. They will therefore always be incompatible with
  597. a procvar. Because isconvertable cannot check for procedures we
  598. use an extra check for them.}
  599. if (m_tp_procvar in aktmodeswitches) then
  600. begin
  601. if (p^.resulttype^.deftype=procvardef) and
  602. (is_procsym_load(p^.left) or is_procsym_call(p^.left)) then
  603. begin
  604. if is_procsym_call(p^.left) then
  605. begin
  606. {if p^.left^.right=nil then
  607. begin}
  608. if (p^.left^.symtableprocentry^.owner^.symtabletype=objectsymtable){ and
  609. (pobjectdef(p^.left^.symtableprocentry^.owner^.defowner)^.is_class) }then
  610. hp:=genloadmethodcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc,
  611. getcopy(p^.left^.methodpointer))
  612. else
  613. hp:=genloadcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc);
  614. disposetree(p^.left);
  615. firstpass(hp);
  616. p^.left:=hp;
  617. aprocdef:=pprocdef(p^.left^.resulttype);
  618. (* end
  619. else
  620. begin
  621. p^.left^.right^.treetype:=loadn;
  622. p^.left^.right^.symtableentry:=p^.left^.right^.symtableentry;
  623. P^.left^.right^.resulttype:=pvarsym(p^.left^.symtableentry)^.definition;
  624. hp:=p^.left^.right;
  625. putnode(p^.left);
  626. p^.left:=hp;
  627. { should we do that ? }
  628. firstpass(p^.left);
  629. if not is_equal(p^.left^.resulttype,p^.resulttype) then
  630. begin
  631. CGMessage(type_e_mismatch);
  632. exit;
  633. end
  634. else
  635. begin
  636. hp:=p;
  637. p:=p^.left;
  638. p^.resulttype:=hp^.resulttype;
  639. putnode(hp);
  640. exit;
  641. end;
  642. end; *)
  643. end
  644. else
  645. begin
  646. if (p^.left^.treetype<>addrn) then
  647. aprocdef:=pprocsym(p^.left^.symtableentry)^.definition;
  648. end;
  649. p^.convtyp:=tc_proc_2_procvar;
  650. { Now check if the procedure we are going to assign to
  651. the procvar, is compatible with the procvar's type }
  652. if assigned(aprocdef) then
  653. begin
  654. if not proc_to_procvar_equal(aprocdef,pprocvardef(p^.resulttype)) then
  655. CGMessage2(type_e_incompatible_types,aprocdef^.typename,p^.resulttype^.typename);
  656. firstconvert[p^.convtyp](p);
  657. end
  658. else
  659. CGMessage2(type_e_incompatible_types,p^.left^.resulttype^.typename,p^.resulttype^.typename);
  660. exit;
  661. end;
  662. end;
  663. if p^.explizit then
  664. begin
  665. { check if the result could be in a register }
  666. if not(p^.resulttype^.is_intregable) and
  667. not(p^.resulttype^.is_fpuregable) then
  668. make_not_regable(p^.left);
  669. { boolean to byte are special because the
  670. location can be different }
  671. if is_integer(p^.resulttype) and
  672. is_boolean(p^.left^.resulttype) then
  673. begin
  674. p^.convtyp:=tc_bool_2_int;
  675. firstconvert[p^.convtyp](p);
  676. exit;
  677. end;
  678. { ansistring to pchar }
  679. if is_pchar(p^.resulttype) and
  680. is_ansistring(p^.left^.resulttype) then
  681. begin
  682. p^.convtyp:=tc_ansistring_2_pchar;
  683. firstconvert[p^.convtyp](p);
  684. exit;
  685. end;
  686. { do common tc_equal cast }
  687. p^.convtyp:=tc_equal;
  688. { enum to ordinal will always be s32bit }
  689. if (p^.left^.resulttype^.deftype=enumdef) and
  690. is_ordinal(p^.resulttype) then
  691. begin
  692. if p^.left^.treetype=ordconstn then
  693. begin
  694. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  695. disposetree(p);
  696. firstpass(hp);
  697. p:=hp;
  698. exit;
  699. end
  700. else
  701. begin
  702. if isconvertable(s32bitdef,p^.resulttype,p^.convtyp,ordconstn,false)=0 then
  703. CGMessage(cg_e_illegal_type_conversion);
  704. end;
  705. end
  706. { ordinal to enumeration }
  707. else
  708. if (p^.resulttype^.deftype=enumdef) and
  709. is_ordinal(p^.left^.resulttype) then
  710. begin
  711. if p^.left^.treetype=ordconstn then
  712. begin
  713. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  714. disposetree(p);
  715. firstpass(hp);
  716. p:=hp;
  717. exit;
  718. end
  719. else
  720. begin
  721. if IsConvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn,false)=0 then
  722. CGMessage(cg_e_illegal_type_conversion);
  723. end;
  724. end
  725. { nil to ordinal node }
  726. else if is_ordinal(p^.resulttype) and
  727. (p^.left^.treetype=niln) then
  728. begin
  729. hp:=genordinalconstnode(0,p^.resulttype);
  730. firstpass(hp);
  731. disposetree(p);
  732. p:=hp;
  733. exit;
  734. end
  735. {Are we typecasting an ordconst to a char?}
  736. else
  737. if is_char(p^.resulttype) and
  738. is_ordinal(p^.left^.resulttype) then
  739. begin
  740. if p^.left^.treetype=ordconstn then
  741. begin
  742. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  743. firstpass(hp);
  744. disposetree(p);
  745. p:=hp;
  746. exit;
  747. end
  748. else
  749. begin
  750. { this is wrong because it converts to a 4 byte long var !!
  751. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn nur Dummy ) then }
  752. if IsConvertable(p^.left^.resulttype,u8bitdef,p^.convtyp,ordconstn,false)=0 then
  753. CGMessage(cg_e_illegal_type_conversion);
  754. end;
  755. end
  756. { only if the same size or formal def }
  757. { why do we allow typecasting of voiddef ?? (PM) }
  758. else
  759. begin
  760. if not(
  761. (p^.left^.resulttype^.deftype=formaldef) or
  762. (p^.left^.resulttype^.size=p^.resulttype^.size) or
  763. (is_equal(p^.left^.resulttype,voiddef) and
  764. (p^.left^.treetype=derefn))
  765. ) then
  766. CGMessage(cg_e_illegal_type_conversion);
  767. if ((p^.left^.resulttype^.deftype=orddef) and
  768. (p^.resulttype^.deftype=pointerdef)) or
  769. ((p^.resulttype^.deftype=orddef) and
  770. (p^.left^.resulttype^.deftype=pointerdef))
  771. {$ifdef extdebug}and (p^.firstpasscount=0){$endif} then
  772. CGMessage(cg_d_pointer_to_longint_conv_not_portable);
  773. end;
  774. { the conversion into a strutured type is only }
  775. { possible, if the source is no register }
  776. if ((p^.resulttype^.deftype in [recorddef,stringdef,arraydef]) or
  777. ((p^.resulttype^.deftype=objectdef) and not(pobjectdef(p^.resulttype)^.is_class))
  778. ) and (p^.left^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
  779. it also works if the assignment is overloaded
  780. YES but this code is not executed if assignment is overloaded (PM)
  781. not assigned(assignment_overloaded(p^.left^.resulttype,p^.resulttype))} then
  782. CGMessage(cg_e_illegal_type_conversion);
  783. end
  784. else
  785. CGMessage2(type_e_incompatible_types,p^.left^.resulttype^.typename,p^.resulttype^.typename);
  786. end;
  787. { tp7 procvar support, when right is not a procvardef and we got a
  788. loadn of a procvar then convert to a calln, the check for the
  789. result is already done in is_convertible, also no conflict with
  790. @procvar is here because that has an extra addrn }
  791. if (m_tp_procvar in aktmodeswitches) and
  792. (p^.resulttype^.deftype<>procvardef) and
  793. (p^.left^.resulttype^.deftype=procvardef) and
  794. (p^.left^.treetype=loadn) then
  795. begin
  796. hp:=gencallnode(nil,nil);
  797. hp^.right:=p^.left;
  798. firstpass(hp);
  799. p^.left:=hp;
  800. end;
  801. { ordinal contants can be directly converted }
  802. { but not int64/qword }
  803. if (p^.left^.treetype=ordconstn) and is_ordinal(p^.resulttype) and
  804. not(is_64bitint(p^.resulttype)) then
  805. begin
  806. { range checking is done in genordinalconstnode (PFV) }
  807. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  808. disposetree(p);
  809. firstpass(hp);
  810. p:=hp;
  811. exit;
  812. end;
  813. if p^.convtyp<>tc_equal then
  814. firstconvert[p^.convtyp](p);
  815. end;
  816. {*****************************************************************************
  817. FirstIs
  818. *****************************************************************************}
  819. procedure firstis(var p : ptree);
  820. begin
  821. firstpass(p^.left);
  822. set_varstate(p^.left,true);
  823. firstpass(p^.right);
  824. set_varstate(p^.right,true);
  825. if codegenerror then
  826. exit;
  827. if (p^.right^.resulttype^.deftype<>classrefdef) then
  828. CGMessage(type_e_mismatch);
  829. left_right_max(p);
  830. { left must be a class }
  831. if (p^.left^.resulttype^.deftype<>objectdef) or
  832. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  833. CGMessage(type_e_mismatch);
  834. { the operands must be related }
  835. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  836. pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)))) and
  837. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)^.is_related(
  838. pobjectdef(p^.left^.resulttype)))) then
  839. CGMessage(type_e_mismatch);
  840. p^.location.loc:=LOC_FLAGS;
  841. p^.resulttype:=booldef;
  842. end;
  843. {*****************************************************************************
  844. FirstAs
  845. *****************************************************************************}
  846. procedure firstas(var p : ptree);
  847. begin
  848. firstpass(p^.right);
  849. set_varstate(p^.right,true);
  850. firstpass(p^.left);
  851. set_varstate(p^.left,true);
  852. if codegenerror then
  853. exit;
  854. if (p^.right^.resulttype^.deftype<>classrefdef) then
  855. CGMessage(type_e_mismatch);
  856. left_right_max(p);
  857. { left must be a class }
  858. if (p^.left^.resulttype^.deftype<>objectdef) or
  859. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  860. CGMessage(type_e_mismatch);
  861. { the operands must be related }
  862. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  863. pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)))) and
  864. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.pointertype.def)^.is_related(
  865. pobjectdef(p^.left^.resulttype)))) then
  866. CGMessage(type_e_mismatch);
  867. set_location(p^.location,p^.left^.location);
  868. p^.resulttype:=pclassrefdef(p^.right^.resulttype)^.pointertype.def;
  869. end;
  870. end.
  871. {
  872. $Log$
  873. Revision 1.57 2000-01-07 01:14:44 peter
  874. * updated copyright to 2000
  875. Revision 1.56 1999/12/19 12:08:27 florian
  876. * bug reported by Alex S. fixed: it wasn't possible to type cast nil in const
  877. declarations: const l = longint(nil);
  878. Revision 1.55 1999/12/09 23:18:04 pierre
  879. * no_fast_exit if procedure contains implicit termination code
  880. Revision 1.54 1999/11/30 10:40:57 peter
  881. + ttype, tsymlist
  882. Revision 1.53 1999/11/18 15:34:49 pierre
  883. * Notes/Hints for local syms changed to
  884. Set_varstate function
  885. Revision 1.52 1999/11/06 14:34:29 peter
  886. * truncated log to 20 revs
  887. Revision 1.51 1999/11/05 13:15:00 florian
  888. * some fixes to get the new cg compiling again
  889. Revision 1.50 1999/09/27 23:45:00 peter
  890. * procinfo is now a pointer
  891. * support for result setting in sub procedure
  892. Revision 1.49 1999/09/26 21:30:22 peter
  893. + constant pointer support which can happend with typecasting like
  894. const p=pointer(1)
  895. * better procvar parsing in typed consts
  896. Revision 1.48 1999/09/17 17:14:12 peter
  897. * @procvar fixes for tp mode
  898. * @<id>:= gives now an error
  899. Revision 1.47 1999/09/11 09:08:34 florian
  900. * fixed bug 596
  901. * fixed some problems with procedure variables and procedures of object,
  902. especially in TP mode. Procedure of object doesn't apply only to classes,
  903. it is also allowed for objects !!
  904. Revision 1.46 1999/08/13 15:43:59 peter
  905. * fixed proc->procvar conversion for tp_procvar mode, it now uses
  906. also the genload(method)call() function
  907. Revision 1.45 1999/08/07 14:21:04 florian
  908. * some small problems fixed
  909. Revision 1.44 1999/08/04 13:03:14 jonas
  910. * all tokens now start with an underscore
  911. * PowerPC compiles!!
  912. Revision 1.43 1999/08/04 00:23:36 florian
  913. * renamed i386asm and i386base to cpuasm and cpubase
  914. Revision 1.42 1999/08/03 22:03:28 peter
  915. * moved bitmask constants to sets
  916. * some other type/const renamings
  917. Revision 1.41 1999/06/30 22:16:23 florian
  918. * use of is_ordinal checked: often a qword/int64 isn't allowed (case/for ...)
  919. * small qword problems fixed
  920. Revision 1.40 1999/06/28 22:29:21 florian
  921. * qword division fixed
  922. + code for qword/int64 type casting added:
  923. range checking isn't implemented yet
  924. Revision 1.39 1999/06/28 19:30:07 peter
  925. * merged
  926. Revision 1.35.2.5 1999/06/28 19:07:47 peter
  927. * remove cstring->string typeconvs after updating cstringn
  928. Revision 1.35.2.4 1999/06/28 00:33:50 pierre
  929. * better error position bug0269
  930. Revision 1.35.2.3 1999/06/17 12:51:48 pierre
  931. * changed is_assignment_overloaded into
  932. function assignment_overloaded : pprocdef
  933. to allow overloading of assignment with only different result type
  934. Revision 1.35.2.2 1999/06/15 18:54:53 peter
  935. * more procvar fixes
  936. Revision 1.35.2.1 1999/06/13 22:39:19 peter
  937. * use proc_to_procvar_equal
  938. Revision 1.35 1999/06/02 22:44:24 pierre
  939. * previous wrong log corrected
  940. Revision 1.34 1999/06/02 22:25:54 pierre
  941. * changed $ifdef FPC @ into $ifndef TP
  942. + debug note about longint to pointer conversion
  943. }