tcinl.pas 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Type checking and register allocation for inline 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. unit tcinl;
  19. interface
  20. uses
  21. tree;
  22. procedure firstinline(var p : ptree);
  23. implementation
  24. uses
  25. cobjects,verbose,globals,systems,
  26. globtype,
  27. symtable,aasm,types,
  28. hcodegen,htypechk,pass_1,
  29. tccal
  30. {$ifdef i386}
  31. ,i386base
  32. ,tgeni386
  33. {$endif}
  34. {$ifdef m68k}
  35. ,m68k,tgen68k
  36. {$endif}
  37. ;
  38. {*****************************************************************************
  39. FirstInLine
  40. *****************************************************************************}
  41. procedure firstinline(var p : ptree);
  42. var
  43. vl,vl2 : longint;
  44. vr : bestreal;
  45. p1,hp,hpp : ptree;
  46. {$ifndef NOCOLONCHECK}
  47. frac_para,length_para : ptree;
  48. {$endif ndef NOCOLONCHECK}
  49. store_count_ref,
  50. isreal,
  51. dowrite,
  52. store_valid,
  53. file_is_typed : boolean;
  54. procedure do_lowhigh(adef : pdef);
  55. var
  56. v : longint;
  57. enum : penumsym;
  58. begin
  59. case Adef^.deftype of
  60. orddef:
  61. begin
  62. if p^.inlinenumber=in_low_x then
  63. v:=porddef(Adef)^.low
  64. else
  65. v:=porddef(Adef)^.high;
  66. hp:=genordinalconstnode(v,adef);
  67. firstpass(hp);
  68. disposetree(p);
  69. p:=hp;
  70. end;
  71. enumdef:
  72. begin
  73. enum:=Penumdef(Adef)^.firstenum;
  74. if p^.inlinenumber=in_high_x then
  75. while enum^.nextenum<>nil do
  76. enum:=enum^.nextenum;
  77. hp:=genenumnode(enum);
  78. disposetree(p);
  79. p:=hp;
  80. end
  81. end;
  82. end;
  83. begin
  84. store_valid:=must_be_valid;
  85. store_count_ref:=count_ref;
  86. count_ref:=false;
  87. if not (p^.inlinenumber in [in_read_x,in_readln_x,in_sizeof_x,
  88. in_typeof_x,in_ord_x,in_str_x_string,
  89. {$IfnDef OLDVAL}
  90. in_val_x,
  91. {$EndIf OLDVAL}
  92. in_reset_typedfile,in_rewrite_typedfile]) then
  93. must_be_valid:=true
  94. else
  95. must_be_valid:=false;
  96. { if we handle writeln; p^.left contains no valid address }
  97. if assigned(p^.left) then
  98. begin
  99. if p^.left^.treetype=callparan then
  100. firstcallparan(p^.left,nil)
  101. else
  102. firstpass(p^.left);
  103. left_right_max(p);
  104. set_location(p^.location,p^.left^.location);
  105. end;
  106. { handle intern constant functions in separate case }
  107. if p^.inlineconst then
  108. begin
  109. { no parameters? }
  110. if not assigned(p^.left) then
  111. begin
  112. case p^.inlinenumber of
  113. in_const_pi :
  114. hp:=genrealconstnode(pi,bestrealdef^);
  115. else
  116. internalerror(89);
  117. end;
  118. end
  119. else
  120. { process constant expression with parameter }
  121. begin
  122. vl:=0;
  123. vl2:=0; { second parameter Ex: ptr(vl,vl2) }
  124. vr:=0;
  125. isreal:=false;
  126. case p^.left^.treetype of
  127. realconstn :
  128. begin
  129. isreal:=true;
  130. vr:=p^.left^.value_real;
  131. end;
  132. ordconstn :
  133. vl:=p^.left^.value;
  134. callparan :
  135. begin
  136. { both exists, else it was not generated }
  137. vl:=p^.left^.left^.value;
  138. vl2:=p^.left^.right^.left^.value;
  139. end;
  140. else
  141. CGMessage(cg_e_illegal_expression);
  142. end;
  143. case p^.inlinenumber of
  144. in_const_trunc :
  145. begin
  146. if isreal then
  147. begin
  148. if (vr>=2147483648.0) or (vr<=-2147483649.0) then
  149. begin
  150. CGMessage(parser_e_range_check_error);
  151. hp:=genordinalconstnode(1,s32bitdef)
  152. end
  153. else
  154. hp:=genordinalconstnode(trunc(vr),s32bitdef)
  155. end
  156. else
  157. hp:=genordinalconstnode(trunc(vl),s32bitdef);
  158. end;
  159. in_const_round :
  160. begin
  161. if isreal then
  162. begin
  163. if (vr>=2147483647.5) or (vr<=-2147483648.5) then
  164. begin
  165. CGMessage(parser_e_range_check_error);
  166. hp:=genordinalconstnode(1,s32bitdef)
  167. end
  168. else
  169. hp:=genordinalconstnode(round(vr),s32bitdef)
  170. end
  171. else
  172. hp:=genordinalconstnode(round(vl),s32bitdef);
  173. end;
  174. in_const_frac :
  175. begin
  176. if isreal then
  177. hp:=genrealconstnode(frac(vr),bestrealdef^)
  178. else
  179. hp:=genrealconstnode(frac(vl),bestrealdef^);
  180. end;
  181. in_const_int :
  182. begin
  183. if isreal then
  184. hp:=genrealconstnode(int(vr),bestrealdef^)
  185. else
  186. hp:=genrealconstnode(int(vl),bestrealdef^);
  187. end;
  188. in_const_abs :
  189. begin
  190. if isreal then
  191. hp:=genrealconstnode(abs(vr),bestrealdef^)
  192. else
  193. hp:=genordinalconstnode(abs(vl),p^.left^.resulttype);
  194. end;
  195. in_const_sqr :
  196. begin
  197. if isreal then
  198. hp:=genrealconstnode(sqr(vr),bestrealdef^)
  199. else
  200. hp:=genordinalconstnode(sqr(vl),p^.left^.resulttype);
  201. end;
  202. in_const_odd :
  203. begin
  204. if isreal then
  205. CGMessage(type_e_integer_expr_expected)
  206. else
  207. hp:=genordinalconstnode(byte(odd(vl)),booldef);
  208. end;
  209. in_const_swap_word :
  210. begin
  211. if isreal then
  212. CGMessage(type_e_integer_expr_expected)
  213. else
  214. hp:=genordinalconstnode((vl and $ff) shl 8+(vl shr 8),p^.left^.resulttype);
  215. end;
  216. in_const_swap_long :
  217. begin
  218. if isreal then
  219. CGMessage(type_e_mismatch)
  220. else
  221. hp:=genordinalconstnode((vl and $ffff) shl 16+(vl shr 16),p^.left^.resulttype);
  222. end;
  223. in_const_ptr :
  224. begin
  225. if isreal then
  226. CGMessage(type_e_mismatch)
  227. else
  228. hp:=genordinalconstnode((vl2 shl 16) or vl,voidpointerdef);
  229. end;
  230. in_const_sqrt :
  231. begin
  232. if isreal then
  233. begin
  234. if vr<0.0 then
  235. message(cg_w_may_wrong_math_argument);
  236. hp:=genrealconstnode(sqrt(vr),bestrealdef^)
  237. end
  238. else
  239. begin
  240. if vl<0 then
  241. message(cg_w_may_wrong_math_argument);
  242. hp:=genrealconstnode(sqrt(vl),bestrealdef^);
  243. end;
  244. end;
  245. in_const_arctan :
  246. begin
  247. if isreal then
  248. hp:=genrealconstnode(arctan(vr),bestrealdef^)
  249. else
  250. hp:=genrealconstnode(arctan(vl),bestrealdef^);
  251. end;
  252. in_const_cos :
  253. begin
  254. if isreal then
  255. hp:=genrealconstnode(cos(vr),bestrealdef^)
  256. else
  257. hp:=genrealconstnode(cos(vl),bestrealdef^);
  258. end;
  259. in_const_sin :
  260. begin
  261. if isreal then
  262. hp:=genrealconstnode(sin(vr),bestrealdef^)
  263. else
  264. hp:=genrealconstnode(sin(vl),bestrealdef^);
  265. end;
  266. in_const_exp :
  267. begin
  268. if isreal then
  269. hp:=genrealconstnode(exp(vr),bestrealdef^)
  270. else
  271. hp:=genrealconstnode(exp(vl),bestrealdef^);
  272. end;
  273. in_const_ln :
  274. begin
  275. if isreal then
  276. begin
  277. if vr<=0.0 then
  278. message(cg_w_may_wrong_math_argument);
  279. hp:=genrealconstnode(ln(vr),bestrealdef^)
  280. end
  281. else
  282. begin
  283. if vl<=0 then
  284. message(cg_w_may_wrong_math_argument);
  285. hp:=genrealconstnode(ln(vl),bestrealdef^);
  286. end;
  287. end;
  288. else
  289. internalerror(88);
  290. end;
  291. end;
  292. disposetree(p);
  293. firstpass(hp);
  294. p:=hp;
  295. end
  296. else
  297. begin
  298. case p^.inlinenumber of
  299. in_lo_long,
  300. in_hi_long,
  301. in_lo_word,
  302. in_hi_word:
  303. begin
  304. if p^.registers32<1 then
  305. p^.registers32:=1;
  306. if p^.inlinenumber in [in_lo_word,in_hi_word] then
  307. p^.resulttype:=u8bitdef
  308. else
  309. begin
  310. p^.resulttype:=u16bitdef;
  311. if (m_tp in aktmodeswitches) or
  312. (m_delphi in aktmodeswitches) then
  313. CGMessage(type_w_maybe_wrong_hi_lo);
  314. end;
  315. p^.location.loc:=LOC_REGISTER;
  316. if not is_integer(p^.left^.resulttype) then
  317. CGMessage(type_e_mismatch)
  318. else
  319. begin
  320. if p^.left^.treetype=ordconstn then
  321. begin
  322. case p^.inlinenumber of
  323. in_lo_word : hp:=genordinalconstnode(p^.left^.value and $ff,p^.left^.resulttype);
  324. in_hi_word : hp:=genordinalconstnode(p^.left^.value shr 8,p^.left^.resulttype);
  325. in_lo_long : hp:=genordinalconstnode(p^.left^.value and $ffff,p^.left^.resulttype);
  326. in_hi_long : hp:=genordinalconstnode(p^.left^.value shr 16,p^.left^.resulttype);
  327. end;
  328. disposetree(p);
  329. firstpass(hp);
  330. p:=hp;
  331. end;
  332. end;
  333. end;
  334. in_sizeof_x:
  335. begin
  336. if push_high_param(p^.left^.resulttype) then
  337. begin
  338. getsymonlyin(p^.left^.symtable,'high'+pvarsym(p^.left^.symtableentry)^.name);
  339. hp:=gennode(addn,genloadnode(pvarsym(srsym),p^.left^.symtable),
  340. genordinalconstnode(1,s32bitdef));
  341. if (p^.left^.resulttype^.deftype=arraydef) and
  342. (parraydef(p^.left^.resulttype)^.elesize<>1) then
  343. hp:=gennode(muln,hp,genordinalconstnode(parraydef(p^.left^.resulttype)^.elesize,s32bitdef));
  344. disposetree(p);
  345. p:=hp;
  346. firstpass(p);
  347. end;
  348. if p^.registers32<1 then
  349. p^.registers32:=1;
  350. p^.resulttype:=s32bitdef;
  351. p^.location.loc:=LOC_REGISTER;
  352. end;
  353. in_typeof_x:
  354. begin
  355. if p^.registers32<1 then
  356. p^.registers32:=1;
  357. p^.location.loc:=LOC_REGISTER;
  358. p^.resulttype:=voidpointerdef;
  359. end;
  360. in_ord_x:
  361. begin
  362. if (p^.left^.treetype=ordconstn) then
  363. begin
  364. hp:=genordinalconstnode(p^.left^.value,s32bitdef);
  365. disposetree(p);
  366. p:=hp;
  367. firstpass(p);
  368. end
  369. else
  370. begin
  371. if (p^.left^.resulttype^.deftype=orddef) then
  372. if (porddef(p^.left^.resulttype)^.typ in [uchar,bool8bit]) then
  373. begin
  374. if porddef(p^.left^.resulttype)^.typ=bool8bit then
  375. begin
  376. hp:=gentypeconvnode(p^.left,u8bitdef);
  377. putnode(p);
  378. p:=hp;
  379. p^.convtyp:=tc_bool_2_int;
  380. p^.explizit:=true;
  381. firstpass(p);
  382. end
  383. else
  384. begin
  385. hp:=gentypeconvnode(p^.left,u8bitdef);
  386. putnode(p);
  387. p:=hp;
  388. p^.explizit:=true;
  389. firstpass(p);
  390. end;
  391. end
  392. { can this happen ? }
  393. else if (porddef(p^.left^.resulttype)^.typ=uvoid) then
  394. CGMessage(type_e_mismatch)
  395. else
  396. { all other orddef need no transformation }
  397. begin
  398. hp:=p^.left;
  399. putnode(p);
  400. p:=hp;
  401. end
  402. else if (p^.left^.resulttype^.deftype=enumdef) then
  403. begin
  404. hp:=gentypeconvnode(p^.left,s32bitdef);
  405. putnode(p);
  406. p:=hp;
  407. p^.explizit:=true;
  408. firstpass(p);
  409. end
  410. else
  411. begin
  412. { can anything else be ord() ?}
  413. CGMessage(type_e_mismatch);
  414. end;
  415. end;
  416. end;
  417. in_chr_byte:
  418. begin
  419. hp:=gentypeconvnode(p^.left,cchardef);
  420. putnode(p);
  421. p:=hp;
  422. p^.explizit:=true;
  423. firstpass(p);
  424. end;
  425. in_length_string:
  426. begin
  427. if is_ansistring(p^.left^.resulttype) then
  428. p^.resulttype:=s32bitdef
  429. else
  430. p^.resulttype:=u8bitdef;
  431. { we don't need string conversations here }
  432. if (p^.left^.treetype=typeconvn) and
  433. (p^.left^.left^.resulttype^.deftype=stringdef) then
  434. begin
  435. hp:=p^.left^.left;
  436. putnode(p^.left);
  437. p^.left:=hp;
  438. end;
  439. { check the type, must be string or char }
  440. if (p^.left^.resulttype^.deftype<>stringdef) and
  441. (not is_char(p^.left^.resulttype)) then
  442. CGMessage(type_e_mismatch);
  443. { evaluates length of constant strings direct }
  444. if (p^.left^.treetype=stringconstn) then
  445. begin
  446. hp:=genordinalconstnode(p^.left^.length,s32bitdef);
  447. disposetree(p);
  448. firstpass(hp);
  449. p:=hp;
  450. end
  451. { length of char is one allways }
  452. else if is_constcharnode(p^.left) then
  453. begin
  454. hp:=genordinalconstnode(1,s32bitdef);
  455. disposetree(p);
  456. firstpass(hp);
  457. p:=hp;
  458. end;
  459. end;
  460. in_assigned_x:
  461. begin
  462. p^.resulttype:=booldef;
  463. p^.location.loc:=LOC_FLAGS;
  464. end;
  465. in_pred_x,
  466. in_succ_x:
  467. begin
  468. inc(p^.registers32);
  469. p^.resulttype:=p^.left^.resulttype;
  470. p^.location.loc:=LOC_REGISTER;
  471. if not is_ordinal(p^.resulttype) then
  472. CGMessage(type_e_ordinal_expr_expected)
  473. else
  474. begin
  475. if (p^.resulttype^.deftype=enumdef) and
  476. (penumdef(p^.resulttype)^.has_jumps) then
  477. CGMessage(type_e_succ_and_pred_enums_with_assign_not_possible)
  478. else
  479. if p^.left^.treetype=ordconstn then
  480. begin
  481. if p^.inlinenumber=in_succ_x then
  482. hp:=genordinalconstnode(p^.left^.value+1,p^.left^.resulttype)
  483. else
  484. hp:=genordinalconstnode(p^.left^.value-1,p^.left^.resulttype);
  485. disposetree(p);
  486. firstpass(hp);
  487. p:=hp;
  488. end;
  489. end;
  490. end;
  491. in_inc_x,
  492. in_dec_x:
  493. begin
  494. p^.resulttype:=voiddef;
  495. if assigned(p^.left) then
  496. begin
  497. firstcallparan(p^.left,nil);
  498. if codegenerror then
  499. exit;
  500. { first param must be var }
  501. if is_constnode(p^.left^.left) then
  502. CGMessage(type_e_variable_id_expected);
  503. { check type }
  504. if (p^.left^.resulttype^.deftype in [enumdef,pointerdef]) or
  505. is_ordinal(p^.left^.resulttype) then
  506. begin
  507. { two paras ? }
  508. if assigned(p^.left^.right) then
  509. begin
  510. { insert a type conversion }
  511. { the second param is always longint }
  512. p^.left^.right^.left:=gentypeconvnode(p^.left^.right^.left,s32bitdef);
  513. { check the type conversion }
  514. firstpass(p^.left^.right^.left);
  515. { need we an additional register ? }
  516. if not(is_constintnode(p^.left^.right^.left)) and
  517. (p^.left^.right^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) and
  518. (p^.left^.right^.left^.registers32<1) then
  519. inc(p^.registers32);
  520. if assigned(p^.left^.right^.right) then
  521. CGMessage(cg_e_illegal_expression);
  522. end;
  523. end
  524. else
  525. CGMessage(type_e_ordinal_expr_expected);
  526. end
  527. else
  528. CGMessage(type_e_mismatch);
  529. end;
  530. in_read_x,
  531. in_readln_x,
  532. in_write_x,
  533. in_writeln_x :
  534. begin
  535. { needs a call }
  536. procinfo.flags:=procinfo.flags or pi_do_call;
  537. p^.resulttype:=voiddef;
  538. { we must know if it is a typed file or not }
  539. { but we must first do the firstpass for it }
  540. file_is_typed:=false;
  541. if assigned(p^.left) then
  542. begin
  543. dowrite:=(p^.inlinenumber in [in_write_x,in_writeln_x]);
  544. firstcallparan(p^.left,nil);
  545. { now we can check }
  546. hp:=p^.left;
  547. while assigned(hp^.right) do
  548. hp:=hp^.right;
  549. { if resulttype is not assigned, then automatically }
  550. { file is not typed. }
  551. if assigned(hp) and assigned(hp^.resulttype) then
  552. Begin
  553. if (hp^.resulttype^.deftype=filedef) and
  554. (pfiledef(hp^.resulttype)^.filetype=ft_typed) then
  555. begin
  556. file_is_typed:=true;
  557. { test the type }
  558. hpp:=p^.left;
  559. while (hpp<>hp) do
  560. begin
  561. if (hpp^.left^.treetype=typen) then
  562. CGMessage(type_e_cant_read_write_type);
  563. if not is_equal(hpp^.resulttype,pfiledef(hp^.resulttype)^.typed_as) then
  564. CGMessage(type_e_mismatch);
  565. { generate the high() value for the shortstring }
  566. if ((not dowrite) and is_shortstring(hpp^.left^.resulttype)) or
  567. (is_chararray(hpp^.left^.resulttype)) then
  568. gen_high_tree(hpp,true);
  569. hpp:=hpp^.right;
  570. end;
  571. end;
  572. end; { endif assigned(hp) }
  573. { insert type conversions for write(ln) }
  574. if (not file_is_typed) then
  575. begin
  576. hp:=p^.left;
  577. while assigned(hp) do
  578. begin
  579. if (hp^.left^.treetype=typen) then
  580. CGMessage(type_e_cant_read_write_type);
  581. if assigned(hp^.left^.resulttype) then
  582. begin
  583. isreal:=false;
  584. { support writeln(procvar) for tp7 }
  585. if (m_tp_procvar in aktmodeswitches) and (hp^.left^.resulttype^.deftype=procvardef) then
  586. begin
  587. p1:=gencallnode(nil,nil);
  588. p1^.right:=hp^.left;
  589. p1^.resulttype:=pprocvardef(hp^.left^.resulttype)^.retdef;
  590. firstpass(p1);
  591. hp^.left:=p1;
  592. end;
  593. case hp^.left^.resulttype^.deftype of
  594. filedef :
  595. begin
  596. { only allowed as first parameter }
  597. if assigned(hp^.right) then
  598. CGMessage(type_e_cant_read_write_type);
  599. end;
  600. stringdef :
  601. begin
  602. { generate the high() value for the shortstring }
  603. if (not dowrite) and
  604. is_shortstring(hp^.left^.resulttype) then
  605. gen_high_tree(hp,true);
  606. end;
  607. pointerdef :
  608. begin
  609. if not is_pchar(hp^.left^.resulttype) then
  610. CGMessage(type_e_cant_read_write_type);
  611. end;
  612. floatdef :
  613. begin
  614. isreal:=true;
  615. end;
  616. orddef :
  617. begin
  618. case porddef(hp^.left^.resulttype)^.typ of
  619. uchar,
  620. u32bit,s32bit,
  621. u64bit,s64bitint:
  622. ;
  623. u8bit,s8bit,
  624. u16bit,s16bit :
  625. if dowrite then
  626. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  627. bool8bit,
  628. bool16bit,
  629. bool32bit :
  630. if dowrite then
  631. hp^.left:=gentypeconvnode(hp^.left,booldef)
  632. else
  633. CGMessage(type_e_cant_read_write_type);
  634. else
  635. CGMessage(type_e_cant_read_write_type);
  636. end;
  637. end;
  638. arraydef :
  639. begin
  640. if is_chararray(hp^.left^.resulttype) then
  641. gen_high_tree(hp,true)
  642. else
  643. CGMessage(type_e_cant_read_write_type);
  644. end;
  645. else
  646. CGMessage(type_e_cant_read_write_type);
  647. end;
  648. { some format options ? }
  649. if hp^.is_colon_para then
  650. begin
  651. if hp^.right^.is_colon_para then
  652. begin
  653. frac_para:=hp;
  654. length_para:=hp^.right;
  655. hp:=hp^.right;
  656. hpp:=hp^.right;
  657. end
  658. else
  659. begin
  660. length_para:=hp;
  661. frac_para:=nil;
  662. hpp:=hp^.right;
  663. end;
  664. isreal:=hpp^.resulttype^.deftype=floatdef;
  665. if (not is_integer(length_para^.resulttype)) then
  666. CGMessage(type_e_integer_expr_expected)
  667. else
  668. length_para^.left:=gentypeconvnode(length_para^.left,s32bitdef);
  669. if assigned(frac_para) then
  670. begin
  671. if isreal then
  672. begin
  673. if (not is_integer(frac_para^.resulttype)) then
  674. CGMessage(type_e_integer_expr_expected)
  675. else
  676. frac_para^.left:=gentypeconvnode(frac_para^.left,s32bitdef);
  677. end
  678. else
  679. CGMessage(parser_e_illegal_colon_qualifier);
  680. end;
  681. { do the checking for the colon'd arg }
  682. hp:=length_para;
  683. end;
  684. end;
  685. hp:=hp^.right;
  686. end;
  687. end;
  688. { pass all parameters again for the typeconversions }
  689. if codegenerror then
  690. exit;
  691. must_be_valid:=true;
  692. firstcallparan(p^.left,nil);
  693. { calc registers }
  694. left_right_max(p);
  695. end;
  696. end;
  697. in_settextbuf_file_x :
  698. begin
  699. { warning here p^.left is the callparannode
  700. not the argument directly }
  701. { p^.left^.left is text var }
  702. { p^.left^.right^.left is the buffer var }
  703. { firstcallparan(p^.left,nil);
  704. already done in firstcalln }
  705. { now we know the type of buffer }
  706. getsymonlyin(systemunit,'SETTEXTBUF');
  707. hp:=gencallnode(pprocsym(srsym),systemunit);
  708. hp^.left:=gencallparanode(
  709. genordinalconstnode(p^.left^.left^.resulttype^.size,s32bitdef),p^.left);
  710. putnode(p);
  711. p:=hp;
  712. firstpass(p);
  713. end;
  714. { the firstpass of the arg has been done in firstcalln ? }
  715. in_reset_typedfile,
  716. in_rewrite_typedfile :
  717. begin
  718. procinfo.flags:=procinfo.flags or pi_do_call;
  719. { to be sure the right definition is loaded }
  720. p^.left^.resulttype:=nil;
  721. firstpass(p^.left);
  722. p^.resulttype:=voiddef;
  723. end;
  724. in_str_x_string :
  725. begin
  726. procinfo.flags:=procinfo.flags or pi_do_call;
  727. p^.resulttype:=voiddef;
  728. { check the amount of parameters }
  729. if not(assigned(p^.left)) or
  730. not(assigned(p^.left^.right)) then
  731. begin
  732. CGMessage(parser_e_wrong_parameter_size);
  733. exit;
  734. end;
  735. { first pass just the string for first local use }
  736. hp:=p^.left^.right;
  737. must_be_valid:=false;
  738. count_ref:=true;
  739. p^.left^.right:=nil;
  740. firstcallparan(p^.left,nil);
  741. { remove warning when result is passed }
  742. if (p^.left^.left^.treetype=funcretn) then
  743. procinfo.funcret_is_valid:=true;
  744. must_be_valid:=true;
  745. p^.left^.right:=hp;
  746. firstcallparan(p^.left^.right,nil);
  747. hp:=p^.left;
  748. { valid string ? }
  749. if not assigned(hp) or
  750. (hp^.left^.resulttype^.deftype<>stringdef) or
  751. (hp^.right=nil) or
  752. (hp^.left^.location.loc<>LOC_REFERENCE) then
  753. CGMessage(cg_e_illegal_expression);
  754. { generate the high() value for the shortstring }
  755. if is_shortstring(hp^.left^.resulttype) then
  756. gen_high_tree(hp,true);
  757. { !!!! check length of string }
  758. while assigned(hp^.right) do
  759. hp:=hp^.right;
  760. { check and convert the first param }
  761. if hp^.is_colon_para then
  762. CGMessage(cg_e_illegal_expression);
  763. isreal:=false;
  764. case hp^.resulttype^.deftype of
  765. orddef :
  766. begin
  767. case porddef(hp^.left^.resulttype)^.typ of
  768. u32bit,s32bit,
  769. s64bitint,u64bit:
  770. ;
  771. u8bit,s8bit,
  772. u16bit,s16bit:
  773. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  774. else
  775. CGMessage(type_e_integer_or_real_expr_expected);
  776. end;
  777. end;
  778. floatdef :
  779. begin
  780. isreal:=true;
  781. end;
  782. else
  783. CGMessage(type_e_integer_or_real_expr_expected);
  784. end;
  785. { some format options ? }
  786. hpp:=p^.left^.right;
  787. if assigned(hpp) and hpp^.is_colon_para then
  788. begin
  789. if (not is_integer(hpp^.resulttype)) then
  790. CGMessage(type_e_integer_expr_expected)
  791. else
  792. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  793. hpp:=hpp^.right;
  794. if assigned(hpp) and hpp^.is_colon_para then
  795. begin
  796. if isreal then
  797. begin
  798. if (not is_integer(hpp^.resulttype)) then
  799. CGMessage(type_e_integer_expr_expected)
  800. else
  801. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  802. end
  803. else
  804. CGMessage(parser_e_illegal_colon_qualifier);
  805. end;
  806. end;
  807. { for first local use }
  808. must_be_valid:=false;
  809. count_ref:=true;
  810. { pass all parameters again for the typeconversions }
  811. if codegenerror then
  812. exit;
  813. must_be_valid:=true;
  814. firstcallparan(p^.left,nil);
  815. { calc registers }
  816. left_right_max(p);
  817. end;
  818. {$IfnDef OLDVAL}
  819. in_val_x :
  820. begin
  821. procinfo.flags:=procinfo.flags or pi_do_call;
  822. p^.resulttype:=voiddef;
  823. { check the amount of parameters }
  824. if not(assigned(p^.left)) or
  825. not(assigned(p^.left^.right)) then
  826. begin
  827. CGMessage(parser_e_wrong_parameter_size);
  828. exit;
  829. end;
  830. If Assigned(p^.left^.right^.right) Then
  831. {there is a "code" parameter}
  832. Begin
  833. { first pass just the code parameter for first local use}
  834. hp := p^.left^.right;
  835. p^.left^.right := nil;
  836. must_be_valid := false;
  837. count_ref := true;
  838. firstcallparan(p^.left, nil);
  839. if codegenerror then exit;
  840. p^.left^.right := hp;
  841. {code has to be a var parameter}
  842. if (p^.left^.left^.location.loc<>LOC_REFERENCE) then
  843. CGMessage(type_e_variable_id_expected)
  844. else
  845. if (p^.left^.left^.resulttype^.deftype <> orddef) or
  846. not(porddef(p^.left^.left^.resulttype)^.typ in
  847. [u16bit,s16bit,u32bit,s32bit]) then
  848. CGMessage(type_e_mismatch);
  849. hpp := p^.left^.right
  850. End
  851. Else hpp := p^.left;
  852. {now hpp = the destination value tree}
  853. { first pass just the destination parameter for first local use}
  854. hp:=hpp^.right;
  855. must_be_valid:=false;
  856. count_ref:=true;
  857. hpp^.right:=nil;
  858. {hpp = destination}
  859. firstcallparan(hpp,nil);
  860. if codegenerror then
  861. exit;
  862. { remove warning when result is passed }
  863. if (hpp^.left^.treetype=funcretn) then
  864. procinfo.funcret_is_valid:=true;
  865. hpp^.right := hp;
  866. if (hpp^.left^.location.loc<>LOC_REFERENCE) then
  867. CGMessage(type_e_variable_id_expected)
  868. else
  869. If Not((hpp^.left^.resulttype^.deftype = floatdef) or
  870. ((hpp^.left^.resulttype^.deftype = orddef) And
  871. (POrdDef(hpp^.left^.resulttype)^.typ in
  872. [u32bit,s32bit,{s64bitint,u64bit, -- not supported yet in RTL}
  873. u8bit,s8bit,u16bit,s16bit])))
  874. Then CGMessage(type_e_mismatch);
  875. must_be_valid:=true;
  876. {hp = source (String)}
  877. count_ref := false;
  878. must_be_valid := true;
  879. firstcallparan(hp,nil);
  880. if codegenerror then
  881. exit;
  882. { if not a stringdef then insert a type conv which
  883. does the other type checking }
  884. If (hp^.left^.resulttype^.deftype<>stringdef) then
  885. begin
  886. hp^.left:=gentypeconvnode(hp^.left,cshortstringdef);
  887. firstpass(hp);
  888. end;
  889. { calc registers }
  890. left_right_max(p);
  891. { val doesn't calculate the registers really }
  892. { correct, we need one register extra (FK) }
  893. inc(p^.registers32,1);
  894. end;
  895. {$EndIf OLDVAL}
  896. in_include_x_y,
  897. in_exclude_x_y:
  898. begin
  899. p^.resulttype:=voiddef;
  900. if assigned(p^.left) then
  901. begin
  902. firstcallparan(p^.left,nil);
  903. p^.registers32:=p^.left^.registers32;
  904. p^.registersfpu:=p^.left^.registersfpu;
  905. {$ifdef SUPPORT_MMX}
  906. p^.registersmmx:=p^.left^.registersmmx;
  907. {$endif SUPPORT_MMX}
  908. { remove warning when result is passed }
  909. if (p^.left^.left^.treetype=funcretn) then
  910. procinfo.funcret_is_valid:=true;
  911. { first param must be var }
  912. if (p^.left^.left^.location.loc<>LOC_REFERENCE) and
  913. (p^.left^.left^.location.loc<>LOC_CREGISTER) then
  914. CGMessage(cg_e_illegal_expression);
  915. { check type }
  916. if (p^.left^.resulttype^.deftype=setdef) then
  917. begin
  918. { two paras ? }
  919. if assigned(p^.left^.right) then
  920. begin
  921. { insert a type conversion }
  922. { to the type of the set elements }
  923. p^.left^.right^.left:=gentypeconvnode(
  924. p^.left^.right^.left,
  925. psetdef(p^.left^.resulttype)^.setof);
  926. { check the type conversion }
  927. firstpass(p^.left^.right^.left);
  928. { only three parameters are allowed }
  929. if assigned(p^.left^.right^.right) then
  930. CGMessage(cg_e_illegal_expression);
  931. end;
  932. end
  933. else
  934. CGMessage(type_e_mismatch);
  935. end
  936. else
  937. CGMessage(type_e_mismatch);
  938. end;
  939. in_low_x,
  940. in_high_x:
  941. begin
  942. if p^.left^.treetype in [typen,loadn,subscriptn] then
  943. begin
  944. case p^.left^.resulttype^.deftype of
  945. orddef,enumdef:
  946. begin
  947. do_lowhigh(p^.left^.resulttype);
  948. firstpass(p);
  949. end;
  950. setdef:
  951. begin
  952. do_lowhigh(Psetdef(p^.left^.resulttype)^.setof);
  953. firstpass(p);
  954. end;
  955. arraydef:
  956. begin
  957. if p^.inlinenumber=in_low_x then
  958. begin
  959. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.lowrange,s32bitdef);
  960. disposetree(p);
  961. p:=hp;
  962. firstpass(p);
  963. end
  964. else
  965. begin
  966. if is_open_array(p^.left^.resulttype) or
  967. is_array_of_const(p^.left^.resulttype) then
  968. begin
  969. getsymonlyin(p^.left^.symtable,'high'+pvarsym(p^.left^.symtableentry)^.name);
  970. hp:=genloadnode(pvarsym(srsym),p^.left^.symtable);
  971. disposetree(p);
  972. p:=hp;
  973. firstpass(p);
  974. end
  975. else
  976. begin
  977. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.highrange,s32bitdef);
  978. disposetree(p);
  979. p:=hp;
  980. firstpass(p);
  981. end;
  982. end;
  983. end;
  984. stringdef:
  985. begin
  986. if p^.inlinenumber=in_low_x then
  987. begin
  988. hp:=genordinalconstnode(0,u8bitdef);
  989. disposetree(p);
  990. p:=hp;
  991. firstpass(p);
  992. end
  993. else
  994. begin
  995. if is_open_string(p^.left^.resulttype) then
  996. begin
  997. getsymonlyin(p^.left^.symtable,'high'+pvarsym(p^.left^.symtableentry)^.name);
  998. hp:=genloadnode(pvarsym(srsym),p^.left^.symtable);
  999. disposetree(p);
  1000. p:=hp;
  1001. firstpass(p);
  1002. end
  1003. else
  1004. begin
  1005. hp:=genordinalconstnode(Pstringdef(p^.left^.resulttype)^.len,u8bitdef);
  1006. disposetree(p);
  1007. p:=hp;
  1008. firstpass(p);
  1009. end;
  1010. end;
  1011. end;
  1012. else
  1013. CGMessage(type_e_mismatch);
  1014. end;
  1015. end
  1016. else
  1017. CGMessage(type_e_varid_or_typeid_expected);
  1018. end;
  1019. in_assert_x_y :
  1020. begin
  1021. p^.resulttype:=voiddef;
  1022. if assigned(p^.left) then
  1023. begin
  1024. firstcallparan(p^.left,nil);
  1025. p^.registers32:=p^.left^.registers32;
  1026. p^.registersfpu:=p^.left^.registersfpu;
  1027. {$ifdef SUPPORT_MMX}
  1028. p^.registersmmx:=p^.left^.registersmmx;
  1029. {$endif SUPPORT_MMX}
  1030. { check type }
  1031. if is_boolean(p^.left^.resulttype) then
  1032. begin
  1033. { must always be a string }
  1034. p^.left^.right^.left:=gentypeconvnode(p^.left^.right^.left,cshortstringdef);
  1035. firstpass(p^.left^.right^.left);
  1036. end
  1037. else
  1038. CGMessage(type_e_mismatch);
  1039. end
  1040. else
  1041. CGMessage(type_e_mismatch);
  1042. end;
  1043. else
  1044. internalerror(8);
  1045. end;
  1046. end;
  1047. { generate an error if no resulttype is set }
  1048. if not assigned(p^.resulttype) then
  1049. p^.resulttype:=generrordef;
  1050. must_be_valid:=store_valid;
  1051. count_ref:=store_count_ref;
  1052. end;
  1053. end.
  1054. {
  1055. $Log$
  1056. Revision 1.35 1999-05-27 19:45:19 peter
  1057. * removed oldasm
  1058. * plabel -> pasmlabel
  1059. * -a switches to source writing automaticly
  1060. * assembler readers OOPed
  1061. * asmsymbol automaticly external
  1062. * jumptables and other label fixes for asm readers
  1063. Revision 1.34 1999/05/23 18:42:20 florian
  1064. * better error recovering in typed constants
  1065. * some problems with arrays of const fixed, some problems
  1066. due my previous
  1067. - the location type of array constructor is now LOC_MEM
  1068. - the pushing of high fixed
  1069. - parameter copying fixed
  1070. - zero temp. allocation removed
  1071. * small problem in the assembler writers fixed:
  1072. ref to nil wasn't written correctly
  1073. Revision 1.33 1999/05/06 09:05:35 peter
  1074. * generic write_float and str_float
  1075. * fixed constant float conversions
  1076. Revision 1.32 1999/05/05 22:25:21 florian
  1077. * fixed register allocation for val
  1078. Revision 1.31 1999/05/02 21:33:57 florian
  1079. * several bugs regarding -Or fixed
  1080. Revision 1.30 1999/05/01 13:24:53 peter
  1081. * merged nasm compiler
  1082. * old asm moved to oldasm/
  1083. Revision 1.29 1999/04/28 06:02:15 florian
  1084. * changes of Bruessel:
  1085. + message handler can now take an explicit self
  1086. * typinfo fixed: sometimes the type names weren't written
  1087. * the type checking for pointer comparisations and subtraction
  1088. and are now more strict (was also buggy)
  1089. * small bug fix to link.pas to support compiling on another
  1090. drive
  1091. * probable bug in popt386 fixed: call/jmp => push/jmp
  1092. transformation didn't count correctly the jmp references
  1093. + threadvar support
  1094. * warning if ln/sqrt gets an invalid constant argument
  1095. Revision 1.28 1999/04/26 18:28:12 peter
  1096. * better read/write array
  1097. Revision 1.27 1999/04/26 09:32:22 peter
  1098. * try to convert to string for val()
  1099. Revision 1.26 1999/04/15 14:10:51 pierre
  1100. * fix for bug0238.pp
  1101. Revision 1.25 1999/04/15 10:00:35 peter
  1102. * writeln(procvar) support for tp7 mode
  1103. Revision 1.24 1999/04/14 09:15:07 peter
  1104. * first things to store the symbol/def number in the ppu
  1105. Revision 1.23 1999/04/08 10:16:48 peter
  1106. * funcret_valid flag is set for inline functions
  1107. Revision 1.22 1999/03/26 00:05:48 peter
  1108. * released valintern
  1109. + deffile is now removed when compiling is finished
  1110. * ^( compiles now correct
  1111. + static directive
  1112. * shrd fixed
  1113. Revision 1.21 1999/03/24 23:17:37 peter
  1114. * fixed bugs 212,222,225,227,229,231,233
  1115. Revision 1.20 1999/03/16 17:52:55 jonas
  1116. * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
  1117. * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
  1118. * in cgai386: also small fixes to emitrangecheck
  1119. Revision 1.19 1999/02/22 12:36:34 florian
  1120. + warning for lo/hi(longint/dword) in -So and -Sd mode added
  1121. Revision 1.18 1999/02/22 02:15:49 peter
  1122. * updates for ag386bin
  1123. Revision 1.17 1999/02/01 00:00:50 florian
  1124. * compiler crash fixed when constant arguments passed to round/trunc
  1125. exceeds the longint range
  1126. Revision 1.16 1999/01/28 19:43:43 peter
  1127. * fixed high generation for ansistrings with str,writeln
  1128. Revision 1.15 1999/01/27 16:28:22 pierre
  1129. * bug0157 solved : write(x:5.3) is rejected now
  1130. Revision 1.14 1999/01/21 22:10:50 peter
  1131. * fixed array of const
  1132. * generic platform independent high() support
  1133. Revision 1.13 1998/12/30 22:13:13 peter
  1134. * check the amount of paras for Str()
  1135. Revision 1.12 1998/12/15 10:23:31 peter
  1136. + -iSO, -iSP, -iTO, -iTP
  1137. Revision 1.11 1998/12/11 23:36:08 florian
  1138. + again more stuff for int64/qword:
  1139. - comparision operators
  1140. - code generation for: str, read(ln), write(ln)
  1141. Revision 1.10 1998/11/27 14:50:53 peter
  1142. + open strings, $P switch support
  1143. Revision 1.9 1998/11/24 17:04:28 peter
  1144. * fixed length(char) when char is a variable
  1145. Revision 1.8 1998/11/14 10:51:33 peter
  1146. * fixed low/high for record.field
  1147. Revision 1.7 1998/11/13 10:15:52 peter
  1148. * fixed ptr() with constants
  1149. Revision 1.6 1998/11/05 12:03:05 peter
  1150. * released useansistring
  1151. * removed -Sv, its now available in fpc modes
  1152. Revision 1.5 1998/10/20 11:16:47 pierre
  1153. + length(c) where C is a char is allways 1
  1154. Revision 1.4 1998/10/06 20:49:11 peter
  1155. * m68k compiler compiles again
  1156. Revision 1.3 1998/10/05 12:32:49 peter
  1157. + assert() support
  1158. Revision 1.2 1998/10/02 09:24:23 peter
  1159. * more constant expression evaluators
  1160. Revision 1.1 1998/09/23 20:42:24 peter
  1161. * splitted pass_1
  1162. }