pstatmnt.pas 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Does the parsing of the statements
  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 pstatmnt;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. tokens,node;
  23. function statement_block(starttoken : ttoken) : tnode;
  24. { reads an assembler block }
  25. function assembler_block : tnode;
  26. implementation
  27. uses
  28. { common }
  29. cutils,cclasses,
  30. { global }
  31. globtype,globals,verbose,
  32. systems,cpuinfo,
  33. { aasm }
  34. cpubase,aasmbase,aasmtai,
  35. { symtable }
  36. symconst,symbase,symtype,symdef,symsym,symtable,defutil,defcmp,
  37. paramgr,symutil,
  38. { pass 1 }
  39. pass_1,htypechk,
  40. nutils,nbas,nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
  41. { parser }
  42. scanner,
  43. pbase,pexpr,
  44. { codegen }
  45. procinfo,cgbase,
  46. { assembler reader }
  47. rabase
  48. ;
  49. function statement : tnode;forward;
  50. function if_statement : tnode;
  51. var
  52. ex,if_a,else_a : tnode;
  53. begin
  54. consume(_IF);
  55. ex:=comp_expr(true);
  56. consume(_THEN);
  57. if token<>_ELSE then
  58. if_a:=statement
  59. else
  60. if_a:=nil;
  61. if try_to_consume(_ELSE) then
  62. else_a:=statement
  63. else
  64. else_a:=nil;
  65. if_statement:=genloopnode(ifn,ex,if_a,else_a,false);
  66. end;
  67. { creates a block (list) of statements, til the next END token }
  68. function statements_til_end : tnode;
  69. var
  70. first,last : tstatementnode;
  71. begin
  72. first:=nil;
  73. while token<>_END do
  74. begin
  75. if first=nil then
  76. begin
  77. last:=cstatementnode.create(statement,nil);
  78. first:=last;
  79. end
  80. else
  81. begin
  82. last.right:=cstatementnode.create(statement,nil);
  83. last:=tstatementnode(last.right);
  84. end;
  85. if not try_to_consume(_SEMICOLON) then
  86. break;
  87. consume_emptystats;
  88. end;
  89. consume(_END);
  90. statements_til_end:=cblocknode.create(first);
  91. end;
  92. function case_statement : tnode;
  93. var
  94. { contains the label number of currently parsed case block }
  95. aktcaselabel : tasmlabel;
  96. firstlabel : boolean;
  97. root : pcaserecord;
  98. { the typ of the case expression }
  99. casedef : tdef;
  100. procedure newcaselabel(l,h : TConstExprInt;first:boolean);
  101. var
  102. hcaselabel : pcaserecord;
  103. procedure insertlabel(var p : pcaserecord);
  104. begin
  105. if p=nil then p:=hcaselabel
  106. else
  107. if (p^._low>hcaselabel^._low) and
  108. (p^._low>hcaselabel^._high) then
  109. if (hcaselabel^.statement = p^.statement) and
  110. (p^._low = hcaselabel^._high + 1) then
  111. begin
  112. p^._low := hcaselabel^._low;
  113. dispose(hcaselabel);
  114. end
  115. else
  116. insertlabel(p^.less)
  117. else
  118. if (p^._high<hcaselabel^._low) and
  119. (p^._high<hcaselabel^._high) then
  120. if (hcaselabel^.statement = p^.statement) and
  121. (p^._high+1 = hcaselabel^._low) then
  122. begin
  123. p^._high := hcaselabel^._high;
  124. dispose(hcaselabel);
  125. end
  126. else
  127. insertlabel(p^.greater)
  128. else Message(parser_e_double_caselabel);
  129. end;
  130. begin
  131. new(hcaselabel);
  132. hcaselabel^.less:=nil;
  133. hcaselabel^.greater:=nil;
  134. hcaselabel^.statement:=aktcaselabel;
  135. hcaselabel^.firstlabel:=first;
  136. objectlibrary.getlabel(hcaselabel^._at);
  137. hcaselabel^._low:=l;
  138. hcaselabel^._high:=h;
  139. insertlabel(root);
  140. end;
  141. var
  142. code,caseexpr,p,instruc,elseblock : tnode;
  143. hl1,hl2 : TConstExprInt;
  144. casedeferror : boolean;
  145. begin
  146. consume(_CASE);
  147. caseexpr:=comp_expr(true);
  148. { determines result type }
  149. do_resulttypepass(caseexpr);
  150. set_varstate(caseexpr,vs_used,true);
  151. casedeferror:=false;
  152. casedef:=caseexpr.resulttype.def;
  153. if (not assigned(casedef)) or
  154. not(is_ordinal(casedef)) then
  155. begin
  156. CGMessage(type_e_ordinal_expr_expected);
  157. { create a correct tree }
  158. caseexpr.free;
  159. caseexpr:=cordconstnode.create(0,u32inttype,false);
  160. { set error flag so no rangechecks are done }
  161. casedeferror:=true;
  162. end;
  163. consume(_OF);
  164. root:=nil;
  165. instruc:=nil;
  166. repeat
  167. objectlibrary.getlabel(aktcaselabel);
  168. firstlabel:=true;
  169. { maybe an instruction has more case labels }
  170. repeat
  171. p:=expr;
  172. if is_widechar(casedef) then
  173. begin
  174. if (p.nodetype=rangen) then
  175. begin
  176. trangenode(p).left:=ctypeconvnode.create(trangenode(p).left,cwidechartype);
  177. trangenode(p).right:=ctypeconvnode.create(trangenode(p).right,cwidechartype);
  178. do_resulttypepass(trangenode(p).left);
  179. do_resulttypepass(trangenode(p).right);
  180. end
  181. else
  182. begin
  183. p:=ctypeconvnode.create(p,cwidechartype);
  184. do_resulttypepass(p);
  185. end;
  186. end;
  187. hl1:=0;
  188. hl2:=0;
  189. if (p.nodetype=rangen) then
  190. begin
  191. { type checking for case statements }
  192. if is_subequal(casedef, trangenode(p).left.resulttype.def) and
  193. is_subequal(casedef, trangenode(p).right.resulttype.def) then
  194. begin
  195. hl1:=get_ordinal_value(trangenode(p).left);
  196. hl2:=get_ordinal_value(trangenode(p).right);
  197. if hl1>hl2 then
  198. CGMessage(parser_e_case_lower_less_than_upper_bound);
  199. if not casedeferror then
  200. begin
  201. testrange(casedef,hl1,false);
  202. testrange(casedef,hl2,false);
  203. end;
  204. end
  205. else
  206. CGMessage(parser_e_case_mismatch);
  207. newcaselabel(hl1,hl2,firstlabel);
  208. end
  209. else
  210. begin
  211. { type checking for case statements }
  212. if not is_subequal(casedef, p.resulttype.def) then
  213. CGMessage(parser_e_case_mismatch);
  214. hl1:=get_ordinal_value(p);
  215. if not casedeferror then
  216. testrange(casedef,hl1,false);
  217. newcaselabel(hl1,hl1,firstlabel);
  218. end;
  219. p.free;
  220. if token=_COMMA then
  221. consume(_COMMA)
  222. else
  223. break;
  224. firstlabel:=false;
  225. until false;
  226. consume(_COLON);
  227. { handles instruction block }
  228. p:=clabelnode.createcase(aktcaselabel,statement);
  229. { concats instruction }
  230. instruc:=cstatementnode.create(p,instruc);
  231. if not(token in [_ELSE,_OTHERWISE,_END]) then
  232. consume(_SEMICOLON);
  233. until (token in [_ELSE,_OTHERWISE,_END]);
  234. if (token in [_ELSE,_OTHERWISE]) then
  235. begin
  236. if not try_to_consume(_ELSE) then
  237. consume(_OTHERWISE);
  238. elseblock:=statements_til_end;
  239. end
  240. else
  241. begin
  242. elseblock:=nil;
  243. consume(_END);
  244. end;
  245. code:=ccasenode.create(caseexpr,instruc,root);
  246. tcasenode(code).elseblock:=elseblock;
  247. case_statement:=code;
  248. end;
  249. function repeat_statement : tnode;
  250. var
  251. first,last,p_e : tnode;
  252. begin
  253. consume(_REPEAT);
  254. first:=nil;
  255. while token<>_UNTIL do
  256. begin
  257. if first=nil then
  258. begin
  259. last:=cstatementnode.create(statement,nil);
  260. first:=last;
  261. end
  262. else
  263. begin
  264. tstatementnode(last).right:=cstatementnode.create(statement,nil);
  265. last:=tstatementnode(last).right;
  266. end;
  267. if not try_to_consume(_SEMICOLON) then
  268. break;
  269. consume_emptystats;
  270. end;
  271. consume(_UNTIL);
  272. first:=cblocknode.create(first);
  273. p_e:=comp_expr(true);
  274. repeat_statement:=genloopnode(whilerepeatn,p_e,first,nil,true);
  275. end;
  276. function while_statement : tnode;
  277. var
  278. p_e,p_a : tnode;
  279. begin
  280. consume(_WHILE);
  281. p_e:=comp_expr(true);
  282. consume(_DO);
  283. p_a:=statement;
  284. while_statement:=genloopnode(whilerepeatn,p_e,p_a,nil,false);
  285. end;
  286. function for_statement : tnode;
  287. var
  288. p_e,tovalue,p_a : tnode;
  289. backward : boolean;
  290. begin
  291. { parse loop header }
  292. consume(_FOR);
  293. p_e:=expr;
  294. if token=_DOWNTO then
  295. begin
  296. consume(_DOWNTO);
  297. backward:=true;
  298. end
  299. else
  300. begin
  301. consume(_TO);
  302. backward:=false;
  303. end;
  304. tovalue:=comp_expr(true);
  305. consume(_DO);
  306. { ... now the instruction }
  307. p_a:=statement;
  308. for_statement:=genloopnode(forn,p_e,tovalue,p_a,backward);
  309. end;
  310. function _with_statement : tnode;
  311. var
  312. right,p : tnode;
  313. i,levelcount : longint;
  314. withsymtable,symtab : tsymtable;
  315. obj : tobjectdef;
  316. hp : tnode;
  317. newblock : tblocknode;
  318. newstatement : tstatementnode;
  319. calltempp,
  320. loadp : ttempcreatenode;
  321. refp : tnode;
  322. htype : ttype;
  323. hasimplicitderef : boolean;
  324. begin
  325. p:=comp_expr(true);
  326. do_resulttypepass(p);
  327. set_varstate(p,vs_used,false);
  328. right:=nil;
  329. if (not codegenerror) and
  330. (p.resulttype.def.deftype in [objectdef,recorddef]) then
  331. begin
  332. newblock:=nil;
  333. { ignore nodes that don't add instructions in the tree }
  334. hp:=p;
  335. while { equal type conversions }
  336. (
  337. (hp.nodetype=typeconvn) and
  338. (ttypeconvnode(hp).convtype=tc_equal)
  339. ) or
  340. { constant array index }
  341. (
  342. (hp.nodetype=vecn) and
  343. (tvecnode(hp).right.nodetype=ordconstn)
  344. ) do
  345. hp:=tunarynode(hp).left;
  346. if (hp.nodetype=loadn) and
  347. (
  348. (tloadnode(hp).symtable=current_procinfo.procdef.localst) or
  349. (tloadnode(hp).symtable=current_procinfo.procdef.parast) or
  350. (tloadnode(hp).symtable.symtabletype in [staticsymtable,globalsymtable])
  351. ) then
  352. begin
  353. { simple load, we can reference direct }
  354. loadp:=nil;
  355. refp:=p;
  356. end
  357. else
  358. begin
  359. calltempp:=nil;
  360. { complex load, load in temp first }
  361. newblock:=internalstatements(newstatement);
  362. { when right is a call then load it first in a temp }
  363. if p.nodetype=calln then
  364. begin
  365. calltempp:=ctempcreatenode.create(p.resulttype,p.resulttype.def.size,tt_persistent);
  366. addstatement(newstatement,calltempp);
  367. addstatement(newstatement,cassignmentnode.create(
  368. ctemprefnode.create(calltempp),
  369. p));
  370. p:=ctemprefnode.create(calltempp);
  371. resulttypepass(p);
  372. end;
  373. { classes and interfaces have implicit dereferencing }
  374. hasimplicitderef:=is_class_or_interface(p.resulttype.def);
  375. if hasimplicitderef then
  376. htype:=p.resulttype
  377. else
  378. htype.setdef(tpointerdef.create(p.resulttype));
  379. { we can't generate debuginfo for a withnode stored in a }
  380. { register }
  381. if (cs_debuginfo in aktmoduleswitches) then
  382. loadp:=ctempcreatenode.create(htype,POINTER_SIZE,tt_persistent)
  383. else
  384. loadp:=ctempcreatenode.create_reg(htype,POINTER_SIZE,tt_persistent);
  385. resulttypepass(loadp);
  386. if hasimplicitderef then
  387. begin
  388. hp:=p;
  389. refp:=ctemprefnode.create(loadp);
  390. end
  391. else
  392. begin
  393. hp:=caddrnode.create(p);
  394. refp:=cderefnode.create(ctemprefnode.create(loadp));
  395. end;
  396. addstatement(newstatement,loadp);
  397. addstatement(newstatement,cassignmentnode.create(
  398. ctemprefnode.create(loadp),
  399. hp));
  400. resulttypepass(refp);
  401. end;
  402. case p.resulttype.def.deftype of
  403. objectdef :
  404. begin
  405. obj:=tobjectdef(p.resulttype.def);
  406. withsymtable:=twithsymtable.Create(obj,obj.symtable.symsearch,refp);
  407. { include also all parent symtables }
  408. levelcount:=1;
  409. obj:=obj.childof;
  410. symtab:=withsymtable;
  411. while assigned(obj) do
  412. begin
  413. { keep the original tobjectdef as owner, because that is used for
  414. visibility of the symtable }
  415. symtab.next:=twithsymtable.create(tobjectdef(p.resulttype.def),obj.symtable.symsearch,refp.getcopy);
  416. symtab:=symtab.next;
  417. obj:=obj.childof;
  418. inc(levelcount);
  419. end;
  420. symtab.next:=symtablestack;
  421. symtablestack:=withsymtable;
  422. end;
  423. recorddef :
  424. begin
  425. symtab:=trecorddef(p.resulttype.def).symtable;
  426. levelcount:=1;
  427. withsymtable:=twithsymtable.create(trecorddef(p.resulttype.def),symtab.symsearch,refp);
  428. withsymtable.next:=symtablestack;
  429. symtablestack:=withsymtable;
  430. end;
  431. end;
  432. if try_to_consume(_COMMA) then
  433. right:=_with_statement{$ifdef FPCPROCVAR}(){$endif}
  434. else
  435. begin
  436. consume(_DO);
  437. if token<>_SEMICOLON then
  438. right:=statement
  439. else
  440. right:=cerrornode.create;
  441. end;
  442. { remove symtables from the stack }
  443. for i:=1 to levelcount do
  444. symtablestack:=symtablestack.next;
  445. p:=cwithnode.create(right,twithsymtable(withsymtable),levelcount,refp);
  446. { Finalize complex withnode with destroy of temp }
  447. if assigned(newblock) then
  448. begin
  449. addstatement(newstatement,p);
  450. addstatement(newstatement,ctempdeletenode.create(loadp));
  451. if assigned(calltempp) then
  452. addstatement(newstatement,ctempdeletenode.create(calltempp));
  453. p:=newblock;
  454. end;
  455. _with_statement:=p;
  456. end
  457. else
  458. begin
  459. p.free;
  460. Message(parser_e_false_with_expr);
  461. { try to recover from error }
  462. if try_to_consume(_COMMA) then
  463. begin
  464. hp:=_with_statement{$ifdef FPCPROCVAR}(){$endif};
  465. if (hp=nil) then; { remove warning about unused }
  466. end
  467. else
  468. begin
  469. consume(_DO);
  470. { ignore all }
  471. if token<>_SEMICOLON then
  472. statement;
  473. end;
  474. _with_statement:=nil;
  475. end;
  476. end;
  477. function with_statement : tnode;
  478. begin
  479. consume(_WITH);
  480. with_statement:=_with_statement;
  481. end;
  482. function raise_statement : tnode;
  483. var
  484. p,pobj,paddr,pframe : tnode;
  485. begin
  486. pobj:=nil;
  487. paddr:=nil;
  488. pframe:=nil;
  489. consume(_RAISE);
  490. if not(token in endtokens) then
  491. begin
  492. { object }
  493. pobj:=comp_expr(true);
  494. if try_to_consume(_AT) then
  495. begin
  496. paddr:=comp_expr(true);
  497. if try_to_consume(_COMMA) then
  498. pframe:=comp_expr(true);
  499. end;
  500. end
  501. else
  502. begin
  503. if (block_type<>bt_except) then
  504. Message(parser_e_no_reraise_possible);
  505. end;
  506. p:=craisenode.create(pobj,paddr,pframe);
  507. raise_statement:=p;
  508. end;
  509. function try_statement : tnode;
  510. var
  511. p_try_block,p_finally_block,first,last,
  512. p_default,p_specific,hp : tnode;
  513. ot : ttype;
  514. sym : tvarsym;
  515. old_block_type : tblock_type;
  516. exceptsymtable : tsymtable;
  517. objname,objrealname : stringid;
  518. srsym : tsym;
  519. srsymtable : tsymtable;
  520. oldaktexceptblock: integer;
  521. begin
  522. include(current_procinfo.flags,pi_uses_exceptions);
  523. p_default:=nil;
  524. p_specific:=nil;
  525. { read statements to try }
  526. consume(_TRY);
  527. first:=nil;
  528. inc(exceptblockcounter);
  529. oldaktexceptblock := aktexceptblock;
  530. aktexceptblock := exceptblockcounter;
  531. while (token<>_FINALLY) and (token<>_EXCEPT) do
  532. begin
  533. if first=nil then
  534. begin
  535. last:=cstatementnode.create(statement,nil);
  536. first:=last;
  537. end
  538. else
  539. begin
  540. tstatementnode(last).right:=cstatementnode.create(statement,nil);
  541. last:=tstatementnode(last).right;
  542. end;
  543. if not try_to_consume(_SEMICOLON) then
  544. break;
  545. consume_emptystats;
  546. end;
  547. p_try_block:=cblocknode.create(first);
  548. if try_to_consume(_FINALLY) then
  549. begin
  550. inc(exceptblockcounter);
  551. aktexceptblock := exceptblockcounter;
  552. p_finally_block:=statements_til_end;
  553. try_statement:=ctryfinallynode.create(p_try_block,p_finally_block);
  554. end
  555. else
  556. begin
  557. consume(_EXCEPT);
  558. old_block_type:=block_type;
  559. block_type:=bt_except;
  560. inc(exceptblockcounter);
  561. aktexceptblock := exceptblockcounter;
  562. ot:=generrortype;
  563. p_specific:=nil;
  564. if (idtoken=_ON) then
  565. { catch specific exceptions }
  566. begin
  567. repeat
  568. consume(_ID);
  569. if token=_ID then
  570. begin
  571. objname:=pattern;
  572. objrealname:=orgpattern;
  573. { can't use consume_sym here, because we need already
  574. to check for the colon }
  575. searchsym(objname,srsym,srsymtable);
  576. consume(_ID);
  577. { is a explicit name for the exception given ? }
  578. if try_to_consume(_COLON) then
  579. begin
  580. consume_sym(srsym,srsymtable);
  581. if (srsym.typ=typesym) and
  582. is_class(ttypesym(srsym).restype.def) then
  583. begin
  584. ot:=ttypesym(srsym).restype;
  585. sym:=tvarsym.create(objrealname,vs_value,ot);
  586. end
  587. else
  588. begin
  589. sym:=tvarsym.create(objrealname,vs_value,generrortype);
  590. if (srsym.typ=typesym) then
  591. Message1(type_e_class_type_expected,ttypesym(srsym).restype.def.typename)
  592. else
  593. Message1(type_e_class_type_expected,ot.def.typename);
  594. end;
  595. exceptsymtable:=tstt_exceptsymtable.create;
  596. exceptsymtable.insert(sym);
  597. { insert the exception symtable stack }
  598. exceptsymtable.next:=symtablestack;
  599. symtablestack:=exceptsymtable;
  600. end
  601. else
  602. begin
  603. { check if type is valid, must be done here because
  604. with "e: Exception" the e is not necessary }
  605. if srsym=nil then
  606. begin
  607. identifier_not_found(objrealname);
  608. srsym:=generrorsym;
  609. end;
  610. { support unit.identifier }
  611. if srsym.typ=unitsym then
  612. begin
  613. consume(_POINT);
  614. srsym:=searchsymonlyin(tunitsym(srsym).unitsymtable,pattern);
  615. if srsym=nil then
  616. begin
  617. identifier_not_found(orgpattern);
  618. srsym:=generrorsym;
  619. end;
  620. consume(_ID);
  621. end;
  622. { check if type is valid, must be done here because
  623. with "e: Exception" the e is not necessary }
  624. if (srsym.typ=typesym) and
  625. is_class(ttypesym(srsym).restype.def) then
  626. ot:=ttypesym(srsym).restype
  627. else
  628. begin
  629. ot:=generrortype;
  630. if (srsym.typ=typesym) then
  631. Message1(type_e_class_type_expected,ttypesym(srsym).restype.def.typename)
  632. else
  633. Message1(type_e_class_type_expected,ot.def.typename);
  634. end;
  635. exceptsymtable:=nil;
  636. end;
  637. end
  638. else
  639. consume(_ID);
  640. consume(_DO);
  641. hp:=connode.create(nil,statement);
  642. if ot.def.deftype=errordef then
  643. begin
  644. hp.free;
  645. hp:=cerrornode.create;
  646. end;
  647. if p_specific=nil then
  648. begin
  649. last:=hp;
  650. p_specific:=last;
  651. end
  652. else
  653. begin
  654. tonnode(last).left:=hp;
  655. last:=tonnode(last).left;
  656. end;
  657. { set the informations }
  658. { only if the creation of the onnode was succesful, it's possible }
  659. { that last and hp are errornodes (JM) }
  660. if last.nodetype = onn then
  661. begin
  662. tonnode(last).excepttype:=tobjectdef(ot.def);
  663. tonnode(last).exceptsymtable:=exceptsymtable;
  664. end;
  665. { remove exception symtable }
  666. if assigned(exceptsymtable) then
  667. begin
  668. symtablestack:=symtablestack.next;
  669. if last.nodetype <> onn then
  670. exceptsymtable.free;
  671. end;
  672. if not try_to_consume(_SEMICOLON) then
  673. break;
  674. consume_emptystats;
  675. until (token in [_END,_ELSE]);
  676. if try_to_consume(_ELSE) then
  677. begin
  678. { catch the other exceptions }
  679. p_default:=statements_til_end;
  680. end
  681. else
  682. consume(_END);
  683. end
  684. else
  685. begin
  686. { catch all exceptions }
  687. p_default:=statements_til_end;
  688. end;
  689. block_type:=old_block_type;
  690. try_statement:=ctryexceptnode.create(p_try_block,p_specific,p_default);
  691. end;
  692. aktexceptblock := oldaktexceptblock;
  693. end;
  694. function _asm_statement : tnode;
  695. var
  696. asmstat : tasmnode;
  697. Marker : tai;
  698. reg : tregister;
  699. asmreader : tbaseasmreader;
  700. begin
  701. Inside_asm_statement:=true;
  702. if assigned(asmmodeinfos[aktasmmode]) then
  703. begin
  704. asmreader:=asmmodeinfos[aktasmmode]^.casmreader.create;
  705. asmstat:=casmnode.create(asmreader.assemble as taasmoutput);
  706. asmreader.free;
  707. end
  708. else
  709. Message(parser_f_assembler_reader_not_supported);
  710. { Read first the _ASM statement }
  711. consume(_ASM);
  712. { END is read, got a list of changed registers? }
  713. if try_to_consume(_LECKKLAMMER) then
  714. begin
  715. asmstat.used_regs_fpu:=[0..first_fpu_imreg-1];
  716. if token<>_RECKKLAMMER then
  717. begin
  718. repeat
  719. { it's possible to specify the modified registers }
  720. reg:=std_regnum_search(lower(pattern));
  721. if reg<>NR_NO then
  722. begin
  723. if getregtype(reg)=R_INTREGISTER then
  724. include(asmstat.used_regs_int,getsupreg(reg));
  725. end
  726. else
  727. Message(asmr_e_invalid_register);
  728. consume(_CSTRING);
  729. if not try_to_consume(_COMMA) then
  730. break;
  731. until false;
  732. end;
  733. consume(_RECKKLAMMER);
  734. end
  735. else
  736. begin
  737. asmstat.used_regs_int:=paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
  738. asmstat.used_regs_fpu:=paramanager.get_volatile_registers_fpu(current_procinfo.procdef.proccalloption);
  739. end;
  740. { mark the start and the end of the assembler block
  741. this is needed for the optimizer }
  742. If Assigned(AsmStat.p_asm) Then
  743. Begin
  744. Marker := Tai_Marker.Create(AsmBlockStart);
  745. AsmStat.p_asm.Insert(Marker);
  746. Marker := Tai_Marker.Create(AsmBlockEnd);
  747. AsmStat.p_asm.Concat(Marker);
  748. End;
  749. Inside_asm_statement:=false;
  750. _asm_statement:=asmstat;
  751. end;
  752. function statement : tnode;
  753. var
  754. p : tnode;
  755. code : tnode;
  756. filepos : tfileposinfo;
  757. srsym : tsym;
  758. srsymtable : tsymtable;
  759. s : stringid;
  760. begin
  761. filepos:=akttokenpos;
  762. case token of
  763. _GOTO :
  764. begin
  765. if not(cs_support_goto in aktmoduleswitches)then
  766. Message(sym_e_goto_and_label_not_supported);
  767. consume(_GOTO);
  768. if (token<>_INTCONST) and (token<>_ID) then
  769. begin
  770. Message(sym_e_label_not_found);
  771. code:=cerrornode.create;
  772. end
  773. else
  774. begin
  775. if token=_ID then
  776. consume_sym(srsym,srsymtable)
  777. else
  778. begin
  779. searchsym(pattern,srsym,srsymtable);
  780. if srsym=nil then
  781. begin
  782. identifier_not_found(pattern);
  783. srsym:=generrorsym;
  784. srsymtable:=nil;
  785. end;
  786. consume(token);
  787. end;
  788. if srsym.typ<>labelsym then
  789. begin
  790. Message(sym_e_id_is_no_label_id);
  791. code:=cerrornode.create;
  792. end
  793. else
  794. begin
  795. { goto is only allowed to labels within the current scope }
  796. if srsym.owner<>current_procinfo.procdef.localst then
  797. CGMessage(parser_e_goto_outside_proc);
  798. code:=cgotonode.create(tlabelsym(srsym));
  799. tgotonode(code).labsym:=tlabelsym(srsym);
  800. { set flag that this label is used }
  801. tlabelsym(srsym).used:=true;
  802. end;
  803. end;
  804. end;
  805. _BEGIN :
  806. code:=statement_block(_BEGIN);
  807. _IF :
  808. code:=if_statement;
  809. _CASE :
  810. code:=case_statement;
  811. _REPEAT :
  812. code:=repeat_statement;
  813. _WHILE :
  814. code:=while_statement;
  815. _FOR :
  816. code:=for_statement;
  817. _WITH :
  818. code:=with_statement;
  819. _TRY :
  820. code:=try_statement;
  821. _RAISE :
  822. code:=raise_statement;
  823. { semicolons,else until and end are ignored }
  824. _SEMICOLON,
  825. _ELSE,
  826. _UNTIL,
  827. _END:
  828. code:=cnothingnode.create;
  829. _FAIL :
  830. begin
  831. if (current_procinfo.procdef.proctypeoption<>potype_constructor) then
  832. Message(parser_e_fail_only_in_constructor);
  833. consume(_FAIL);
  834. code:=call_fail_node;
  835. end;
  836. _ASM :
  837. code:=_asm_statement;
  838. _EOF :
  839. Message(scan_f_end_of_file);
  840. else
  841. begin
  842. p:=expr;
  843. { When a colon follows a intconst then transform it into a label }
  844. if (p.nodetype=ordconstn) and
  845. try_to_consume(_COLON) then
  846. begin
  847. s:=tostr(tordconstnode(p).value);
  848. p.free;
  849. searchsym(s,srsym,srsymtable);
  850. if assigned(srsym) and
  851. (srsym.typ=labelsym) then
  852. begin
  853. if tlabelsym(srsym).defined then
  854. Message(sym_e_label_already_defined);
  855. tlabelsym(srsym).defined:=true;
  856. p:=clabelnode.create(tlabelsym(srsym),nil);
  857. end
  858. else
  859. begin
  860. Message1(sym_e_label_used_and_not_defined,s);
  861. p:=cnothingnode.create;
  862. end;
  863. end;
  864. if p.nodetype=labeln then
  865. begin
  866. { the pointer to the following instruction }
  867. { isn't a very clean way }
  868. if token in endtokens then
  869. tlabelnode(p).left:=cnothingnode.create
  870. else
  871. tlabelnode(p).left:=statement{$ifdef FPCPROCVAR}(){$endif};
  872. { be sure to have left also resulttypepass }
  873. resulttypepass(tlabelnode(p).left);
  874. end
  875. else
  876. { change a load of a procvar to a call. this is also
  877. supported in fpc mode }
  878. if p.nodetype in [vecn,derefn,typeconvn,subscriptn,loadn] then
  879. maybe_call_procvar(p,false);
  880. { blockn support because a read/write is changed into a blocknode }
  881. { with a separate statement for each read/write operation (JM) }
  882. { the same is true for val() if the third parameter is not 32 bit }
  883. if not(p.nodetype in [nothingn,calln,ifn,assignn,breakn,inlinen,
  884. continuen,labeln,blockn,exitn]) then
  885. Message(cg_e_illegal_expression);
  886. { Specify that we don't use the value returned by the call.
  887. This is used for :
  888. - dispose of temp stack space
  889. - dispose on FPU stack }
  890. if (p.nodetype=calln) then
  891. exclude(tcallnode(p).callnodeflags,cnf_return_value_used);
  892. code:=p;
  893. end;
  894. end;
  895. if assigned(code) then
  896. code.set_tree_filepos(filepos);
  897. statement:=code;
  898. end;
  899. function statement_block(starttoken : ttoken) : tnode;
  900. var
  901. first,last : tnode;
  902. filepos : tfileposinfo;
  903. begin
  904. first:=nil;
  905. filepos:=akttokenpos;
  906. consume(starttoken);
  907. while not(token in [_END,_FINALIZATION]) do
  908. begin
  909. if first=nil then
  910. begin
  911. last:=cstatementnode.create(statement,nil);
  912. first:=last;
  913. end
  914. else
  915. begin
  916. tstatementnode(last).right:=cstatementnode.create(statement,nil);
  917. last:=tstatementnode(last).right;
  918. end;
  919. if (token in [_END,_FINALIZATION]) then
  920. break
  921. else
  922. begin
  923. { if no semicolon, then error and go on }
  924. if token<>_SEMICOLON then
  925. begin
  926. consume(_SEMICOLON);
  927. consume_all_until(_SEMICOLON);
  928. end;
  929. consume(_SEMICOLON);
  930. end;
  931. consume_emptystats;
  932. end;
  933. { don't consume the finalization token, it is consumed when
  934. reading the finalization block, but allow it only after
  935. an initalization ! }
  936. if (starttoken<>_INITIALIZATION) or (token<>_FINALIZATION) then
  937. consume(_END);
  938. last:=cblocknode.create(first);
  939. last.set_tree_filepos(filepos);
  940. statement_block:=last;
  941. end;
  942. function assembler_block : tnode;
  943. var
  944. p : tnode;
  945. locals : longint;
  946. begin
  947. { Rename the funcret so that recursive calls are possible }
  948. if not is_void(current_procinfo.procdef.rettype.def) then
  949. symtablestack.rename(current_procinfo.procdef.resultname,'$hiddenresult');
  950. { delphi uses register calling for assembler methods }
  951. if (m_delphi in aktmodeswitches) and
  952. (po_assembler in current_procinfo.procdef.procoptions) and
  953. not(po_hascallingconvention in current_procinfo.procdef.procoptions) then
  954. current_procinfo.procdef.proccalloption:=pocall_register;
  955. { force the asm statement }
  956. if token<>_ASM then
  957. consume(_ASM);
  958. include(current_procinfo.flags,pi_is_assembler);
  959. p:=_asm_statement;
  960. {$ifndef sparc}
  961. {$ifndef arm}
  962. if (po_assembler in current_procinfo.procdef.procoptions) then
  963. begin
  964. { set the framepointer to esp for assembler functions when the
  965. following conditions are met:
  966. - if the are no local variables and parameters (except the allocated result)
  967. - no reference to the result variable (refcount<=1)
  968. - result is not stored as parameter
  969. - target processor has optional frame pointer save
  970. (vm, i386, vm only currently)
  971. }
  972. locals:=0;
  973. current_procinfo.procdef.localst.foreach_static({$ifdef FPCPROCVAR}@{$endif}count_locals,@locals);
  974. current_procinfo.procdef.parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}count_locals,@locals);
  975. if (locals=0) and
  976. (current_procinfo.procdef.owner.symtabletype<>objectsymtable) and
  977. (not assigned(current_procinfo.procdef.funcretsym) or
  978. (tvarsym(current_procinfo.procdef.funcretsym).refcount<=1)) and
  979. not(paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
  980. begin
  981. { Only need to set the framepointer, the locals will
  982. be inserted with the correct reference in tcgasmnode.pass_2 }
  983. current_procinfo.framepointer:=NR_STACK_POINTER_REG;
  984. end;
  985. end;
  986. {$endif arm}
  987. {$endif sparc}
  988. { Flag the result as assigned when it is returned in a
  989. register.
  990. }
  991. if assigned(current_procinfo.procdef.funcretsym) and
  992. (not paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
  993. tvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_assigned;
  994. { because the END is already read we need to get the
  995. last_endtoken_filepos here (PFV) }
  996. last_endtoken_filepos:=akttokenpos;
  997. assembler_block:=p;
  998. end;
  999. end.
  1000. {
  1001. $Log$
  1002. Revision 1.134 2004-05-23 18:28:41 peter
  1003. * methodpointer is loaded into a temp when it was a calln
  1004. Revision 1.133 2004/05/23 11:39:38 peter
  1005. * give error when goto jumps to label outside current proc scope
  1006. Revision 1.132 2004/03/04 17:22:10 peter
  1007. * better check for maybe_call_procvar
  1008. Revision 1.131 2004/02/26 16:14:48 peter
  1009. * withsymtables need to have the original tobject owner instead of
  1010. the parent objectdef. Needed to check for visibility
  1011. Revision 1.130 2004/02/20 21:55:59 peter
  1012. * procvar cleanup
  1013. Revision 1.129 2004/02/03 22:32:54 peter
  1014. * renamed xNNbittype to xNNinttype
  1015. * renamed registers32 to registersint
  1016. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  1017. Revision 1.128 2004/02/03 19:47:45 jonas
  1018. * don't put the temp of a withnode in a register if debugging info is on,
  1019. because then our stabs generation internalerror's
  1020. Revision 1.127 2004/02/03 16:46:51 jonas
  1021. + support to store ttempcreate/ref/deletenodes in registers
  1022. * put temps for withnodes and some newnodes in registers
  1023. Note: this currently only works because calling ungetregister()
  1024. multiple times for the same register doesn't matter. We need again
  1025. a way to specify that a register is currently a regvar and as such
  1026. should not be freed when you call ungetregister() on it.
  1027. Revision 1.126 2004/01/22 17:24:49 peter
  1028. * except is also an end of block token
  1029. * after a label don't try to parse a statement when the next token
  1030. is an end token
  1031. Revision 1.125 2004/01/12 16:36:53 peter
  1032. * removed asmmode_direct
  1033. Revision 1.124 2003/12/07 16:40:45 jonas
  1034. * moved count_locals from pstatmnt to symutils
  1035. * use count_locals in powerpc/cpupi to check whether we should set the
  1036. first temp offset (and as such generate a stackframe)
  1037. Revision 1.123 2003/12/03 17:39:04 florian
  1038. * fixed several arm calling conventions issues
  1039. * fixed reference reading in the assembler reader
  1040. * fixed a_loadaddr_ref_reg
  1041. Revision 1.122 2003/11/12 16:05:39 florian
  1042. * assembler readers OOPed
  1043. + typed currency constants
  1044. + typed 128 bit float constants if the CPU supports it
  1045. Revision 1.121 2003/11/11 21:10:12 peter
  1046. * remove temporary stdcall hack
  1047. Revision 1.120 2003/11/10 22:02:52 peter
  1048. * cross unit inlining fixed
  1049. Revision 1.119 2003/10/29 20:34:20 peter
  1050. * move check for unused object constructor result to blocknode
  1051. Revision 1.117 2003/10/29 15:40:20 peter
  1052. * support indexing and offset retrieval for locals
  1053. Revision 1.116 2003/10/17 14:38:32 peter
  1054. * 64k registers supported
  1055. * fixed some memory leaks
  1056. Revision 1.115 2003/10/10 17:48:13 peter
  1057. * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
  1058. * tregisteralloctor renamed to trgobj
  1059. * removed rgobj from a lot of units
  1060. * moved location_* and reference_* to cgobj
  1061. * first things for mmx register allocation
  1062. Revision 1.114 2003/10/08 19:19:45 peter
  1063. * set_varstate cleanup
  1064. Revision 1.113 2003/10/07 20:06:37 peter
  1065. * set calling convention before assembler block is parsed
  1066. Revision 1.112 2003/10/02 21:15:59 peter
  1067. * delphi mode uses register calling by default for assembler
  1068. Revision 1.111 2003/10/01 20:34:49 peter
  1069. * procinfo unit contains tprocinfo
  1070. * cginfo renamed to cgbase
  1071. * moved cgmessage to verbose
  1072. * fixed ppc and sparc compiles
  1073. Revision 1.110 2003/09/23 17:56:05 peter
  1074. * locals and paras are allocated in the code generation
  1075. * tvarsym.localloc contains the location of para/local when
  1076. generating code for the current procedure
  1077. Revision 1.109 2003/09/16 16:17:01 peter
  1078. * varspez in calls to push_addr_param
  1079. Revision 1.108 2003/09/07 22:09:35 peter
  1080. * preparations for different default calling conventions
  1081. * various RA fixes
  1082. Revision 1.107 2003/09/03 15:55:01 peter
  1083. * NEWRA branch merged
  1084. Revision 1.106.2.3 2003/08/31 15:46:26 peter
  1085. * more updates for tregister
  1086. Revision 1.106.2.2 2003/08/29 17:28:59 peter
  1087. * next batch of updates
  1088. Revision 1.106.2.1 2003/08/28 18:35:08 peter
  1089. * tregister changed to cardinal
  1090. Revision 1.106 2003/07/08 21:24:59 peter
  1091. * sparc fixes
  1092. Revision 1.105 2003/06/17 16:34:44 jonas
  1093. * lots of newra fixes (need getfuncretparaloc implementation for i386)!
  1094. * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
  1095. processor dependent
  1096. Revision 1.104 2003/06/13 21:19:31 peter
  1097. * current_procdef removed, use current_procinfo.procdef instead
  1098. Revision 1.103 2003/06/09 18:27:14 peter
  1099. * load calln in temprefn in with statement
  1100. Revision 1.102 2003/05/23 22:33:48 florian
  1101. * fix some small flaws which prevent sparc linux system unit from compiling
  1102. * some reformatting done
  1103. Revision 1.101 2003/05/23 15:15:36 peter
  1104. * better error for undefined ordinal labels
  1105. Revision 1.100 2003/05/17 13:30:08 jonas
  1106. * changed tt_persistant to tt_persistent :)
  1107. * tempcreatenode now doesn't accept a boolean anymore for persistent
  1108. temps, but a ttemptype, so you can also create ansistring temps etc
  1109. Revision 1.99 2003/05/15 18:58:53 peter
  1110. * removed selfpointer_offset, vmtpointer_offset
  1111. * tvarsym.adjusted_address
  1112. * address in localsymtable is now in the real direction
  1113. * removed some obsolete globals
  1114. Revision 1.98 2003/05/13 19:14:41 peter
  1115. * failn removed
  1116. * inherited result code check moven to pexpr
  1117. Revision 1.97 2003/05/11 14:45:12 peter
  1118. * tloadnode does not support objectsymtable,withsymtable anymore
  1119. * withnode cleanup
  1120. * direct with rewritten to use temprefnode
  1121. Revision 1.96 2003/05/09 17:47:03 peter
  1122. * self moved to hidden parameter
  1123. * removed hdisposen,hnewn,selfn
  1124. Revision 1.95 2003/04/30 22:15:59 florian
  1125. * some 64 bit adaptions in ncgadd
  1126. * x86-64 now uses ncgadd
  1127. * tparamanager.ret_in_acc doesn't return true anymore for a void-def
  1128. Revision 1.94 2003/04/27 11:21:34 peter
  1129. * aktprocdef renamed to current_procinfo.procdef
  1130. * procinfo renamed to current_procinfo
  1131. * procinfo will now be stored in current_module so it can be
  1132. cleaned up properly
  1133. * gen_main_procsym changed to create_main_proc and release_main_proc
  1134. to also generate a tprocinfo structure
  1135. * fixed unit implicit initfinal
  1136. Revision 1.93 2003/04/27 07:29:50 peter
  1137. * current_procinfo.procdef cleanup, current_procinfo.procdef is now always nil when parsing
  1138. a new procdef declaration
  1139. * aktprocsym removed
  1140. * lexlevel removed, use symtable.symtablelevel instead
  1141. * implicit init/final code uses the normal genentry/genexit
  1142. * funcret state checking updated for new funcret handling
  1143. Revision 1.92 2003/04/26 11:30:59 florian
  1144. * fixed the powerpc to work with the new function result handling
  1145. Revision 1.91 2003/04/25 20:59:34 peter
  1146. * removed funcretn,funcretsym, function result is now in varsym
  1147. and aliases for result and function name are added using absolutesym
  1148. * vs_hidden parameter for funcret passed in parameter
  1149. * vs_hidden fixes
  1150. * writenode changed to printnode and released from extdebug
  1151. * -vp option added to generate a tree.log with the nodetree
  1152. * nicer printnode for statements, callnode
  1153. Revision 1.90 2002/04/25 20:15:40 florian
  1154. * block nodes within expressions shouldn't release the used registers,
  1155. fixed using a flag till the new rg is ready
  1156. Revision 1.89 2003/04/25 08:25:26 daniel
  1157. * Ifdefs around a lot of calls to cleartempgen
  1158. * Fixed registers that are allocated but not freed in several nodes
  1159. * Tweak to register allocator to cause less spills
  1160. * 8-bit registers now interfere with esi,edi and ebp
  1161. Compiler can now compile rtl successfully when using new register
  1162. allocator
  1163. Revision 1.88 2003/03/28 19:16:57 peter
  1164. * generic constructor working for i386
  1165. * remove fixed self register
  1166. * esi added as address register for i386
  1167. Revision 1.87 2003/03/17 18:55:30 peter
  1168. * allow more tokens instead of only semicolon after inherited
  1169. Revision 1.86 2003/02/19 22:00:14 daniel
  1170. * Code generator converted to new register notation
  1171. - Horribily outdated todo.txt removed
  1172. Revision 1.85 2003/01/08 18:43:56 daniel
  1173. * Tregister changed into a record
  1174. Revision 1.84 2003/01/01 21:05:24 peter
  1175. * fixed assembler methods stackpointer optimization that was
  1176. broken after the previous change
  1177. Revision 1.83 2002/12/29 18:59:34 peter
  1178. * fixed parsing of declarations before asm statement
  1179. Revision 1.82 2002/12/27 18:18:56 peter
  1180. * check for else after empty raise statement
  1181. Revision 1.81 2002/11/27 02:37:14 peter
  1182. * case statement inlining added
  1183. * fixed inlining of write()
  1184. * switched statementnode left and right parts so the statements are
  1185. processed in the correct order when getcopy is used. This is
  1186. required for tempnodes
  1187. Revision 1.80 2002/11/25 17:43:22 peter
  1188. * splitted defbase in defutil,symutil,defcmp
  1189. * merged isconvertable and is_equal into compare_defs(_ext)
  1190. * made operator search faster by walking the list only once
  1191. Revision 1.79 2002/11/18 17:31:58 peter
  1192. * pass proccalloption to ret_in_xxx and push_xxx functions
  1193. Revision 1.78 2002/09/07 19:34:08 florian
  1194. + tcg.direction is used now
  1195. Revision 1.77 2002/09/07 15:25:07 peter
  1196. * old logs removed and tabs fixed
  1197. Revision 1.76 2002/09/07 12:16:03 carl
  1198. * second part bug report 1996 fix, testrange in cordconstnode
  1199. only called if option is set (also make parsing a tiny faster)
  1200. Revision 1.75 2002/09/02 18:40:52 peter
  1201. * fixed parsing of register names with lowercase
  1202. Revision 1.74 2002/09/01 14:43:12 peter
  1203. * fixed direct assembler for i386
  1204. Revision 1.73 2002/08/25 19:25:20 peter
  1205. * sym.insert_in_data removed
  1206. * symtable.insertvardata/insertconstdata added
  1207. * removed insert_in_data call from symtable.insert, it needs to be
  1208. called separatly. This allows to deref the address calculation
  1209. * procedures now calculate the parast addresses after the procedure
  1210. directives are parsed. This fixes the cdecl parast problem
  1211. * push_addr_param has an extra argument that specifies if cdecl is used
  1212. or not
  1213. Revision 1.72 2002/08/17 09:23:40 florian
  1214. * first part of procinfo rewrite
  1215. Revision 1.71 2002/08/16 14:24:58 carl
  1216. * issameref() to test if two references are the same (then emit no opcodes)
  1217. + ret_in_reg to replace ret_in_acc
  1218. (fix some register allocation bugs at the same time)
  1219. + save_std_register now has an extra parameter which is the
  1220. usedinproc registers
  1221. Revision 1.70 2002/08/11 14:32:27 peter
  1222. * renamed current_library to objectlibrary
  1223. Revision 1.69 2002/08/11 13:24:12 peter
  1224. * saving of asmsymbols in ppu supported
  1225. * asmsymbollist global is removed and moved into a new class
  1226. tasmlibrarydata that will hold the info of a .a file which
  1227. corresponds with a single module. Added librarydata to tmodule
  1228. to keep the library info stored for the module. In the future the
  1229. objectfiles will also be stored to the tasmlibrarydata class
  1230. * all getlabel/newasmsymbol and friends are moved to the new class
  1231. Revision 1.68 2002/08/10 14:46:30 carl
  1232. + moved target_cpu_string to cpuinfo
  1233. * renamed asmmode enum.
  1234. * assembler reader has now less ifdef's
  1235. * move from nppcmem.pas -> ncgmem.pas vec. node.
  1236. Revision 1.67 2002/08/09 19:11:44 carl
  1237. + reading of used registers in assembler routines is now
  1238. cpu-independent
  1239. Revision 1.66 2002/08/06 20:55:22 florian
  1240. * first part of ppc calling conventions fix
  1241. Revision 1.65 2002/07/28 20:45:22 florian
  1242. + added direct assembler reader for PowerPC
  1243. Revision 1.64 2002/07/20 11:57:56 florian
  1244. * types.pas renamed to defbase.pas because D6 contains a types
  1245. unit so this would conflicts if D6 programms are compiled
  1246. + Willamette/SSE2 instructions to assembler added
  1247. Revision 1.63 2002/07/19 11:41:36 daniel
  1248. * State tracker work
  1249. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1250. allows the state tracker to change while nodes automatically into
  1251. repeat nodes.
  1252. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1253. 'not(a>b)' is optimized into 'a<=b'.
  1254. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1255. by removing the notn and later switchting the true and falselabels. The
  1256. same is done with 'repeat until not a'.
  1257. Revision 1.62 2002/07/16 15:34:20 florian
  1258. * exit is now a syssym instead of a keyword
  1259. Revision 1.61 2002/07/11 14:41:28 florian
  1260. * start of the new generic parameter handling
  1261. Revision 1.60 2002/07/04 20:43:01 florian
  1262. * first x86-64 patches
  1263. Revision 1.59 2002/07/01 18:46:25 peter
  1264. * internal linker
  1265. * reorganized aasm layer
  1266. Revision 1.58 2002/05/18 13:34:13 peter
  1267. * readded missing revisions
  1268. Revision 1.57 2002/05/16 19:46:44 carl
  1269. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1270. + try to fix temp allocation (still in ifdef)
  1271. + generic constructor calls
  1272. + start of tassembler / tmodulebase class cleanup
  1273. }