pstatmnt.pas 50 KB

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