nflw.pas 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.inc}
  21. interface
  22. uses
  23. node,cpubase,
  24. aasmbase,aasmtai,aasmcpu,symnot,
  25. symppu,symtype,symbase,symdef,symsym;
  26. type
  27. { flags used by loop nodes }
  28. tloopflags = (
  29. { set if it is a for ... downto ... do loop }
  30. lnf_backward,
  31. { Do we need to parse childs to set var state? }
  32. lnf_varstate,
  33. { Do a test at the begin of the loop?}
  34. lnf_testatbegin,
  35. { Negate the loop test? }
  36. lnf_checknegate,
  37. { Should the value of the loop variable on exit be correct. }
  38. lnf_dont_mind_loopvar_on_exit);
  39. const
  40. { loop flags which must match to consider loop nodes equal regarding the flags }
  41. loopflagsequal = [lnf_backward];
  42. type
  43. tloopnode = class(tbinarynode)
  44. t1,t2 : tnode;
  45. loopflags : set of tloopflags;
  46. constructor create(tt : tnodetype;l,r,_t1,_t2 : tnode);virtual;
  47. destructor destroy;override;
  48. function getcopy : tnode;override;
  49. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  50. procedure ppuwrite(ppufile:tcompilerppufile);override;
  51. procedure derefimpl;override;
  52. procedure insertintolist(l : tnodelist);override;
  53. procedure printnodetree(var t:text);override;
  54. function docompare(p: tnode): boolean; override;
  55. end;
  56. twhilerepeatnode = class(tloopnode)
  57. constructor create(l,r,_t1:Tnode;tab,cn:boolean);virtual;
  58. function det_resulttype:tnode;override;
  59. function pass_1 : tnode;override;
  60. {$ifdef state_tracking}
  61. function track_state_pass(exec_known:boolean):boolean;override;
  62. {$endif}
  63. end;
  64. twhilerepeatnodeclass = class of twhilerepeatnode;
  65. tifnode = class(tloopnode)
  66. constructor create(l,r,_t1 : tnode);virtual;
  67. function det_resulttype:tnode;override;
  68. function pass_1 : tnode;override;
  69. end;
  70. tifnodeclass = class of tifnode;
  71. tfornode = class(tloopnode)
  72. loopvar_notid:cardinal;
  73. constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;
  74. procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
  75. function det_resulttype:tnode;override;
  76. function pass_1 : tnode;override;
  77. end;
  78. tfornodeclass = class of tfornode;
  79. texitnode = class(tunarynode)
  80. onlyassign : boolean;
  81. constructor create(l:tnode);virtual;
  82. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  83. procedure ppuwrite(ppufile:tcompilerppufile);override;
  84. function det_resulttype:tnode;override;
  85. function pass_1 : tnode;override;
  86. end;
  87. texitnodeclass = class of texitnode;
  88. tbreaknode = class(tnode)
  89. constructor create;virtual;
  90. function det_resulttype:tnode;override;
  91. function pass_1 : tnode;override;
  92. end;
  93. tbreaknodeclass = class of tbreaknode;
  94. tcontinuenode = class(tnode)
  95. constructor create;virtual;
  96. function det_resulttype:tnode;override;
  97. function pass_1 : tnode;override;
  98. end;
  99. tcontinuenodeclass = class of tcontinuenode;
  100. tgotonode = class(tnode)
  101. labsym : tlabelsym;
  102. exceptionblock : integer;
  103. constructor create(p : tlabelsym);virtual;
  104. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  105. procedure ppuwrite(ppufile:tcompilerppufile);override;
  106. procedure derefimpl;override;
  107. function getcopy : tnode;override;
  108. function det_resulttype:tnode;override;
  109. function pass_1 : tnode;override;
  110. function docompare(p: tnode): boolean; override;
  111. end;
  112. tgotonodeclass = class of tgotonode;
  113. tlabelnode = class(tunarynode)
  114. labelnr : tasmlabel;
  115. labsym : tlabelsym;
  116. exceptionblock : integer;
  117. constructor createcase(p : tasmlabel;l:tnode);virtual;
  118. constructor create(p : tlabelsym;l:tnode);virtual;
  119. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  120. procedure ppuwrite(ppufile:tcompilerppufile);override;
  121. procedure derefimpl;override;
  122. function getcopy : tnode;override;
  123. function det_resulttype:tnode;override;
  124. function pass_1 : tnode;override;
  125. function docompare(p: tnode): boolean; override;
  126. end;
  127. tlabelnodeclass = class of tlabelnode;
  128. traisenode = class(tbinarynode)
  129. frametree : tnode;
  130. constructor create(l,taddr,tframe:tnode);virtual;
  131. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  132. procedure ppuwrite(ppufile:tcompilerppufile);override;
  133. procedure derefimpl;override;
  134. function getcopy : tnode;override;
  135. procedure insertintolist(l : tnodelist);override;
  136. function det_resulttype:tnode;override;
  137. function pass_1 : tnode;override;
  138. function docompare(p: tnode): boolean; override;
  139. end;
  140. traisenodeclass = class of traisenode;
  141. ttryexceptnode = class(tloopnode)
  142. constructor create(l,r,_t1 : tnode);virtual;
  143. function det_resulttype:tnode;override;
  144. function pass_1 : tnode;override;
  145. end;
  146. ttryexceptnodeclass = class of ttryexceptnode;
  147. ttryfinallynode = class(tbinarynode)
  148. constructor create(l,r:tnode);virtual;
  149. function det_resulttype:tnode;override;
  150. function pass_1 : tnode;override;
  151. end;
  152. ttryfinallynodeclass = class of ttryfinallynode;
  153. tonnode = class(tbinarynode)
  154. exceptsymtable : tsymtable;
  155. excepttype : tobjectdef;
  156. constructor create(l,r:tnode);virtual;
  157. destructor destroy;override;
  158. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  159. function det_resulttype:tnode;override;
  160. function pass_1 : tnode;override;
  161. function getcopy : tnode;override;
  162. function docompare(p: tnode): boolean; override;
  163. end;
  164. tonnodeclass = class of tonnode;
  165. tfailnode = class(tnode)
  166. constructor create;virtual;
  167. function det_resulttype:tnode;override;
  168. function pass_1: tnode;override;
  169. function docompare(p: tnode): boolean; override;
  170. end;
  171. tfailnodeclass = class of tfailnode;
  172. { for compatibilty }
  173. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  174. var
  175. cwhilerepeatnode : twhilerepeatnodeclass;
  176. cifnode : tifnodeclass;
  177. cfornode : tfornodeclass;
  178. cexitnode : texitnodeclass;
  179. cbreaknode : tbreaknodeclass;
  180. ccontinuenode : tcontinuenodeclass;
  181. cgotonode : tgotonodeclass;
  182. clabelnode : tlabelnodeclass;
  183. craisenode : traisenodeclass;
  184. ctryexceptnode : ttryexceptnodeclass;
  185. ctryfinallynode : ttryfinallynodeclass;
  186. connode : tonnodeclass;
  187. cfailnode : tfailnodeclass;
  188. implementation
  189. uses
  190. globtype,systems,
  191. cutils,verbose,globals,
  192. symconst,symtable,paramgr,defutil,htypechk,pass_1,
  193. ncon,nmem,nld,ncnv,nbas,rgobj,
  194. {$ifdef state_tracking}
  195. nstate,
  196. {$endif}
  197. cginfo,cgbase
  198. ;
  199. function genloopnode(t : tnodetype;l,r,n1 : tnode;back : boolean) : tnode;
  200. var
  201. p : tnode;
  202. begin
  203. case t of
  204. ifn:
  205. p:=cifnode.create(l,r,n1);
  206. whilerepeatn:
  207. if back then
  208. {Repeat until.}
  209. p:=cwhilerepeatnode.create(l,r,n1,false,true)
  210. else
  211. {While do.}
  212. p:=cwhilerepeatnode.create(l,r,n1,true,false);
  213. forn:
  214. p:=cfornode.create(l,r,n1,nil,back);
  215. end;
  216. genloopnode:=p;
  217. end;
  218. {****************************************************************************
  219. TLOOPNODE
  220. *****************************************************************************}
  221. constructor tloopnode.create(tt : tnodetype;l,r,_t1,_t2 : tnode);
  222. begin
  223. inherited create(tt,l,r);
  224. t1:=_t1;
  225. t2:=_t2;
  226. set_file_line(l);
  227. end;
  228. destructor tloopnode.destroy;
  229. begin
  230. t1.free;
  231. t2.free;
  232. inherited destroy;
  233. end;
  234. constructor tloopnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  235. begin
  236. inherited ppuload(t,ppufile);
  237. t1:=ppuloadnode(ppufile);
  238. t2:=ppuloadnode(ppufile);
  239. end;
  240. procedure tloopnode.ppuwrite(ppufile:tcompilerppufile);
  241. begin
  242. inherited ppuwrite(ppufile);
  243. ppuwritenode(ppufile,t1);
  244. ppuwritenode(ppufile,t2);
  245. end;
  246. procedure tloopnode.derefimpl;
  247. begin
  248. inherited derefimpl;
  249. if assigned(t1) then
  250. t1.derefimpl;
  251. if assigned(t2) then
  252. t2.derefimpl;
  253. end;
  254. function tloopnode.getcopy : tnode;
  255. var
  256. p : tloopnode;
  257. begin
  258. p:=tloopnode(inherited getcopy);
  259. if assigned(t1) then
  260. p.t1:=t1.getcopy
  261. else
  262. p.t1:=nil;
  263. if assigned(t2) then
  264. p.t2:=t2.getcopy
  265. else
  266. p.t2:=nil;
  267. getcopy:=p;
  268. end;
  269. procedure tloopnode.insertintolist(l : tnodelist);
  270. begin
  271. end;
  272. procedure tloopnode.printnodetree(var t:text);
  273. begin
  274. printnodeinfo(t);
  275. printnodeindent;
  276. printnode(t,left);
  277. printnode(t,right);
  278. printnode(t,t1);
  279. printnode(t,t2);
  280. printnodeunindent;
  281. end;
  282. function tloopnode.docompare(p: tnode): boolean;
  283. begin
  284. docompare :=
  285. inherited docompare(p) and
  286. (loopflags*loopflagsequal=tloopnode(p).loopflags*loopflagsequal) and
  287. t1.isequal(tloopnode(p).t1) and
  288. t2.isequal(tloopnode(p).t2);
  289. end;
  290. {****************************************************************************
  291. TWHILEREPEATNODE
  292. *****************************************************************************}
  293. constructor Twhilerepeatnode.create(l,r,_t1:Tnode;tab,cn:boolean);
  294. begin
  295. inherited create(whilerepeatn,l,r,_t1,nil);
  296. if tab then
  297. include(loopflags, lnf_testatbegin);
  298. if cn then
  299. include(loopflags,lnf_checknegate);
  300. end;
  301. function twhilerepeatnode.det_resulttype:tnode;
  302. var
  303. t:Tunarynode;
  304. begin
  305. result:=nil;
  306. resulttype:=voidtype;
  307. resulttypepass(left);
  308. {A not node can be removed.}
  309. if left.nodetype=notn then
  310. begin
  311. t:=Tunarynode(left);
  312. left:=Tunarynode(left).left;
  313. t.left:=nil;
  314. t.destroy;
  315. {$ifdef Delphi}
  316. { How can this be handled in Delphi ? }
  317. RunError(255);
  318. {$else}
  319. {Symdif operator, in case you are wondering:}
  320. loopflags:=loopflags >< [lnf_checknegate];
  321. {$endif}
  322. end;
  323. { loop instruction }
  324. if assigned(right) then
  325. resulttypepass(right);
  326. set_varstate(left,true);
  327. if codegenerror then
  328. exit;
  329. if not is_boolean(left.resulttype.def) then
  330. begin
  331. CGMessage(type_e_mismatch);
  332. exit;
  333. end;
  334. end;
  335. function twhilerepeatnode.pass_1 : tnode;
  336. var
  337. old_t_times : longint;
  338. begin
  339. result:=nil;
  340. expectloc:=LOC_VOID;
  341. old_t_times:=rg.t_times;
  342. { calc register weight }
  343. if not(cs_littlesize in aktglobalswitches ) then
  344. rg.t_times:=rg.t_times*8;
  345. {$ifndef newra}
  346. rg.cleartempgen;
  347. {$endif}
  348. firstpass(left);
  349. if codegenerror then
  350. exit;
  351. registers32:=left.registers32;
  352. registersfpu:=left.registersfpu;
  353. {$ifdef SUPPORT_MMX}
  354. registersmmx:=left.registersmmx;
  355. {$endif SUPPORT_MMX}
  356. { loop instruction }
  357. if assigned(right) then
  358. begin
  359. {$ifndef newra}
  360. rg.cleartempgen;
  361. {$endif}
  362. firstpass(right);
  363. if codegenerror then
  364. exit;
  365. if registers32<right.registers32 then
  366. registers32:=right.registers32;
  367. if registersfpu<right.registersfpu then
  368. registersfpu:=right.registersfpu;
  369. {$ifdef SUPPORT_MMX}
  370. if registersmmx<right.registersmmx then
  371. registersmmx:=right.registersmmx;
  372. {$endif SUPPORT_MMX}
  373. end;
  374. rg.t_times:=old_t_times;
  375. end;
  376. {$ifdef state_tracking}
  377. function Twhilerepeatnode.track_state_pass(exec_known:boolean):boolean;
  378. var condition:Tnode;
  379. code:Tnode;
  380. done:boolean;
  381. value:boolean;
  382. change:boolean;
  383. firsttest:boolean;
  384. factval:Tnode;
  385. begin
  386. track_state_pass:=false;
  387. done:=false;
  388. firsttest:=true;
  389. {For repeat until statements, first do a pass through the code.}
  390. if not(lnf_testatbegin in flags) then
  391. begin
  392. code:=right.getcopy;
  393. if code.track_state_pass(exec_known) then
  394. track_state_pass:=true;
  395. code.destroy;
  396. end;
  397. repeat
  398. condition:=left.getcopy;
  399. code:=right.getcopy;
  400. change:=condition.track_state_pass(exec_known);
  401. factval:=aktstate.find_fact(left);
  402. if factval<>nil then
  403. begin
  404. condition.destroy;
  405. condition:=factval.getcopy;
  406. change:=true;
  407. end;
  408. if change then
  409. begin
  410. track_state_pass:=true;
  411. {Force new resulttype pass.}
  412. condition.resulttype.def:=nil;
  413. do_resulttypepass(condition);
  414. end;
  415. if is_constboolnode(condition) then
  416. begin
  417. {Try to turn a while loop into a repeat loop.}
  418. if firsttest then
  419. exclude(flags,testatbegin);
  420. value:=(Tordconstnode(condition).value<>0) xor checknegate;
  421. if value then
  422. begin
  423. if code.track_state_pass(exec_known) then
  424. track_state_pass:=true;
  425. end
  426. else
  427. done:=true;
  428. end
  429. else
  430. begin
  431. {Remove any modified variables from the state.}
  432. code.track_state_pass(false);
  433. done:=true;
  434. end;
  435. code.destroy;
  436. condition.destroy;
  437. firsttest:=false;
  438. until done;
  439. {The loop condition is also known, for example:
  440. while i<10 do
  441. begin
  442. ...
  443. end;
  444. When the loop is done, we do know that i<10 = false.
  445. }
  446. condition:=left.getcopy;
  447. if condition.track_state_pass(exec_known) then
  448. begin
  449. track_state_pass:=true;
  450. {Force new resulttype pass.}
  451. condition.resulttype.def:=nil;
  452. do_resulttypepass(condition);
  453. end;
  454. if not is_constboolnode(condition) then
  455. aktstate.store_fact(condition,
  456. cordconstnode.create(byte(checknegate),booltype,true))
  457. else
  458. condition.destroy;
  459. end;
  460. {$endif}
  461. {*****************************************************************************
  462. TIFNODE
  463. *****************************************************************************}
  464. constructor tifnode.create(l,r,_t1 : tnode);
  465. begin
  466. inherited create(ifn,l,r,_t1,nil);
  467. end;
  468. function tifnode.det_resulttype:tnode;
  469. begin
  470. result:=nil;
  471. resulttype:=voidtype;
  472. resulttypepass(left);
  473. { if path }
  474. if assigned(right) then
  475. resulttypepass(right);
  476. { else path }
  477. if assigned(t1) then
  478. resulttypepass(t1);
  479. set_varstate(left,true);
  480. if codegenerror then
  481. exit;
  482. if not is_boolean(left.resulttype.def) then
  483. Message1(type_e_boolean_expr_expected,left.resulttype.def.typename);
  484. end;
  485. function tifnode.pass_1 : tnode;
  486. var
  487. old_t_times : longint;
  488. hp : tnode;
  489. begin
  490. result:=nil;
  491. expectloc:=LOC_VOID;
  492. old_t_times:=rg.t_times;
  493. {$ifndef newra}
  494. rg.cleartempgen;
  495. {$endif}
  496. firstpass(left);
  497. registers32:=left.registers32;
  498. registersfpu:=left.registersfpu;
  499. {$ifdef SUPPORT_MMX}
  500. registersmmx:=left.registersmmx;
  501. {$endif SUPPORT_MMX}
  502. { determines registers weigths }
  503. if not(cs_littlesize in aktglobalswitches) then
  504. rg.t_times:=rg.t_times div 2;
  505. if rg.t_times=0 then
  506. rg.t_times:=1;
  507. { if path }
  508. if assigned(right) then
  509. begin
  510. {$ifndef newra}
  511. rg.cleartempgen;
  512. {$endif}
  513. firstpass(right);
  514. if registers32<right.registers32 then
  515. registers32:=right.registers32;
  516. if registersfpu<right.registersfpu then
  517. registersfpu:=right.registersfpu;
  518. {$ifdef SUPPORT_MMX}
  519. if registersmmx<right.registersmmx then
  520. registersmmx:=right.registersmmx;
  521. {$endif SUPPORT_MMX}
  522. end;
  523. { else path }
  524. if assigned(t1) then
  525. begin
  526. {$ifndef newra}
  527. rg.cleartempgen;
  528. {$endif}
  529. firstpass(t1);
  530. if registers32<t1.registers32 then
  531. registers32:=t1.registers32;
  532. if registersfpu<t1.registersfpu then
  533. registersfpu:=t1.registersfpu;
  534. {$ifdef SUPPORT_MMX}
  535. if registersmmx<t1.registersmmx then
  536. registersmmx:=t1.registersmmx;
  537. {$endif SUPPORT_MMX}
  538. end;
  539. { leave if we've got an error in one of the paths }
  540. if codegenerror then
  541. exit;
  542. if left.nodetype=ordconstn then
  543. begin
  544. { optimize }
  545. if tordconstnode(left).value=1 then
  546. begin
  547. hp:=right;
  548. right:=nil;
  549. { we cannot set p to nil !!! }
  550. if assigned(hp) then
  551. result:=hp
  552. else
  553. result:=cnothingnode.create;
  554. end
  555. else
  556. begin
  557. hp:=t1;
  558. t1:=nil;
  559. { we cannot set p to nil !!! }
  560. if assigned(hp) then
  561. result:=hp
  562. else
  563. result:=cnothingnode.create;
  564. end;
  565. end;
  566. rg.t_times:=old_t_times;
  567. end;
  568. {*****************************************************************************
  569. TFORNODE
  570. *****************************************************************************}
  571. constructor tfornode.create(l,r,_t1,_t2 : tnode;back : boolean);
  572. begin
  573. inherited create(forn,l,r,_t1,_t2);
  574. if back then
  575. include(loopflags,lnf_backward);
  576. include(loopflags,lnf_testatbegin);
  577. end;
  578. procedure Tfornode.loop_var_access(not_type:Tnotification_flag;
  579. symbol:Tsym);
  580. begin
  581. {If there is a read access, the value of the loop counter is important;
  582. at the end of the loop the loop variable should contain the value it
  583. had in the last iteration.}
  584. if not_type=vn_onwrite then
  585. begin
  586. writeln('Loopvar does not matter on exit');
  587. end
  588. else
  589. begin
  590. exclude(loopflags,lnf_dont_mind_loopvar_on_exit);
  591. writeln('Loopvar does matter on exit');
  592. end;
  593. Tvarsym(symbol).unregister_notification(loopvar_notid);
  594. end;
  595. function tfornode.det_resulttype:tnode;
  596. var
  597. hp : tnode;
  598. begin
  599. result:=nil;
  600. resulttype:=voidtype;
  601. if left.nodetype<>assignn then
  602. begin
  603. CGMessage(cg_e_illegal_expression);
  604. exit;
  605. end;
  606. {Can we spare the first comparision?}
  607. if (right.nodetype=ordconstn) and (Tassignmentnode(left).right.nodetype=ordconstn) then
  608. if (
  609. (lnf_backward in loopflags) and
  610. (Tordconstnode(Tassignmentnode(left).right).value>=Tordconstnode(right).value)
  611. )
  612. or not(
  613. (lnf_backward in loopflags) and
  614. (Tordconstnode(Tassignmentnode(left).right).value<=Tordconstnode(right).value)
  615. ) then
  616. exclude(loopflags,lnf_testatbegin);
  617. { save counter var }
  618. t2:=tassignmentnode(left).left.getcopy;
  619. resulttypepass(left);
  620. set_varstate(left,false);
  621. if assigned(t1) then
  622. begin
  623. resulttypepass(t1);
  624. if codegenerror then
  625. exit;
  626. end;
  627. { process count var }
  628. resulttypepass(t2);
  629. set_varstate(t2,true);
  630. if codegenerror then
  631. exit;
  632. { Check count var, record fields are also allowed in tp7 }
  633. hp:=t2;
  634. while (hp.nodetype=subscriptn) or
  635. ((hp.nodetype=vecn) and
  636. is_constintnode(tvecnode(hp).right)) do
  637. hp:=tunarynode(hp).left;
  638. { we need a simple loadn, but the load must be in a global symtable or
  639. in the same level as the para of the current proc }
  640. if (
  641. (hp.nodetype=loadn) and
  642. (
  643. (tloadnode(hp).symtable.symtablelevel=main_program_level) or
  644. (tloadnode(hp).symtable.symtablelevel=current_procdef.parast.symtablelevel)
  645. ) and
  646. not(
  647. (tloadnode(hp).symtableentry.typ=varsym) and
  648. ((tvarsym(tloadnode(hp).symtableentry).varspez in [vs_var,vs_out]) or
  649. (vo_is_thread_var in tvarsym(tloadnode(hp).symtableentry).varoptions))
  650. )
  651. ) then
  652. begin
  653. if (hp.nodetype=loadn) and
  654. (tloadnode(hp).symtableentry.typ=varsym) then
  655. tvarsym(tloadnode(hp).symtableentry).varstate:=vs_used;
  656. if not(is_ordinal(t2.resulttype.def))
  657. {$ifndef cpu64bit}
  658. or is_64bitint(t2.resulttype.def)
  659. {$endif cpu64bit}
  660. then
  661. CGMessagePos(hp.fileinfo,type_e_ordinal_expr_expected);
  662. end
  663. else
  664. CGMessagePos(hp.fileinfo,cg_e_illegal_count_var);
  665. resulttypepass(right);
  666. set_varstate(right,true);
  667. inserttypeconv(right,t2.resulttype);
  668. end;
  669. function tfornode.pass_1 : tnode;
  670. var
  671. old_t_times : longint;
  672. {$ifdef loopvar_dont_mind}
  673. hp : Tnode;
  674. {$endif loopvar_dont_mind}
  675. begin
  676. result:=nil;
  677. expectloc:=LOC_VOID;
  678. { Calc register weight }
  679. old_t_times:=rg.t_times;
  680. if not(cs_littlesize in aktglobalswitches) then
  681. rg.t_times:=rg.t_times*8;
  682. {$ifndef newra}
  683. rg.cleartempgen;
  684. {$endif}
  685. firstpass(left);
  686. {$ifndef newra}
  687. rg.cleartempgen;
  688. {$endif}
  689. if assigned(t1) then
  690. begin
  691. firstpass(t1);
  692. if codegenerror then
  693. exit;
  694. end;
  695. registers32:=t1.registers32;
  696. registersfpu:=t1.registersfpu;
  697. {$ifdef SUPPORT_MMX}
  698. registersmmx:=left.registersmmx;
  699. {$endif SUPPORT_MMX}
  700. if left.registers32>registers32 then
  701. registers32:=left.registers32;
  702. if left.registersfpu>registersfpu then
  703. registersfpu:=left.registersfpu;
  704. {$ifdef SUPPORT_MMX}
  705. if left.registersmmx>registersmmx then
  706. registersmmx:=left.registersmmx;
  707. {$endif SUPPORT_MMX}
  708. { process count var }
  709. {$ifndef newra}
  710. rg.cleartempgen;
  711. {$endif}
  712. firstpass(t2);
  713. if codegenerror then
  714. exit;
  715. if t2.registers32>registers32 then
  716. registers32:=t2.registers32;
  717. if t2.registersfpu>registersfpu then
  718. registersfpu:=t2.registersfpu;
  719. {$ifdef SUPPORT_MMX}
  720. if t2.registersmmx>registersmmx then
  721. registersmmx:=t2.registersmmx;
  722. {$endif SUPPORT_MMX}
  723. {$ifndef newra}
  724. rg.cleartempgen;
  725. {$endif}
  726. firstpass(right);
  727. {$ifdef loopvar_dont_mind}
  728. { Check count var, record fields are also allowed in tp7 }
  729. include(loopflags,lnf_dont_mind_loopvar_on_exit);
  730. hp:=t2;
  731. while (hp.nodetype=subscriptn) or
  732. ((hp.nodetype=vecn) and
  733. is_constintnode(tvecnode(hp).right)) do
  734. hp:=tunarynode(hp).left;
  735. if (hp.nodetype=loadn) and (Tloadnode(hp).symtableentry.typ=varsym) then
  736. loopvar_notid:=Tvarsym(Tloadnode(hp).symtableentry).
  737. register_notification([vn_onread,vn_onwrite],@loop_var_access);
  738. {$endif}
  739. if right.registers32>registers32 then
  740. registers32:=right.registers32;
  741. if right.registersfpu>registersfpu then
  742. registersfpu:=right.registersfpu;
  743. {$ifdef SUPPORT_MMX}
  744. if right.registersmmx>registersmmx then
  745. registersmmx:=right.registersmmx;
  746. {$endif SUPPORT_MMX}
  747. { we need at least one register for comparisons PM }
  748. if registers32=0 then
  749. inc(registers32);
  750. rg.t_times:=old_t_times;
  751. end;
  752. {*****************************************************************************
  753. TEXITNODE
  754. *****************************************************************************}
  755. constructor texitnode.create(l:tnode);
  756. begin
  757. inherited create(exitn,l);
  758. onlyassign:=false;
  759. end;
  760. constructor texitnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  761. begin
  762. inherited ppuload(t,ppufile);
  763. onlyassign:=boolean(ppufile.getbyte);
  764. end;
  765. procedure texitnode.ppuwrite(ppufile:tcompilerppufile);
  766. begin
  767. inherited ppuwrite(ppufile);
  768. ppufile.putbyte(byte(onlyassign));
  769. end;
  770. function texitnode.det_resulttype:tnode;
  771. begin
  772. result:=nil;
  773. { Check the 2 types }
  774. if not inlining_procedure then
  775. begin
  776. if assigned(left) then
  777. begin
  778. inserttypeconv(left,current_procdef.rettype);
  779. if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) or
  780. (current_procdef.proctypeoption=potype_constructor) or
  781. (pi_needs_implicit_finally in current_procinfo.flags) or
  782. (pi_uses_exceptions in current_procinfo.flags) then
  783. begin
  784. left:=cassignmentnode.create(
  785. cloadnode.create(current_procdef.funcretsym,current_procdef.funcretsym.owner),
  786. left);
  787. onlyassign:=true;
  788. end
  789. else
  790. begin
  791. { mark funcretsym as assigned }
  792. inc(tvarsym(current_procdef.funcretsym).refs);
  793. tvarsym(current_procdef.funcretsym).varstate:=vs_assigned;
  794. end;
  795. end;
  796. end;
  797. if assigned(left) then
  798. begin
  799. resulttypepass(left);
  800. set_varstate(left,true);
  801. end;
  802. resulttype:=voidtype;
  803. end;
  804. function texitnode.pass_1 : tnode;
  805. begin
  806. result:=nil;
  807. expectloc:=LOC_VOID;
  808. if assigned(left) then
  809. begin
  810. firstpass(left);
  811. if codegenerror then
  812. exit;
  813. registers32:=left.registers32;
  814. registersfpu:=left.registersfpu;
  815. {$ifdef SUPPORT_MMX}
  816. registersmmx:=left.registersmmx;
  817. {$endif SUPPORT_MMX}
  818. end;
  819. end;
  820. {*****************************************************************************
  821. TBREAKNODE
  822. *****************************************************************************}
  823. constructor tbreaknode.create;
  824. begin
  825. inherited create(breakn);
  826. end;
  827. function tbreaknode.det_resulttype:tnode;
  828. begin
  829. result:=nil;
  830. resulttype:=voidtype;
  831. end;
  832. function tbreaknode.pass_1 : tnode;
  833. begin
  834. result:=nil;
  835. expectloc:=LOC_VOID;
  836. end;
  837. {*****************************************************************************
  838. TCONTINUENODE
  839. *****************************************************************************}
  840. constructor tcontinuenode.create;
  841. begin
  842. inherited create(continuen);
  843. end;
  844. function tcontinuenode.det_resulttype:tnode;
  845. begin
  846. result:=nil;
  847. resulttype:=voidtype;
  848. end;
  849. function tcontinuenode.pass_1 : tnode;
  850. begin
  851. result:=nil;
  852. expectloc:=LOC_VOID;
  853. end;
  854. {*****************************************************************************
  855. TGOTONODE
  856. *****************************************************************************}
  857. constructor tgotonode.create(p : tlabelsym);
  858. begin
  859. inherited create(goton);
  860. exceptionblock:=aktexceptblock;
  861. labsym:=p;
  862. end;
  863. constructor tgotonode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  864. begin
  865. inherited ppuload(t,ppufile);
  866. labsym:=tlabelsym(ppufile.getderef);
  867. exceptionblock:=ppufile.getbyte;
  868. end;
  869. procedure tgotonode.ppuwrite(ppufile:tcompilerppufile);
  870. begin
  871. inherited ppuwrite(ppufile);
  872. ppufile.putderef(labsym);
  873. ppufile.putbyte(exceptionblock);
  874. end;
  875. procedure tgotonode.derefimpl;
  876. begin
  877. inherited derefimpl;
  878. resolvesym(pointer(labsym));
  879. end;
  880. function tgotonode.det_resulttype:tnode;
  881. begin
  882. result:=nil;
  883. resulttype:=voidtype;
  884. end;
  885. function tgotonode.pass_1 : tnode;
  886. begin
  887. result:=nil;
  888. expectloc:=LOC_VOID;
  889. { check if }
  890. if assigned(labsym) and
  891. assigned(labsym.code) and
  892. (exceptionblock<>tlabelnode(labsym.code).exceptionblock) then
  893. begin
  894. writeln('goto exceptblock: ',exceptionblock);
  895. writeln('label exceptblock: ',tlabelnode(labsym.code).exceptionblock);
  896. CGMessage(cg_e_goto_inout_of_exception_block);
  897. end;
  898. end;
  899. function tgotonode.getcopy : tnode;
  900. var
  901. p : tgotonode;
  902. begin
  903. p:=tgotonode(inherited getcopy);
  904. p.labsym:=labsym;
  905. p.exceptionblock:=exceptionblock;
  906. result:=p;
  907. end;
  908. function tgotonode.docompare(p: tnode): boolean;
  909. begin
  910. docompare := false;
  911. end;
  912. {*****************************************************************************
  913. TLABELNODE
  914. *****************************************************************************}
  915. constructor tlabelnode.createcase(p : tasmlabel;l:tnode);
  916. begin
  917. inherited create(labeln,l);
  918. { it shouldn't be possible to jump to case labels using goto }
  919. exceptionblock:=-1;
  920. labsym:=nil;
  921. labelnr:=p;
  922. end;
  923. constructor tlabelnode.create(p : tlabelsym;l:tnode);
  924. begin
  925. inherited create(labeln,l);
  926. exceptionblock:=aktexceptblock;
  927. labsym:=p;
  928. labelnr:=p.lab;
  929. { save the current labelnode in the labelsym }
  930. p.code:=self;
  931. end;
  932. constructor tlabelnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  933. begin
  934. inherited ppuload(t,ppufile);
  935. labsym:=tlabelsym(ppufile.getderef);
  936. labelnr:=tasmlabel(ppufile.getasmsymbol);
  937. exceptionblock:=ppufile.getbyte;
  938. end;
  939. procedure tlabelnode.ppuwrite(ppufile:tcompilerppufile);
  940. begin
  941. inherited ppuwrite(ppufile);
  942. ppufile.putderef(labsym);
  943. ppufile.putasmsymbol(labelnr);
  944. ppufile.putbyte(exceptionblock);
  945. end;
  946. procedure tlabelnode.derefimpl;
  947. begin
  948. inherited derefimpl;
  949. resolvesym(pointer(labsym));
  950. objectlibrary.derefasmsymbol(tasmsymbol(labelnr));
  951. end;
  952. function tlabelnode.det_resulttype:tnode;
  953. begin
  954. result:=nil;
  955. { left could still be unassigned }
  956. if assigned(left) then
  957. resulttypepass(left);
  958. resulttype:=voidtype;
  959. end;
  960. function tlabelnode.pass_1 : tnode;
  961. begin
  962. result:=nil;
  963. expectloc:=LOC_VOID;
  964. if assigned(left) then
  965. begin
  966. {$ifndef newra}
  967. rg.cleartempgen;
  968. {$endif}
  969. firstpass(left);
  970. registers32:=left.registers32;
  971. registersfpu:=left.registersfpu;
  972. {$ifdef SUPPORT_MMX}
  973. registersmmx:=left.registersmmx;
  974. {$endif SUPPORT_MMX}
  975. end;
  976. end;
  977. function tlabelnode.getcopy : tnode;
  978. var
  979. p : tlabelnode;
  980. begin
  981. p:=tlabelnode(inherited getcopy);
  982. p.labelnr:=labelnr;
  983. p.exceptionblock:=exceptionblock;
  984. p.labsym:=labsym;
  985. result:=p;
  986. end;
  987. function tlabelnode.docompare(p: tnode): boolean;
  988. begin
  989. docompare := false;
  990. end;
  991. {*****************************************************************************
  992. TRAISENODE
  993. *****************************************************************************}
  994. constructor traisenode.create(l,taddr,tframe:tnode);
  995. begin
  996. inherited create(raisen,l,taddr);
  997. frametree:=tframe;
  998. end;
  999. constructor traisenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  1000. begin
  1001. inherited ppuload(t,ppufile);
  1002. frametree:=ppuloadnode(ppufile);
  1003. end;
  1004. procedure traisenode.ppuwrite(ppufile:tcompilerppufile);
  1005. begin
  1006. inherited ppuwrite(ppufile);
  1007. ppuwritenode(ppufile,frametree);
  1008. end;
  1009. procedure traisenode.derefimpl;
  1010. begin
  1011. inherited derefimpl;
  1012. if assigned(frametree) then
  1013. frametree.derefimpl;
  1014. end;
  1015. function traisenode.getcopy : tnode;
  1016. var
  1017. n : traisenode;
  1018. begin
  1019. n:=traisenode(inherited getcopy);
  1020. if assigned(frametree) then
  1021. n.frametree:=frametree.getcopy
  1022. else
  1023. n.frametree:=nil;
  1024. getcopy:=n;
  1025. end;
  1026. procedure traisenode.insertintolist(l : tnodelist);
  1027. begin
  1028. end;
  1029. function traisenode.det_resulttype:tnode;
  1030. begin
  1031. result:=nil;
  1032. resulttype:=voidtype;
  1033. if assigned(left) then
  1034. begin
  1035. { first para must be a _class_ }
  1036. resulttypepass(left);
  1037. set_varstate(left,true);
  1038. if codegenerror then
  1039. exit;
  1040. if not(is_class(left.resulttype.def)) then
  1041. CGMessage(type_e_mismatch);
  1042. { insert needed typeconvs for addr,frame }
  1043. if assigned(right) then
  1044. begin
  1045. { addr }
  1046. resulttypepass(right);
  1047. inserttypeconv(right,voidpointertype);
  1048. { frame }
  1049. if assigned(frametree) then
  1050. begin
  1051. resulttypepass(frametree);
  1052. inserttypeconv(frametree,voidpointertype);
  1053. end;
  1054. end;
  1055. end;
  1056. end;
  1057. function traisenode.pass_1 : tnode;
  1058. begin
  1059. result:=nil;
  1060. expectloc:=LOC_VOID;
  1061. if assigned(left) then
  1062. begin
  1063. { first para must be a _class_ }
  1064. firstpass(left);
  1065. { insert needed typeconvs for addr,frame }
  1066. if assigned(right) then
  1067. begin
  1068. { addr }
  1069. firstpass(right);
  1070. { frame }
  1071. if assigned(frametree) then
  1072. firstpass(frametree);
  1073. end;
  1074. left_right_max;
  1075. end;
  1076. end;
  1077. function traisenode.docompare(p: tnode): boolean;
  1078. begin
  1079. docompare := false;
  1080. end;
  1081. {*****************************************************************************
  1082. TTRYEXCEPTNODE
  1083. *****************************************************************************}
  1084. constructor ttryexceptnode.create(l,r,_t1 : tnode);
  1085. begin
  1086. inherited create(tryexceptn,l,r,_t1,nil);
  1087. end;
  1088. function ttryexceptnode.det_resulttype:tnode;
  1089. begin
  1090. result:=nil;
  1091. resulttypepass(left);
  1092. { on statements }
  1093. if assigned(right) then
  1094. resulttypepass(right);
  1095. { else block }
  1096. if assigned(t1) then
  1097. resulttypepass(t1);
  1098. resulttype:=voidtype;
  1099. end;
  1100. function ttryexceptnode.pass_1 : tnode;
  1101. begin
  1102. result:=nil;
  1103. expectloc:=LOC_VOID;
  1104. {$ifndef newra}
  1105. rg.cleartempgen;
  1106. {$endif}
  1107. firstpass(left);
  1108. { on statements }
  1109. if assigned(right) then
  1110. begin
  1111. {$ifndef newra}
  1112. rg.cleartempgen;
  1113. {$endif}
  1114. firstpass(right);
  1115. registers32:=max(registers32,right.registers32);
  1116. registersfpu:=max(registersfpu,right.registersfpu);
  1117. {$ifdef SUPPORT_MMX}
  1118. registersmmx:=max(registersmmx,right.registersmmx);
  1119. {$endif SUPPORT_MMX}
  1120. end;
  1121. { else block }
  1122. if assigned(t1) then
  1123. begin
  1124. firstpass(t1);
  1125. registers32:=max(registers32,t1.registers32);
  1126. registersfpu:=max(registersfpu,t1.registersfpu);
  1127. {$ifdef SUPPORT_MMX}
  1128. registersmmx:=max(registersmmx,t1.registersmmx);
  1129. {$endif SUPPORT_MMX}
  1130. end;
  1131. end;
  1132. {*****************************************************************************
  1133. TTRYFINALLYNODE
  1134. *****************************************************************************}
  1135. constructor ttryfinallynode.create(l,r:tnode);
  1136. begin
  1137. inherited create(tryfinallyn,l,r);
  1138. end;
  1139. function ttryfinallynode.det_resulttype:tnode;
  1140. begin
  1141. result:=nil;
  1142. resulttype:=voidtype;
  1143. resulttypepass(left);
  1144. set_varstate(left,true);
  1145. resulttypepass(right);
  1146. set_varstate(right,true);
  1147. end;
  1148. function ttryfinallynode.pass_1 : tnode;
  1149. begin
  1150. result:=nil;
  1151. expectloc:=LOC_VOID;
  1152. {$ifndef newra}
  1153. rg.cleartempgen;
  1154. {$endif}
  1155. firstpass(left);
  1156. {$ifndef newra}
  1157. rg.cleartempgen;
  1158. {$endif}
  1159. firstpass(right);
  1160. left_right_max;
  1161. end;
  1162. {*****************************************************************************
  1163. TONNODE
  1164. *****************************************************************************}
  1165. constructor tonnode.create(l,r:tnode);
  1166. begin
  1167. inherited create(onn,l,r);
  1168. exceptsymtable:=nil;
  1169. excepttype:=nil;
  1170. end;
  1171. destructor tonnode.destroy;
  1172. begin
  1173. if assigned(exceptsymtable) then
  1174. exceptsymtable.free;
  1175. inherited destroy;
  1176. end;
  1177. constructor tonnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  1178. begin
  1179. inherited ppuload(t,ppufile);
  1180. exceptsymtable:=nil;
  1181. excepttype:=nil;
  1182. end;
  1183. function tonnode.getcopy : tnode;
  1184. var
  1185. n : tonnode;
  1186. begin
  1187. n:=tonnode(inherited getcopy);
  1188. n.exceptsymtable:=exceptsymtable;
  1189. n.excepttype:=excepttype;
  1190. result:=n;
  1191. end;
  1192. function tonnode.det_resulttype:tnode;
  1193. begin
  1194. result:=nil;
  1195. resulttype:=voidtype;
  1196. if not(is_class(excepttype)) then
  1197. CGMessage(type_e_mismatch);
  1198. if assigned(left) then
  1199. resulttypepass(left);
  1200. if assigned(right) then
  1201. resulttypepass(right);
  1202. end;
  1203. function tonnode.pass_1 : tnode;
  1204. begin
  1205. result:=nil;
  1206. expectloc:=LOC_VOID;
  1207. rg.cleartempgen;
  1208. registers32:=0;
  1209. registersfpu:=0;
  1210. {$ifdef SUPPORT_MMX}
  1211. registersmmx:=0;
  1212. {$endif SUPPORT_MMX}
  1213. if assigned(left) then
  1214. begin
  1215. firstpass(left);
  1216. registers32:=left.registers32;
  1217. registersfpu:=left.registersfpu;
  1218. {$ifdef SUPPORT_MMX}
  1219. registersmmx:=left.registersmmx;
  1220. {$endif SUPPORT_MMX}
  1221. end;
  1222. rg.cleartempgen;
  1223. if assigned(right) then
  1224. begin
  1225. firstpass(right);
  1226. registers32:=max(registers32,right.registers32);
  1227. registersfpu:=max(registersfpu,right.registersfpu);
  1228. {$ifdef SUPPORT_MMX}
  1229. registersmmx:=max(registersmmx,right.registersmmx);
  1230. {$endif SUPPORT_MMX}
  1231. end;
  1232. end;
  1233. function tonnode.docompare(p: tnode): boolean;
  1234. begin
  1235. docompare := false;
  1236. end;
  1237. {*****************************************************************************
  1238. TFAILNODE
  1239. *****************************************************************************}
  1240. constructor tfailnode.create;
  1241. begin
  1242. inherited create(failn);
  1243. end;
  1244. function tfailnode.det_resulttype:tnode;
  1245. begin
  1246. result:=nil;
  1247. resulttype:=voidtype;
  1248. end;
  1249. function tfailnode.pass_1 : tnode;
  1250. begin
  1251. result:=nil;
  1252. expectloc:=LOC_VOID;
  1253. end;
  1254. function tfailnode.docompare(p: tnode): boolean;
  1255. begin
  1256. docompare := false;
  1257. end;
  1258. begin
  1259. cwhilerepeatnode:=twhilerepeatnode;
  1260. cifnode:=tifnode;
  1261. cfornode:=tfornode;
  1262. cexitnode:=texitnode;
  1263. cgotonode:=tgotonode;
  1264. clabelnode:=tlabelnode;
  1265. craisenode:=traisenode;
  1266. ctryexceptnode:=ttryexceptnode;
  1267. ctryfinallynode:=ttryfinallynode;
  1268. connode:=tonnode;
  1269. cfailnode:=tfailnode;
  1270. end.
  1271. {
  1272. $Log$
  1273. Revision 1.72 2003-05-01 07:59:42 florian
  1274. * introduced defaultordconsttype to decribe the default size of ordinal constants
  1275. on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
  1276. + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
  1277. * int64s/qwords are allowed as for loop counter on 64 bit CPUs
  1278. Revision 1.71 2003/04/27 11:21:33 peter
  1279. * aktprocdef renamed to current_procdef
  1280. * procinfo renamed to current_procinfo
  1281. * procinfo will now be stored in current_module so it can be
  1282. cleaned up properly
  1283. * gen_main_procsym changed to create_main_proc and release_main_proc
  1284. to also generate a tprocinfo structure
  1285. * fixed unit implicit initfinal
  1286. Revision 1.70 2003/04/27 07:29:50 peter
  1287. * current_procdef cleanup, current_procdef is now always nil when parsing
  1288. a new procdef declaration
  1289. * aktprocsym removed
  1290. * lexlevel removed, use symtable.symtablelevel instead
  1291. * implicit init/final code uses the normal genentry/genexit
  1292. * funcret state checking updated for new funcret handling
  1293. Revision 1.69 2003/04/26 00:28:41 peter
  1294. * removed load_funcret
  1295. Revision 1.68 2003/04/25 20:59:33 peter
  1296. * removed funcretn,funcretsym, function result is now in varsym
  1297. and aliases for result and function name are added using absolutesym
  1298. * vs_hidden parameter for funcret passed in parameter
  1299. * vs_hidden fixes
  1300. * writenode changed to printnode and released from extdebug
  1301. * -vp option added to generate a tree.log with the nodetree
  1302. * nicer printnode for statements, callnode
  1303. Revision 1.67 2003/04/25 08:25:26 daniel
  1304. * Ifdefs around a lot of calls to cleartempgen
  1305. * Fixed registers that are allocated but not freed in several nodes
  1306. * Tweak to register allocator to cause less spills
  1307. * 8-bit registers now interfere with esi,edi and ebp
  1308. Compiler can now compile rtl successfully when using new register
  1309. allocator
  1310. Revision 1.66 2003/04/22 23:50:23 peter
  1311. * firstpass uses expectloc
  1312. * checks if there are differences between the expectloc and
  1313. location.loc from secondpass in EXTDEBUG
  1314. Revision 1.65 2003/03/20 15:54:46 peter
  1315. * don't allow var and out parameters as for loop counter
  1316. Revision 1.64 2003/01/09 21:52:37 peter
  1317. * merged some verbosity options.
  1318. * V_LineInfo is a verbosity flag to include line info
  1319. Revision 1.63 2003/01/04 08:08:47 daniel
  1320. * Readded missing variable
  1321. Revision 1.62 2003/01/03 17:16:57 peter
  1322. * fixed warning about unset funcret
  1323. Revision 1.61 2003/01/03 12:15:56 daniel
  1324. * Removed ifdefs around notifications
  1325. ifdefs around for loop optimizations remain
  1326. Revision 1.60 2002/12/31 09:55:58 daniel
  1327. + Notification implementation complete
  1328. + Add for loop code optimization using notifications
  1329. results in 1.5-1.9% speed improvement in nestloop benchmark
  1330. Optimization incomplete, compiler does not cycle yet with
  1331. notifications enabled.
  1332. Revision 1.59 2002/12/30 22:44:53 daniel
  1333. * Some work on notifications
  1334. Revision 1.58 2002/12/27 15:25:40 peter
  1335. * do not allow threadvar as loop counter
  1336. Revision 1.57 2002/11/28 11:17:02 florian
  1337. * loop node flags from node flags splitted
  1338. Revision 1.56 2002/11/25 17:43:18 peter
  1339. * splitted defbase in defutil,symutil,defcmp
  1340. * merged isconvertable and is_equal into compare_defs(_ext)
  1341. * made operator search faster by walking the list only once
  1342. Revision 1.55 2002/11/18 17:31:56 peter
  1343. * pass proccalloption to ret_in_xxx and push_xxx functions
  1344. Revision 1.54 2002/10/20 15:31:49 peter
  1345. * set funcret state for exit(0)
  1346. Revision 1.53 2002/10/05 12:43:25 carl
  1347. * fixes for Delphi 6 compilation
  1348. (warning : Some features do not work under Delphi)
  1349. Revision 1.52 2002/09/07 15:25:03 peter
  1350. * old logs removed and tabs fixed
  1351. Revision 1.51 2002/09/07 12:16:04 carl
  1352. * second part bug report 1996 fix, testrange in cordconstnode
  1353. only called if option is set (also make parsing a tiny faster)
  1354. Revision 1.50 2002/09/01 18:47:00 peter
  1355. * assignn check in exitnode changed to use a separate boolean as the
  1356. assignn can be changed to a calln
  1357. Revision 1.49 2002/09/01 08:01:16 daniel
  1358. * Removed sets from Tcallnode.det_resulttype
  1359. + Added read/write notifications of variables. These will be usefull
  1360. for providing information for several optimizations. For example
  1361. the value of the loop variable of a for loop does matter is the
  1362. variable is read after the for loop, but if it's no longer used
  1363. or written, it doesn't matter and this can be used to optimize
  1364. the loop code generation.
  1365. Revision 1.48 2002/08/22 15:15:20 daniel
  1366. * Fixed the detection wether the first check of a for loop can be skipped
  1367. Revision 1.47 2002/08/19 19:36:43 peter
  1368. * More fixes for cross unit inlining, all tnodes are now implemented
  1369. * Moved pocall_internconst to po_internconst because it is not a
  1370. calling type at all and it conflicted when inlining of these small
  1371. functions was requested
  1372. Revision 1.46 2002/08/17 22:09:46 florian
  1373. * result type handling in tcgcal.pass_2 overhauled
  1374. * better tnode.dowrite
  1375. * some ppc stuff fixed
  1376. Revision 1.45 2002/08/17 09:23:37 florian
  1377. * first part of current_procinfo rewrite
  1378. Revision 1.44 2002/07/21 06:58:49 daniel
  1379. * Changed booleans into flags
  1380. Revision 1.43 2002/07/20 11:57:54 florian
  1381. * types.pas renamed to defbase.pas because D6 contains a types
  1382. unit so this would conflicts if D6 programms are compiled
  1383. + Willamette/SSE2 instructions to assembler added
  1384. Revision 1.42 2002/07/20 11:18:18 daniel
  1385. * Small mistake fixed; the skip test was done before we know the for node
  1386. is correct.
  1387. Revision 1.40 2002/07/20 08:19:31 daniel
  1388. * State tracker automatically changes while loops into repeat loops
  1389. Revision 1.39 2002/07/19 12:55:27 daniel
  1390. * Further developed state tracking in whilerepeatn
  1391. Revision 1.38 2002/07/19 11:41:35 daniel
  1392. * State tracker work
  1393. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1394. allows the state tracker to change while nodes automatically into
  1395. repeat nodes.
  1396. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1397. 'not(a>b)' is optimized into 'a<=b'.
  1398. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1399. by removing the notn and later switchting the true and falselabels. The
  1400. same is done with 'repeat until not a'.
  1401. Revision 1.37 2002/07/16 13:57:02 florian
  1402. * raise takes now a void pointer as at and frame address
  1403. instead of a longint
  1404. Revision 1.36 2002/07/15 18:03:15 florian
  1405. * readded removed changes
  1406. Revision 1.35 2002/07/14 18:00:44 daniel
  1407. + Added the beginning of a state tracker. This will track the values of
  1408. variables through procedures and optimize things away.
  1409. Revision 1.34 2002/07/11 14:41:28 florian
  1410. * start of the new generic parameter handling
  1411. Revision 1.33 2002/07/01 18:46:23 peter
  1412. * internal linker
  1413. * reorganized aasm layer
  1414. Revision 1.32 2002/05/18 13:34:10 peter
  1415. * readded missing revisions
  1416. Revision 1.31 2002/05/16 19:46:38 carl
  1417. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1418. + try to fix temp allocation (still in ifdef)
  1419. + generic constructor calls
  1420. + start of tassembler / tmodulebase class cleanup
  1421. }