nflw.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Type checking and register allocation for nodes that influence
  5. the flow
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. unit nflw;
  20. {$i defines.inc}
  21. interface
  22. uses
  23. node,aasm,cpubase,symtable;
  24. type
  25. tloopnode = class(tbinarynode)
  26. t1,t2 : tnode;
  27. constructor create(tt : tnodetype;l,r,_t1,_t2 : tnode);virtual;
  28. destructor destroy;override;
  29. function getcopy : tnode;override;
  30. end;
  31. tlabelednode = class(tunarynode)
  32. labelnr : pasmlabel;
  33. exceptionblock : tnode;
  34. labsym : plabelsym;
  35. destructor destroy;override;
  36. function getcopy : tnode;override;
  37. end;
  38. twhilerepeatnode = class(tloopnode)
  39. function pass_1 : tnode;override;
  40. end;
  41. tifnode = class(tloopnode)
  42. constructor create(l,r,_t1 : tnode);virtual;
  43. function pass_1 : tnode;override;
  44. end;
  45. tfornode = class(tloopnode)
  46. constructor create(l,r,_t1,_t2 : tnode;back : boolean);
  47. function pass_1 : tnode;override;
  48. end;
  49. texitnode = class(tunarynode)
  50. constructor create;virtual;
  51. function pass_1 : tnode;override;
  52. end;
  53. tgotonode = class(tlabelednode)
  54. constructor create;virtual;
  55. function pass_1 : tnode;override;
  56. end;
  57. tlabelnode = class(tlabelednode)
  58. constructor create;virtual;
  59. function pass_1 : tnode;override;
  60. end;
  61. traisenode = class(tbinarynode)
  62. frametree : tnode;
  63. constructor create;virtual;
  64. function getcopy : tnode;override;
  65. function pass_1 : tnode;override;
  66. end;
  67. ttryexceptnode = class(tloopnode)
  68. constructor create;virtual;
  69. function pass_1 : tnode;override;
  70. end;
  71. ttryfinallynode = class(tbinarynode)
  72. constructor create;virtual;
  73. function pass_1 : tnode;override;
  74. end;
  75. tonnode = class(tbinarynode)
  76. exceptsymtable : psymtable;
  77. excepttype : pobjectdef;
  78. constructor create;virtual;
  79. function pass_1 : tnode;override;
  80. function getcopy : tnode;override;
  81. end;
  82. { for compatibilty }
  83. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  84. var
  85. cwhilerepeatnode : class of twhilerepeatnode;
  86. cifnode : class of tifnode;
  87. cfornode : class of tfornode;
  88. cexitnode : class of texitnode;
  89. cgotonode : class of tgotonode;
  90. clabelnode : class of tlabelnode;
  91. craisenode : class of traisenode;
  92. ctryexceptnode : class of ttryexceptnode;
  93. ctryfinallynode : class of ttryfinallynode;
  94. connode : class of tonnode;
  95. { the block node of the current exception block to check gotos }
  96. aktexceptblock : tnode;
  97. implementation
  98. uses
  99. globtype,systems,
  100. cutils,cobjects,verbose,globals,
  101. symconst,types,htypechk,pass_1,
  102. ncon,nmem,nld,ncnv
  103. {$ifdef newcg}
  104. ,tgobj
  105. ,tgcpu
  106. ,cgbase
  107. {$else newcg}
  108. ,hcodegen
  109. ,temp_gen
  110. {$ifdef i386}
  111. ,tgeni386
  112. {$endif}
  113. {$ifdef m68k}
  114. ,tgen68k
  115. {$endif m68k}
  116. {$endif newcg}
  117. ;
  118. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  119. var
  120. p : tnode;
  121. begin
  122. case t of
  123. ifn:
  124. p:=cifnode.create(l,r,n1);
  125. repeatn:
  126. p:=cwhilerepeatnode.create(repeatn,l,r,n1,nil);
  127. whilen:
  128. p:=cwhilerepeatnode.create(whilen,l,r,n1,nil);
  129. forn:
  130. p:=cfornode.create(l,r,n1,nil,back);
  131. end;
  132. genloopnode:=p;
  133. end;
  134. {****************************************************************************
  135. TLOOPNODE
  136. *****************************************************************************}
  137. constructor tloopnode.create(tt : tnodetype;l,r,_t1,_t2 : tnode);
  138. begin
  139. inherited create(tt,l,r);
  140. t1:=_t1;
  141. t2:=_t2;
  142. set_file_line(l);
  143. end;
  144. destructor tloopnode.destroy;
  145. begin
  146. t1.free;
  147. t2.free;
  148. inherited destroy;
  149. end;
  150. function tloopnode.getcopy : tnode;
  151. var
  152. p : tloopnode;
  153. begin
  154. p:=tloopnode(inherited getcopy);
  155. p.t1:=t1.getcopy;
  156. p.t2:=t2.getcopy;
  157. getcopy:=p;
  158. end;
  159. {****************************************************************************
  160. TTLABELDNODE
  161. *****************************************************************************}
  162. destructor tlabelednode.destroy;
  163. begin
  164. end;
  165. function tlabelednode.getcopy : tnode;
  166. var
  167. p : tlabelednode;
  168. begin
  169. p:=tlabelednode(inherited getcopy);
  170. p.labelnr:=labelnr;
  171. p.exceptionblock:=exceptionblock;
  172. p.labsym:=labsym;
  173. end;
  174. {****************************************************************************
  175. TWHILEREPEATNODE
  176. *****************************************************************************}
  177. function twhilerepeatnode.pass_1 : tnode;
  178. var
  179. old_t_times : longint;
  180. begin
  181. pass_1:=nil;
  182. old_t_times:=t_times;
  183. { calc register weight }
  184. if not(cs_littlesize in aktglobalswitches ) then
  185. t_times:=t_times*8;
  186. {$ifdef newcg}
  187. tg.cleartempgen;
  188. {$else newcg}
  189. cleartempgen;
  190. {$endif newcg}
  191. firstpass(left);
  192. set_varstate(left,true);
  193. if codegenerror then
  194. exit;
  195. if not is_boolean(left.resulttype) then
  196. begin
  197. CGMessage(type_e_mismatch);
  198. exit;
  199. end;
  200. registers32:=left.registers32;
  201. registersfpu:=left.registersfpu;
  202. {$ifdef SUPPORT_MMX}
  203. registersmmx:=left.registersmmx;
  204. {$endif SUPPORT_MMX}
  205. { loop instruction }
  206. if assigned(right) then
  207. begin
  208. {$ifdef newcg}
  209. tg.cleartempgen;
  210. {$else newcg}
  211. cleartempgen;
  212. {$endif newcg}
  213. firstpass(right);
  214. if codegenerror then
  215. exit;
  216. if registers32<right.registers32 then
  217. registers32:=right.registers32;
  218. if registersfpu<right.registersfpu then
  219. registersfpu:=right.registersfpu;
  220. {$ifdef SUPPORT_MMX}
  221. if registersmmx<right.registersmmx then
  222. registersmmx:=right.registersmmx;
  223. {$endif SUPPORT_MMX}
  224. end;
  225. t_times:=old_t_times;
  226. end;
  227. {*****************************************************************************
  228. TIFNODE
  229. *****************************************************************************}
  230. constructor tifnode.create(l,r,_t1 : tnode);
  231. begin
  232. inherited create(ifn,l,r,_t1,nil);
  233. end;
  234. function tifnode.pass_1 : tnode;
  235. var
  236. old_t_times : longint;
  237. hp : tnode;
  238. begin
  239. pass_1:=nil;
  240. old_t_times:=t_times;
  241. {$ifdef newcg}
  242. tg.cleartempgen;
  243. {$else newcg}
  244. cleartempgen;
  245. {$endif newcg}
  246. firstpass(left);
  247. set_varstate(left,true);
  248. { Only check type if no error, we can't leave here because
  249. the right also needs to be firstpassed }
  250. if not codegenerror then
  251. begin
  252. if not is_boolean(left.resulttype) then
  253. Message1(type_e_boolean_expr_expected,left.resulttype^.typename);
  254. end;
  255. registers32:=left.registers32;
  256. registersfpu:=left.registersfpu;
  257. {$ifdef SUPPORT_MMX}
  258. registersmmx:=left.registersmmx;
  259. {$endif SUPPORT_MMX}
  260. { determines registers weigths }
  261. if not(cs_littlesize in aktglobalswitches) then
  262. t_times:=t_times div 2;
  263. if t_times=0 then
  264. t_times:=1;
  265. { if path }
  266. if assigned(right) then
  267. begin
  268. {$ifdef newcg}
  269. tg.cleartempgen;
  270. {$else newcg}
  271. cleartempgen;
  272. {$endif newcg}
  273. firstpass(right);
  274. if registers32<right.registers32 then
  275. registers32:=right.registers32;
  276. if registersfpu<right.registersfpu then
  277. registersfpu:=right.registersfpu;
  278. {$ifdef SUPPORT_MMX}
  279. if registersmmx<right.registersmmx then
  280. registersmmx:=right.registersmmx;
  281. {$endif SUPPORT_MMX}
  282. end;
  283. { else path }
  284. if assigned(t1) then
  285. begin
  286. {$ifdef newcg}
  287. tg.cleartempgen;
  288. {$else newcg}
  289. cleartempgen;
  290. {$endif newcg}
  291. firstpass(t1);
  292. if registers32<t1.registers32 then
  293. registers32:=t1.registers32;
  294. if registersfpu<t1.registersfpu then
  295. registersfpu:=t1.registersfpu;
  296. {$ifdef SUPPORT_MMX}
  297. if registersmmx<t1.registersmmx then
  298. registersmmx:=t1.registersmmx;
  299. {$endif SUPPORT_MMX}
  300. end;
  301. { leave if we've got an error in one of the paths }
  302. if codegenerror then
  303. exit;
  304. if left.nodetype=ordconstn then
  305. begin
  306. { optimize }
  307. if tordconstnode(left).value=1 then
  308. begin
  309. left.free;
  310. hp:=right;
  311. right:=nil;
  312. t1.free;
  313. { we cannot set p to nil !!! }
  314. if assigned(hp) then
  315. pass_1:=hp
  316. else
  317. pass_1:=cnothingnode.create;
  318. end
  319. else
  320. begin
  321. left.free;
  322. hp:=t1;
  323. t1:=nil;
  324. right.free;
  325. { we cannot set p to nil !!! }
  326. if assigned(hp) then
  327. pass_1:=hp
  328. else
  329. pass_1:=cnothingnode.create;
  330. end;
  331. end;
  332. t_times:=old_t_times;
  333. end;
  334. {*****************************************************************************
  335. TFORNODE
  336. *****************************************************************************}
  337. constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
  338. begin
  339. inherited create(forn,l,r,_t1,_t2);
  340. if back then
  341. include(flags,nf_backward);
  342. end;
  343. function tfornode.pass_1 : tnode;
  344. var
  345. old_t_times : longint;
  346. hp : tnode;
  347. begin
  348. pass_1:=nil;
  349. { Calc register weight }
  350. old_t_times:=t_times;
  351. if not(cs_littlesize in aktglobalswitches) then
  352. t_times:=t_times*8;
  353. if left.nodetype<>assignn then
  354. begin
  355. CGMessage(cg_e_illegal_expression);
  356. exit;
  357. end;
  358. { save counter var }
  359. { tbinarynode should be tassignnode! }
  360. t2:=tbinarynode(left).left.getcopy;
  361. {$ifdef newcg}
  362. tg.cleartempgen;
  363. {$else newcg}
  364. cleartempgen;
  365. {$endif newcg}
  366. firstpass(left);
  367. set_varstate(left,false);
  368. {$ifdef newcg}
  369. tg.cleartempgen;
  370. {$else newcg}
  371. cleartempgen;
  372. {$endif newcg}
  373. if assigned(t1) then
  374. begin
  375. firstpass(t1);
  376. if codegenerror then
  377. exit;
  378. end;
  379. registers32:=t1.registers32;
  380. registersfpu:=t1.registersfpu;
  381. {$ifdef SUPPORT_MMX}
  382. registersmmx:=left.registersmmx;
  383. {$endif SUPPORT_MMX}
  384. if left.registers32>registers32 then
  385. registers32:=left.registers32;
  386. if left.registersfpu>registersfpu then
  387. registersfpu:=left.registersfpu;
  388. {$ifdef SUPPORT_MMX}
  389. if left.registersmmx>registersmmx then
  390. registersmmx:=left.registersmmx;
  391. {$endif SUPPORT_MMX}
  392. { process count var }
  393. {$ifdef newcg}
  394. tg.cleartempgen;
  395. {$else newcg}
  396. cleartempgen;
  397. {$endif newcg}
  398. firstpass(t2);
  399. set_varstate(t2,true);
  400. if codegenerror then
  401. exit;
  402. { Check count var, record fields are also allowed in tp7 }
  403. hp:=t2;
  404. while (hp.nodetype=subscriptn) do
  405. hp:=tsubscriptnode(hp).left;
  406. { we need a simple loadn, but the load must be in a global symtable or
  407. in the same lexlevel }
  408. if (hp.nodetype=funcretn) or
  409. ((hp.nodetype=loadn) and
  410. ((tloadnode(hp).symtable^.symtablelevel<=1) or
  411. (tloadnode(hp).symtable^.symtablelevel=lexlevel))) then
  412. begin
  413. if tloadnode(hp).symtableentry^.typ=varsym then
  414. pvarsym(tloadnode(hp).symtableentry)^.varstate:=vs_used;
  415. if (not(is_ordinal(t2.resulttype)) or is_64bitint(t2.resulttype)) then
  416. CGMessagePos(hp.fileinfo,type_e_ordinal_expr_expected);
  417. end
  418. else
  419. CGMessagePos(hp.fileinfo,cg_e_illegal_count_var);
  420. if t2.registers32>registers32 then
  421. registers32:=t2.registers32;
  422. if t2.registersfpu>registersfpu then
  423. registersfpu:=t2.registersfpu;
  424. {$ifdef SUPPORT_MMX}
  425. if t2.registersmmx>registersmmx then
  426. registersmmx:=t2.registersmmx;
  427. {$endif SUPPORT_MMX}
  428. {$ifdef newcg}
  429. tg.cleartempgen;
  430. {$else newcg}
  431. cleartempgen;
  432. {$endif newcg}
  433. firstpass(right);
  434. set_varstate(right,true);
  435. if right.nodetype<>ordconstn then
  436. begin
  437. right:=gentypeconvnode(right,t2.resulttype);
  438. {$ifdef newcg}
  439. tg.cleartempgen;
  440. {$else newcg}
  441. cleartempgen;
  442. {$endif newcg}
  443. firstpass(right);
  444. end;
  445. if right.registers32>registers32 then
  446. registers32:=right.registers32;
  447. if right.registersfpu>registersfpu then
  448. registersfpu:=right.registersfpu;
  449. {$ifdef SUPPORT_MMX}
  450. if right.registersmmx>registersmmx then
  451. registersmmx:=right.registersmmx;
  452. {$endif SUPPORT_MMX}
  453. { we need at least one register for comparisons PM }
  454. if registers32=0 then
  455. inc(registers32);
  456. t_times:=old_t_times;
  457. end;
  458. {*****************************************************************************
  459. TEXITNODE
  460. *****************************************************************************}
  461. constructor texitnode.create;
  462. begin
  463. end;
  464. function texitnode.pass_1 : tnode;
  465. var
  466. pt : tfuncretnode;
  467. begin
  468. pass_1:=nil;
  469. resulttype:=voiddef;
  470. if assigned(left) then
  471. begin
  472. firstpass(left);
  473. procinfo^.funcret_state:=vs_assigned;
  474. if codegenerror then
  475. exit;
  476. { Check the 2 types }
  477. left:=gentypeconvnode(left,procinfo^.returntype.def);
  478. firstpass(left);
  479. if ret_in_param(procinfo^.returntype.def) or procinfo^.no_fast_exit then
  480. begin
  481. pt:=cfuncretnode.create;
  482. pt.rettype.setdef(procinfo^.returntype.def);
  483. pt.funcretprocinfo:=procinfo;
  484. left:=cassignmentnode.create(pt,left);
  485. firstpass(left);
  486. end;
  487. registers32:=left.registers32;
  488. registersfpu:=left.registersfpu;
  489. {$ifdef SUPPORT_MMX}
  490. registersmmx:=left.registersmmx;
  491. {$endif SUPPORT_MMX}
  492. end;
  493. end;
  494. {*****************************************************************************
  495. TGOTONODE
  496. *****************************************************************************}
  497. constructor tgotonode.create;
  498. begin
  499. end;
  500. function tgotonode.pass_1 : tnode;
  501. begin
  502. pass_1:=nil;
  503. resulttype:=voiddef;
  504. end;
  505. {*****************************************************************************
  506. TLABELNODE
  507. *****************************************************************************}
  508. constructor tlabelnode.create;
  509. begin
  510. end;
  511. function tlabelnode.pass_1 : tnode;
  512. begin
  513. pass_1:=nil;
  514. {$ifdef newcg}
  515. tg.cleartempgen;
  516. {$else newcg}
  517. cleartempgen;
  518. {$endif newcg}
  519. exceptionblock:=aktexceptblock;
  520. firstpass(left);
  521. registers32:=left.registers32;
  522. registersfpu:=left.registersfpu;
  523. {$ifdef SUPPORT_MMX}
  524. registersmmx:=left.registersmmx;
  525. {$endif SUPPORT_MMX}
  526. resulttype:=voiddef;
  527. end;
  528. {*****************************************************************************
  529. TRAISENODE
  530. *****************************************************************************}
  531. constructor traisenode.create;
  532. begin
  533. inherited create(raisen,nil,nil);
  534. frametree:=nil;
  535. end;
  536. function traisenode.getcopy : tnode;
  537. var
  538. n : traisenode;
  539. begin
  540. n:=traisenode(inherited getcopy);
  541. n.frametree:=frametree;
  542. getcopy:=n;
  543. end;
  544. function traisenode.pass_1 : tnode;
  545. begin
  546. pass_1:=nil;
  547. resulttype:=voiddef;
  548. if assigned(left) then
  549. begin
  550. { first para must be a _class_ }
  551. firstpass(left);
  552. if assigned(left.resulttype) and
  553. ((left.resulttype^.deftype<>objectdef) or
  554. not(pobjectdef(left.resulttype)^.is_class)) then
  555. CGMessage(type_e_mismatch);
  556. set_varstate(left,true);
  557. if codegenerror then
  558. exit;
  559. { insert needed typeconvs for addr,frame }
  560. if assigned(right) then
  561. begin
  562. { addr }
  563. firstpass(right);
  564. right:=gentypeconvnode(right,s32bitdef);
  565. firstpass(right);
  566. if codegenerror then
  567. exit;
  568. { frame }
  569. if assigned(frametree) then
  570. begin
  571. firstpass(frametree);
  572. frametree:=gentypeconvnode(frametree,s32bitdef);
  573. firstpass(frametree);
  574. if codegenerror then
  575. exit;
  576. end;
  577. end;
  578. left_right_max;
  579. end;
  580. end;
  581. {*****************************************************************************
  582. TTRYEXCEPTNODE
  583. *****************************************************************************}
  584. constructor ttryexceptnode.create;
  585. begin
  586. end;
  587. function ttryexceptnode.pass_1 : tnode;
  588. var
  589. oldexceptblock : tnode;
  590. begin
  591. pass_1:=nil;
  592. {$ifdef newcg}
  593. tg.cleartempgen;
  594. {$else newcg}
  595. cleartempgen;
  596. {$endif newcg}
  597. oldexceptblock:=aktexceptblock;
  598. aktexceptblock:=left;
  599. firstpass(left);
  600. aktexceptblock:=oldexceptblock;
  601. { on statements }
  602. if assigned(right) then
  603. begin
  604. {$ifdef newcg}
  605. tg.cleartempgen;
  606. {$else newcg}
  607. cleartempgen;
  608. {$endif newcg}
  609. oldexceptblock:=aktexceptblock;
  610. aktexceptblock:=right;
  611. firstpass(right);
  612. aktexceptblock:=oldexceptblock;
  613. registers32:=max(registers32,right.registers32);
  614. registersfpu:=max(registersfpu,right.registersfpu);
  615. {$ifdef SUPPORT_MMX}
  616. registersmmx:=max(registersmmx,right.registersmmx);
  617. {$endif SUPPORT_MMX}
  618. end;
  619. { else block }
  620. if assigned(t1) then
  621. begin
  622. oldexceptblock:=aktexceptblock;
  623. aktexceptblock:=t1;
  624. firstpass(t1);
  625. aktexceptblock:=oldexceptblock;
  626. registers32:=max(registers32,t1.registers32);
  627. registersfpu:=max(registersfpu,t1.registersfpu);
  628. {$ifdef SUPPORT_MMX}
  629. registersmmx:=max(registersmmx,t1.registersmmx);
  630. {$endif SUPPORT_MMX}
  631. end;
  632. end;
  633. {*****************************************************************************
  634. TTRYFINALLYNODE
  635. *****************************************************************************}
  636. constructor ttryfinallynode.create;
  637. begin
  638. end;
  639. function ttryfinallynode.pass_1 : tnode;
  640. var
  641. oldexceptblock : tnode;
  642. begin
  643. pass_1:=nil;
  644. resulttype:=voiddef;
  645. {$ifdef newcg}
  646. tg.cleartempgen;
  647. {$else newcg}
  648. cleartempgen;
  649. {$endif newcg}
  650. oldexceptblock:=aktexceptblock;
  651. aktexceptblock:=left;
  652. firstpass(left);
  653. aktexceptblock:=oldexceptblock;
  654. set_varstate(left,true);
  655. {$ifdef newcg}
  656. tg.cleartempgen;
  657. {$else newcg}
  658. cleartempgen;
  659. {$endif newcg}
  660. oldexceptblock:=aktexceptblock;
  661. aktexceptblock:=right;
  662. firstpass(right);
  663. aktexceptblock:=oldexceptblock;
  664. set_varstate(right,true);
  665. if codegenerror then
  666. exit;
  667. left_right_max;
  668. end;
  669. {*****************************************************************************
  670. TONNODE
  671. *****************************************************************************}
  672. constructor tonnode.create;
  673. begin
  674. inherited create(onn,nil,nil);
  675. exceptsymtable:=nil;
  676. excepttype:=nil;
  677. end;
  678. function tonnode.getcopy : tnode;
  679. var
  680. n : tonnode;
  681. begin
  682. n:=tonnode(inherited getcopy);
  683. n.exceptsymtable:=exceptsymtable;
  684. n.excepttype:=excepttype;
  685. end;
  686. function tonnode.pass_1 : tnode;
  687. var
  688. oldexceptblock : tnode;
  689. begin
  690. pass_1:=nil;
  691. { that's really an example procedure for a firstpass :) }
  692. if (excepttype^.deftype<>objectdef) or
  693. not(pobjectdef(excepttype)^.is_class) then
  694. CGMessage(type_e_mismatch);
  695. {$ifdef newcg}
  696. tg.cleartempgen;
  697. {$else newcg}
  698. cleartempgen;
  699. {$endif newcg}
  700. resulttype:=voiddef;
  701. registers32:=0;
  702. registersfpu:=0;
  703. {$ifdef SUPPORT_MMX}
  704. registersmmx:=0;
  705. {$endif SUPPORT_MMX}
  706. if assigned(left) then
  707. begin
  708. firstpass(left);
  709. registers32:=left.registers32;
  710. registersfpu:=left.registersfpu;
  711. {$ifdef SUPPORT_MMX}
  712. registersmmx:=left.registersmmx;
  713. {$endif SUPPORT_MMX}
  714. end;
  715. {$ifdef newcg}
  716. tg.cleartempgen;
  717. {$else newcg}
  718. cleartempgen;
  719. {$endif newcg}
  720. if assigned(right) then
  721. begin
  722. oldexceptblock:=aktexceptblock;
  723. aktexceptblock:=right;
  724. firstpass(right);
  725. aktexceptblock:=oldexceptblock;
  726. registers32:=max(registers32,right.registers32);
  727. registersfpu:=max(registersfpu,right.registersfpu);
  728. {$ifdef SUPPORT_MMX}
  729. registersmmx:=max(registersmmx,right.registersmmx);
  730. {$endif SUPPORT_MMX}
  731. end;
  732. end;
  733. begin
  734. cwhilerepeatnode:=twhilerepeatnode;
  735. cifnode:=tifnode;
  736. cfornode:=tfornode;
  737. cexitnode:=texitnode;
  738. cgotonode:=tgotonode;
  739. clabelnode:=tlabelnode;
  740. craisenode:=traisenode;
  741. ctryexceptnode:=ttryexceptnode;
  742. ctryfinallynode:=ttryfinallynode;
  743. connode:=tonnode;
  744. end.
  745. {
  746. $Log$
  747. Revision 1.5 2000-10-01 19:48:24 peter
  748. * lot of compile updates for cg11
  749. Revision 1.4 2000/09/28 19:49:52 florian
  750. *** empty log message ***
  751. Revision 1.3 2000/09/24 21:15:34 florian
  752. * some errors fix to get more stuff compilable
  753. Revision 1.2 2000/09/24 15:06:19 peter
  754. * use defines.inc
  755. Revision 1.1 2000/09/22 22:46:03 florian
  756. + initial revision
  757. }