tccnv.pas 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  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. { ordinal contants can be directly converted }
  754. { but not int64/qword }
  755. if (p^.left^.treetype=ordconstn) and is_ordinal(p^.resulttype) and
  756. not(is_64bitint(p^.resulttype)) then
  757. begin
  758. { range checking is done in genordinalconstnode (PFV) }
  759. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  760. disposetree(p);
  761. firstpass(hp);
  762. p:=hp;
  763. exit;
  764. end;
  765. if p^.convtyp<>tc_equal then
  766. firstconvert[p^.convtyp](p);
  767. end;
  768. {*****************************************************************************
  769. FirstIs
  770. *****************************************************************************}
  771. procedure firstis(var p : ptree);
  772. var
  773. Store_valid : boolean;
  774. begin
  775. Store_valid:=Must_be_valid;
  776. Must_be_valid:=true;
  777. firstpass(p^.left);
  778. firstpass(p^.right);
  779. Must_be_valid:=Store_valid;
  780. if codegenerror then
  781. exit;
  782. if (p^.right^.resulttype^.deftype<>classrefdef) then
  783. CGMessage(type_e_mismatch);
  784. left_right_max(p);
  785. { left must be a class }
  786. if (p^.left^.resulttype^.deftype<>objectdef) or
  787. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  788. CGMessage(type_e_mismatch);
  789. { the operands must be related }
  790. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  791. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  792. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.is_related(
  793. pobjectdef(p^.left^.resulttype)))) then
  794. CGMessage(type_e_mismatch);
  795. p^.location.loc:=LOC_FLAGS;
  796. p^.resulttype:=booldef;
  797. end;
  798. {*****************************************************************************
  799. FirstAs
  800. *****************************************************************************}
  801. procedure firstas(var p : ptree);
  802. var
  803. Store_valid : boolean;
  804. begin
  805. Store_valid:=Must_be_valid;
  806. Must_be_valid:=true;
  807. firstpass(p^.right);
  808. firstpass(p^.left);
  809. Must_be_valid:=Store_valid;
  810. if codegenerror then
  811. exit;
  812. if (p^.right^.resulttype^.deftype<>classrefdef) then
  813. CGMessage(type_e_mismatch);
  814. left_right_max(p);
  815. { left must be a class }
  816. if (p^.left^.resulttype^.deftype<>objectdef) or
  817. not(pobjectdef(p^.left^.resulttype)^.is_class) then
  818. CGMessage(type_e_mismatch);
  819. { the operands must be related }
  820. if (not(pobjectdef(p^.left^.resulttype)^.is_related(
  821. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  822. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.is_related(
  823. pobjectdef(p^.left^.resulttype)))) then
  824. CGMessage(type_e_mismatch);
  825. set_location(p^.location,p^.left^.location);
  826. p^.resulttype:=pclassrefdef(p^.right^.resulttype)^.definition;
  827. end;
  828. end.
  829. {
  830. $Log$
  831. Revision 1.47 1999-09-11 09:08:34 florian
  832. * fixed bug 596
  833. * fixed some problems with procedure variables and procedures of object,
  834. especially in TP mode. Procedure of object doesn't apply only to classes,
  835. it is also allowed for objects !!
  836. Revision 1.46 1999/08/13 15:43:59 peter
  837. * fixed proc->procvar conversion for tp_procvar mode, it now uses
  838. also the genload(method)call() function
  839. Revision 1.45 1999/08/07 14:21:04 florian
  840. * some small problems fixed
  841. Revision 1.44 1999/08/04 13:03:14 jonas
  842. * all tokens now start with an underscore
  843. * PowerPC compiles!!
  844. Revision 1.43 1999/08/04 00:23:36 florian
  845. * renamed i386asm and i386base to cpuasm and cpubase
  846. Revision 1.42 1999/08/03 22:03:28 peter
  847. * moved bitmask constants to sets
  848. * some other type/const renamings
  849. Revision 1.41 1999/06/30 22:16:23 florian
  850. * use of is_ordinal checked: often a qword/int64 isn't allowed (case/for ...)
  851. * small qword problems fixed
  852. Revision 1.40 1999/06/28 22:29:21 florian
  853. * qword division fixed
  854. + code for qword/int64 type casting added:
  855. range checking isn't implemented yet
  856. Revision 1.39 1999/06/28 19:30:07 peter
  857. * merged
  858. Revision 1.35.2.5 1999/06/28 19:07:47 peter
  859. * remove cstring->string typeconvs after updating cstringn
  860. Revision 1.35.2.4 1999/06/28 00:33:50 pierre
  861. * better error position bug0269
  862. Revision 1.35.2.3 1999/06/17 12:51:48 pierre
  863. * changed is_assignment_overloaded into
  864. function assignment_overloaded : pprocdef
  865. to allow overloading of assignment with only different result type
  866. Revision 1.35.2.2 1999/06/15 18:54:53 peter
  867. * more procvar fixes
  868. Revision 1.35.2.1 1999/06/13 22:39:19 peter
  869. * use proc_to_procvar_equal
  870. Revision 1.35 1999/06/02 22:44:24 pierre
  871. * previous wrong log corrected
  872. Revision 1.34 1999/06/02 22:25:54 pierre
  873. * changed $ifdef FPC @ into $ifndef TP
  874. + debug note about longint to pointer conversion
  875. Revision 1.33 1999/05/27 19:45:15 peter
  876. * removed oldasm
  877. * plabel -> pasmlabel
  878. * -a switches to source writing automaticly
  879. * assembler readers OOPed
  880. * asmsymbol automaticly external
  881. * jumptables and other label fixes for asm readers
  882. Revision 1.32 1999/05/20 14:58:28 peter
  883. * fixed arrayconstruct->set conversion which didn't work for enum sets
  884. Revision 1.31 1999/05/13 21:59:52 peter
  885. * removed oldppu code
  886. * warning if objpas is loaded from uses
  887. * first things for new deref writing
  888. Revision 1.30 1999/05/12 00:20:00 peter
  889. * removed R_DEFAULT_SEG
  890. * uniform float names
  891. Revision 1.29 1999/05/09 11:37:05 peter
  892. * fixed order of arguments for incompatible types message
  893. Revision 1.28 1999/05/06 09:05:34 peter
  894. * generic write_float and str_float
  895. * fixed constant float conversions
  896. Revision 1.27 1999/05/01 13:24:48 peter
  897. * merged nasm compiler
  898. * old asm moved to oldasm/
  899. Revision 1.26 1999/04/26 13:31:58 peter
  900. * release storenumber,double_checksum
  901. Revision 1.25 1999/04/22 10:49:09 peter
  902. * fixed pchar to string location
  903. Revision 1.24 1999/04/21 09:44:01 peter
  904. * storenumber works
  905. * fixed some typos in double_checksum
  906. + incompatible types type1 and type2 message (with storenumber)
  907. Revision 1.23 1999/04/15 08:56:24 peter
  908. * fixed bool-bool conversion
  909. Revision 1.22 1999/04/08 09:47:31 pierre
  910. * warn if uninitilized local vars are used in IS or AS statements
  911. Revision 1.21 1999/03/06 17:25:20 peter
  912. * moved comp<->real warning so it doesn't occure everytime that
  913. isconvertable is called with
  914. Revision 1.20 1999/03/02 18:24:23 peter
  915. * fixed overloading of array of char
  916. Revision 1.19 1999/02/22 02:15:46 peter
  917. * updates for ag386bin
  918. Revision 1.18 1999/01/27 14:56:57 pierre
  919. * typo error corrected solves bug0190 and bug0204
  920. Revision 1.17 1999/01/27 14:15:25 pierre
  921. * bug0209 corrected (introduce while solving other bool to int related bugs)
  922. Revision 1.16 1999/01/27 13:02:21 pierre
  923. boolean to int conversion problems bug0205 bug0208
  924. Revision 1.15 1999/01/27 00:13:57 florian
  925. * "procedure of object"-stuff fixed
  926. Revision 1.14 1999/01/19 12:17:45 peter
  927. * removed rangecheck warning which was shown twice
  928. Revision 1.13 1998/12/30 22:13:47 peter
  929. * if explicit cnv then also handle the ordinal consts direct
  930. Revision 1.12 1998/12/11 00:03:53 peter
  931. + globtype,tokens,version unit splitted from globals
  932. Revision 1.11 1998/12/04 10:18:12 florian
  933. * some stuff for procedures of object added
  934. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  935. Revision 1.10 1998/11/29 12:40:24 peter
  936. * newcnv -> not oldcnv
  937. Revision 1.9 1998/11/26 13:10:43 peter
  938. * new int - int conversion -dNEWCNV
  939. * some function renamings
  940. Revision 1.8 1998/11/05 12:03:03 peter
  941. * released useansistring
  942. * removed -Sv, its now available in fpc modes
  943. Revision 1.7 1998/10/23 11:58:27 florian
  944. * better code generation for s:=s+[b] if b is in the range of
  945. a small set and s is also a small set
  946. Revision 1.6 1998/10/21 15:12:58 pierre
  947. * bug fix for IOCHECK inside a procedure with iocheck modifier
  948. * removed the GPF for unexistant overloading
  949. (firstcall was called with procedinition=nil !)
  950. * changed typen to what Florian proposed
  951. gentypenode(p : pdef) sets the typenodetype field
  952. and resulttype is only set if inside bt_type block !
  953. Revision 1.5 1998/10/07 10:38:55 peter
  954. * forgot a firstpass in arrayconstruct2set
  955. Revision 1.4 1998/10/05 21:33:32 peter
  956. * fixed 161,165,166,167,168
  957. Revision 1.3 1998/09/27 10:16:26 florian
  958. * type casts pchar<->ansistring fixed
  959. * ansistring[..] calls does now an unique call
  960. Revision 1.2 1998/09/24 23:49:22 peter
  961. + aktmodeswitches
  962. Revision 1.1 1998/09/23 20:42:24 peter
  963. * splitted pass_1
  964. }