psub.pas 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Daniel Mantione
  4. Does the parsing and codegeneration at subroutine level
  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 psub;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. cobjects;
  23. procedure compile_proc_body(const proc_names:Tstringcontainer;
  24. make_global,parent_has_class:boolean);
  25. { reads the declaration blocks }
  26. procedure read_declarations(islibrary : boolean);
  27. { reads declarations in the interface part of a unit }
  28. procedure read_interface_declarations;
  29. implementation
  30. uses
  31. { common }
  32. cutils,
  33. { global }
  34. globtype,globals,tokens,verbose,
  35. systems,
  36. { aasm }
  37. cpubase,aasm,
  38. { symtable }
  39. symconst,symbase,symtype,symdef,symsym,symtable,types,
  40. ppu,fmodule,
  41. { pass 1 }
  42. node,
  43. nbas,
  44. { pass 2 }
  45. {$ifndef NOPASS2}
  46. pass_2,
  47. {$endif}
  48. { parser }
  49. scanner,
  50. pbase,pstatmnt,pdecl,pdecsub,pexports,
  51. { codegen }
  52. tgcpu,hcodegen
  53. {$ifdef newcg}
  54. ,cgbase
  55. ,cgobj
  56. {$ifndef NOOPT}
  57. ,aopt
  58. {$endif}
  59. {$else}
  60. ,temp_gen
  61. {$ifdef i386}
  62. ,cgai386
  63. {$ifndef NOOPT}
  64. ,aopt386
  65. {$endif}
  66. {$endif}
  67. {$endif}
  68. ;
  69. {****************************************************************************
  70. PROCEDURE/FUNCTION BODY PARSING
  71. ****************************************************************************}
  72. function block(islibrary : boolean) : tnode;
  73. var
  74. funcretsym : pfuncretsym;
  75. storepos : tfileposinfo;
  76. begin
  77. { do we have an assembler block without the po_assembler?
  78. we should allow this for Delphi compatibility (PFV) }
  79. if (token=_ASM) and (m_delphi in aktmodeswitches) then
  80. include(aktprocsym^.definition^.procoptions,po_assembler);
  81. { Handle assembler block different }
  82. if (po_assembler in aktprocsym^.definition^.procoptions) then
  83. begin
  84. read_declarations(false);
  85. block:=assembler_block;
  86. exit;
  87. end;
  88. if procinfo^.returntype.def<>pdef(voiddef) then
  89. begin
  90. { if the current is a function aktprocsym is non nil }
  91. { and there is a local symtable set }
  92. storepos:=akttokenpos;
  93. akttokenpos:=aktprocsym^.fileinfo;
  94. funcretsym:=new(pfuncretsym,init(aktprocsym^.name,procinfo));
  95. { insert in local symtable }
  96. symtablestack^.insert(funcretsym);
  97. akttokenpos:=storepos;
  98. if ret_in_acc(procinfo^.returntype.def) or (procinfo^.returntype.def^.deftype=floatdef) then
  99. procinfo^.return_offset:=-funcretsym^.address;
  100. procinfo^.funcretsym:=funcretsym;
  101. { insert result also if support is on }
  102. if (m_result in aktmodeswitches) then
  103. begin
  104. procinfo^.resultfuncretsym:=new(pfuncretsym,init('RESULT',procinfo));
  105. symtablestack^.insert(procinfo^.resultfuncretsym);
  106. end;
  107. end;
  108. read_declarations(islibrary);
  109. { temporary space is set, while the BEGIN of the procedure }
  110. if (symtablestack^.symtabletype=localsymtable) then
  111. procinfo^.firsttemp_offset := -symtablestack^.datasize
  112. else
  113. procinfo^.firsttemp_offset := 0;
  114. { space for the return value }
  115. { !!!!! this means that we can not set the return value
  116. in a subfunction !!!!! }
  117. { because we don't know yet where the address is }
  118. if procinfo^.returntype.def<>pdef(voiddef) then
  119. begin
  120. if ret_in_acc(procinfo^.returntype.def) or (procinfo^.returntype.def^.deftype=floatdef) then
  121. { if (procinfo^.retdef^.deftype=orddef) or
  122. (procinfo^.retdef^.deftype=pointerdef) or
  123. (procinfo^.retdef^.deftype=enumdef) or
  124. (procinfo^.retdef^.deftype=procvardef) or
  125. (procinfo^.retdef^.deftype=floatdef) or
  126. (
  127. (procinfo^.retdef^.deftype=setdef) and
  128. (psetdef(procinfo^.retdef)^.settype=smallset)
  129. ) then }
  130. begin
  131. { the space has been set in the local symtable }
  132. procinfo^.return_offset:=-funcretsym^.address;
  133. if ((procinfo^.flags and pi_operator)<>0) and
  134. assigned(opsym) then
  135. {opsym^.address:=procinfo^.para_offset; is wrong PM }
  136. opsym^.address:=-procinfo^.return_offset;
  137. { eax is modified by a function }
  138. {$ifndef newcg}
  139. {$ifdef i386}
  140. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  141. if is_64bitint(procinfo^.returntype.def) then
  142. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  143. {$endif}
  144. {$ifdef m68k}
  145. usedinproc:=usedinproc or ($800 shr word(R_D0));
  146. if is_64bitint(procinfo^.retdef) then
  147. usedinproc:=usedinproc or ($800 shr byte(R_D1))
  148. {$endif}
  149. {$endif newcg}
  150. end;
  151. end;
  152. {Unit initialization?.}
  153. if (lexlevel=unit_init_level) and (current_module^.is_unit)
  154. or islibrary then
  155. begin
  156. if (token=_END) then
  157. begin
  158. consume(_END);
  159. { We need at least a node, else the entry/exit code is not
  160. generated and thus no PASCALMAIN symbol which we need (PFV) }
  161. if islibrary then
  162. block:=cnothingnode.create
  163. else
  164. block:=nil;
  165. end
  166. else
  167. begin
  168. if token=_INITIALIZATION then
  169. begin
  170. current_module^.flags:=current_module^.flags or uf_init;
  171. block:=statement_block(_INITIALIZATION);
  172. end
  173. else if (token=_FINALIZATION) then
  174. begin
  175. if (current_module^.flags and uf_finalize)<>0 then
  176. block:=statement_block(_FINALIZATION)
  177. else
  178. begin
  179. { can we allow no INITIALIZATION for DLL ??
  180. I think it should work PM }
  181. block:=nil;
  182. exit;
  183. end;
  184. end
  185. else
  186. begin
  187. current_module^.flags:=current_module^.flags or uf_init;
  188. block:=statement_block(_BEGIN);
  189. end;
  190. end;
  191. end
  192. else
  193. block:=statement_block(_BEGIN);
  194. end;
  195. {****************************************************************************
  196. PROCEDURE/FUNCTION COMPILING
  197. ****************************************************************************}
  198. procedure compile_proc_body(const proc_names:Tstringcontainer;
  199. make_global,parent_has_class:boolean);
  200. {
  201. Compile the body of a procedure
  202. }
  203. var
  204. oldexitlabel,oldexit2label : pasmlabel;
  205. oldfaillabel,oldquickexitlabel:Pasmlabel;
  206. _class,hp:Pobjectdef;
  207. { switches can change inside the procedure }
  208. entryswitches, exitswitches : tlocalswitches;
  209. oldaktmaxfpuregisters,localmaxfpuregisters : longint;
  210. { code for the subroutine as tree }
  211. code:tnode;
  212. { size of the local strackframe }
  213. stackframe:longint;
  214. { true when no stackframe is required }
  215. nostackframe:boolean;
  216. { number of bytes which have to be cleared by RET }
  217. parasize:longint;
  218. { filepositions }
  219. entrypos,
  220. savepos,
  221. exitpos : tfileposinfo;
  222. begin
  223. { calculate the lexical level }
  224. inc(lexlevel);
  225. if lexlevel>32 then
  226. Message(parser_e_too_much_lexlevel);
  227. { static is also important for local procedures !! }
  228. if (po_staticmethod in aktprocsym^.definition^.procoptions) then
  229. allow_only_static:=true
  230. else if (lexlevel=normal_function_level) then
  231. allow_only_static:=false;
  232. { save old labels }
  233. oldexitlabel:=aktexitlabel;
  234. oldexit2label:=aktexit2label;
  235. oldquickexitlabel:=quickexitlabel;
  236. oldfaillabel:=faillabel;
  237. { get new labels }
  238. getlabel(aktexitlabel);
  239. getlabel(aktexit2label);
  240. { exit for fail in constructors }
  241. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  242. begin
  243. getlabel(faillabel);
  244. getlabel(quickexitlabel);
  245. end;
  246. { reset break and continue labels }
  247. block_type:=bt_general;
  248. aktbreaklabel:=nil;
  249. aktcontinuelabel:=nil;
  250. { insert symtables for the class, by only if it is no nested function }
  251. if assigned(procinfo^._class) and not(parent_has_class) then
  252. begin
  253. { insert them in the reverse order ! }
  254. hp:=nil;
  255. repeat
  256. _class:=procinfo^._class;
  257. while _class^.childof<>hp do
  258. _class:=_class^.childof;
  259. hp:=_class;
  260. _class^.symtable^.next:=symtablestack;
  261. symtablestack:=_class^.symtable;
  262. until hp=procinfo^._class;
  263. end;
  264. { insert parasymtable in symtablestack}
  265. { only if lexlevel > 1 !!! global symtable should be right after staticsymtazble
  266. for checking of same names used in interface and implementation !! }
  267. if lexlevel>=normal_function_level then
  268. begin
  269. aktprocsym^.definition^.parast^.next:=symtablestack;
  270. symtablestack:=aktprocsym^.definition^.parast;
  271. symtablestack^.symtablelevel:=lexlevel;
  272. end;
  273. { insert localsymtable in symtablestack}
  274. aktprocsym^.definition^.localst^.next:=symtablestack;
  275. symtablestack:=aktprocsym^.definition^.localst;
  276. symtablestack^.symtablelevel:=lexlevel;
  277. { constant symbols are inserted in this symboltable }
  278. constsymtable:=symtablestack;
  279. { reset the temporary memory }
  280. cleartempgen;
  281. {$ifdef newcg}
  282. tg.usedinproc:=[];
  283. {$else newcg}
  284. { no registers are used }
  285. usedinproc:=0;
  286. {$endif newcg}
  287. { save entry info }
  288. entrypos:=aktfilepos;
  289. entryswitches:=aktlocalswitches;
  290. localmaxfpuregisters:=aktmaxfpuregisters;
  291. { parse the code ... }
  292. code:=block(current_module^.islibrary);
  293. { get a better entry point }
  294. if assigned(code) then
  295. entrypos:=code.fileinfo;
  296. { save exit info }
  297. exitswitches:=aktlocalswitches;
  298. exitpos:=last_endtoken_filepos;
  299. { save current filepos }
  300. savepos:=aktfilepos;
  301. {When we are called to compile the body of a unit, aktprocsym should
  302. point to the unit initialization. If the unit has no initialization,
  303. aktprocsym=nil. But in that case code=nil. hus we should check for
  304. code=nil, when we use aktprocsym.}
  305. { set the framepointer to esp for assembler functions }
  306. { but only if the are no local variables }
  307. { already done in assembler_block }
  308. {$ifdef newcg}
  309. tg.setfirsttemp(procinfo^.firsttemp_offset);
  310. {$else newcg}
  311. setfirsttemp(procinfo^.firsttemp_offset);
  312. {$endif newcg}
  313. { ... and generate assembler }
  314. { but set the right switches for entry !! }
  315. aktlocalswitches:=entryswitches;
  316. oldaktmaxfpuregisters:=aktmaxfpuregisters;
  317. aktmaxfpuregisters:=localmaxfpuregisters;
  318. {$ifndef NOPASS2}
  319. if assigned(code) then
  320. generatecode(code);
  321. { set switches to status at end of procedure }
  322. aktlocalswitches:=exitswitches;
  323. if assigned(code) then
  324. begin
  325. aktprocsym^.definition^.code:=code;
  326. { the procedure is now defined }
  327. aktprocsym^.definition^.forwarddef:=false;
  328. end;
  329. {$ifdef newcg}
  330. stackframe:=tg.gettempsize;
  331. {$else newcg}
  332. stackframe:=gettempsize;
  333. {$endif newcg}
  334. { first generate entry code with the correct position and switches }
  335. aktfilepos:=entrypos;
  336. aktlocalswitches:=entryswitches;
  337. {$ifdef newcg}
  338. if assigned(code) then
  339. cg^.g_entrycode(procinfo^.aktentrycode,proc_names,make_global,stackframe,parasize,nostackframe,false);
  340. {$else newcg}
  341. if assigned(code) then
  342. genentrycode(procinfo^.aktentrycode,proc_names,make_global,stackframe,parasize,nostackframe,false);
  343. {$endif newcg}
  344. { FPC_POPADDRSTACK destroys all registers (JM) }
  345. if (procinfo^.flags and (pi_needs_implicit_finally or pi_uses_exceptions)) <> 0 then
  346. usedinproc := $ff;
  347. { now generate exit code with the correct position and switches }
  348. aktfilepos:=exitpos;
  349. aktlocalswitches:=exitswitches;
  350. if assigned(code) then
  351. begin
  352. {$ifdef newcg}
  353. cg^.g_exitcode(procinfo^.aktexitcode,parasize,nostackframe,false);
  354. {$else newcg}
  355. genexitcode(procinfo^.aktexitcode,parasize,nostackframe,false);
  356. {$endif newcg}
  357. { now all the registers used are known }
  358. {$ifdef newcg}
  359. aktprocsym^.definition^.usedregisters:=tg.usedinproc;
  360. {$else newcg}
  361. aktprocsym^.definition^.usedregisters:=usedinproc;
  362. {$endif newcg}
  363. procinfo^.aktproccode^.insertlist(procinfo^.aktentrycode);
  364. procinfo^.aktproccode^.concatlist(procinfo^.aktexitcode);
  365. {$ifdef i386}
  366. {$ifndef NoOpt}
  367. if (cs_optimize in aktglobalswitches) and
  368. { do not optimize pure assembler procedures }
  369. ((procinfo^.flags and pi_is_assembler)=0) then
  370. Optimize(procinfo^.aktproccode);
  371. {$endif NoOpt}
  372. {$endif i386}
  373. { save local data (casetable) also in the same file }
  374. if assigned(procinfo^.aktlocaldata) and
  375. (not procinfo^.aktlocaldata^.empty) then
  376. begin
  377. procinfo^.aktproccode^.concat(new(pai_section,init(sec_data)));
  378. procinfo^.aktproccode^.concatlist(procinfo^.aktlocaldata);
  379. procinfo^.aktproccode^.concat(new(pai_section,init(sec_code)));
  380. end;
  381. { now we can insert a cut }
  382. if (cs_create_smart in aktmoduleswitches) then
  383. codesegment^.concat(new(pai_cut,init));
  384. { add the procedure to the codesegment }
  385. codesegment^.concatlist(procinfo^.aktproccode);
  386. end;
  387. {$else NOPASS2}
  388. if assigned(code) then
  389. firstpass(code);
  390. {$endif NOPASS2}
  391. { ... remove symbol tables, for the browser leave the static table }
  392. { if (cs_browser in aktmoduleswitches) and (symtablestack^.symtabletype=staticsymtable) then
  393. symtablestack^.next:=symtablestack^.next^.next
  394. else }
  395. if lexlevel>=normal_function_level then
  396. symtablestack:=symtablestack^.next^.next
  397. else
  398. symtablestack:=symtablestack^.next;
  399. { ... check for unused symbols }
  400. { but only if there is no asm block }
  401. if assigned(code) then
  402. begin
  403. if (Errorcount=0) then
  404. begin
  405. pstoredsymtable(aktprocsym^.definition^.localst)^.check_forwards;
  406. pstoredsymtable(aktprocsym^.definition^.localst)^.checklabels;
  407. end;
  408. if (procinfo^.flags and pi_uses_asm)=0 then
  409. begin
  410. { not for unit init, becuase the var can be used in finalize,
  411. it will be done in proc_unit }
  412. if not(aktprocsym^.definition^.proctypeoption
  413. in [potype_proginit,potype_unitinit,potype_unitfinalize]) then
  414. pstoredsymtable(aktprocsym^.definition^.localst)^.allsymbolsused;
  415. pstoredsymtable(aktprocsym^.definition^.parast)^.allsymbolsused;
  416. end;
  417. end;
  418. { the local symtables can be deleted, but the parast }
  419. { doesn't, (checking definitons when calling a }
  420. { function }
  421. { not for a inline procedure !! (PM) }
  422. { at lexlevel = 1 localst is the staticsymtable itself }
  423. { so no dispose here !! }
  424. if assigned(code) and
  425. not(cs_browser in aktmoduleswitches) and
  426. not(pocall_inline in aktprocsym^.definition^.proccalloptions) then
  427. begin
  428. if lexlevel>=normal_function_level then
  429. dispose(aktprocsym^.definition^.localst,done);
  430. aktprocsym^.definition^.localst:=nil;
  431. end;
  432. {$ifdef newcg}
  433. { all registers can be used again }
  434. tg.resetusableregisters;
  435. { only now we can remove the temps }
  436. tg.resettempgen;
  437. {$else newcg}
  438. { all registers can be used again }
  439. resetusableregisters;
  440. { only now we can remove the temps }
  441. resettempgen;
  442. {$endif newcg}
  443. { remove code tree, if not inline procedure }
  444. if assigned(code) and not(pocall_inline in aktprocsym^.definition^.proccalloptions) then
  445. code.free;
  446. { remove class member symbol tables }
  447. while symtablestack^.symtabletype=objectsymtable do
  448. symtablestack:=symtablestack^.next;
  449. aktmaxfpuregisters:=oldaktmaxfpuregisters;
  450. { restore filepos, the switches are already set }
  451. aktfilepos:=savepos;
  452. { restore labels }
  453. aktexitlabel:=oldexitlabel;
  454. aktexit2label:=oldexit2label;
  455. quickexitlabel:=oldquickexitlabel;
  456. faillabel:=oldfaillabel;
  457. { reset to normal non static function }
  458. if (lexlevel=normal_function_level) then
  459. allow_only_static:=false;
  460. { previous lexlevel }
  461. dec(lexlevel);
  462. end;
  463. {****************************************************************************
  464. PROCEDURE/FUNCTION PARSING
  465. ****************************************************************************}
  466. procedure checkvaluepara(p:pnamedindexobject);
  467. var
  468. vs : pvarsym;
  469. s : string;
  470. begin
  471. with pvarsym(p)^ do
  472. begin
  473. if copy(name,1,3)='val' then
  474. begin
  475. s:=Copy(name,4,255);
  476. if not(po_assembler in aktprocsym^.definition^.procoptions) then
  477. begin
  478. vs:=new(Pvarsym,initdef(s,vartype.def));
  479. vs^.fileinfo:=fileinfo;
  480. vs^.varspez:=varspez;
  481. aktprocsym^.definition^.localst^.insert(vs);
  482. include(vs^.varoptions,vo_is_local_copy);
  483. vs^.varstate:=vs_assigned;
  484. localvarsym:=vs;
  485. inc(refs); { the para was used to set the local copy ! }
  486. { warnings only on local copy ! }
  487. varstate:=vs_used;
  488. end
  489. else
  490. begin
  491. aktprocsym^.definition^.parast^.rename(name,s);
  492. end;
  493. end;
  494. end;
  495. end;
  496. procedure read_proc;
  497. {
  498. Parses the procedure directives, then parses the procedure body, then
  499. generates the code for it
  500. }
  501. var
  502. oldprefix : string;
  503. oldprocsym : Pprocsym;
  504. oldprocinfo : pprocinfo;
  505. oldconstsymtable : Psymtable;
  506. oldfilepos : tfileposinfo;
  507. names : Pstringcontainer;
  508. pdflags : word;
  509. prevdef,stdef : pprocdef;
  510. begin
  511. { save old state }
  512. oldprocsym:=aktprocsym;
  513. oldprefix:=procprefix;
  514. oldconstsymtable:=constsymtable;
  515. oldprocinfo:=procinfo;
  516. { create a new procedure }
  517. new(names,init);
  518. {$ifdef fixLeaksOnError}
  519. strContStack.push(names);
  520. {$endif fixLeaksOnError}
  521. codegen_newprocedure;
  522. with procinfo^ do
  523. begin
  524. parent:=oldprocinfo;
  525. { clear flags }
  526. flags:=0;
  527. { standard frame pointer }
  528. framepointer:=frame_pointer;
  529. { funcret_is_valid:=false; }
  530. funcret_state:=vs_declared;
  531. { is this a nested function of a method ? }
  532. if assigned(oldprocinfo) then
  533. _class:=oldprocinfo^._class;
  534. end;
  535. parse_proc_dec;
  536. procinfo^.sym:=aktprocsym;
  537. procinfo^.def:=aktprocsym^.definition;
  538. { set the default function options }
  539. if parse_only then
  540. begin
  541. aktprocsym^.definition^.forwarddef:=true;
  542. { set also the interface flag, for better error message when the
  543. implementation doesn't much this header }
  544. aktprocsym^.definition^.interfacedef:=true;
  545. pdflags:=pd_interface;
  546. end
  547. else
  548. begin
  549. pdflags:=pd_body;
  550. if current_module^.in_implementation then
  551. pdflags:=pdflags or pd_implemen;
  552. if (not current_module^.is_unit) or (cs_create_smart in aktmoduleswitches) then
  553. pdflags:=pdflags or pd_global;
  554. procinfo^.exported:=false;
  555. aktprocsym^.definition^.forwarddef:=false;
  556. end;
  557. { parse the directives that may follow }
  558. inc(lexlevel);
  559. parse_proc_directives(names,pdflags);
  560. dec(lexlevel);
  561. { set aktfilepos to the beginning of the function declaration }
  562. oldfilepos:=aktfilepos;
  563. aktfilepos:=aktprocsym^.definition^.fileinfo;
  564. { search for forward declarations }
  565. if not check_identical_proc(prevdef) then
  566. begin
  567. { A method must be forward defined (in the object declaration) }
  568. if assigned(procinfo^._class) and (not assigned(oldprocinfo^._class)) then
  569. begin
  570. Message1(parser_e_header_dont_match_any_member,
  571. aktprocsym^.definition^.fullprocname);
  572. aktprocsym^.write_parameter_lists(aktprocsym^.definition);
  573. end
  574. else
  575. begin
  576. { Give a better error if there is a forward def in the interface and only
  577. a single implementation }
  578. if (not aktprocsym^.definition^.forwarddef) and
  579. assigned(aktprocsym^.definition^.nextoverloaded) and
  580. aktprocsym^.definition^.nextoverloaded^.forwarddef and
  581. aktprocsym^.definition^.nextoverloaded^.interfacedef and
  582. not(assigned(aktprocsym^.definition^.nextoverloaded^.nextoverloaded)) then
  583. begin
  584. Message1(parser_e_header_dont_match_forward,
  585. aktprocsym^.definition^.fullprocname);
  586. aktprocsym^.write_parameter_lists(aktprocsym^.definition);
  587. end
  588. else
  589. begin
  590. { check the global flag }
  591. if (procinfo^.flags and pi_is_global)<>0 then
  592. Message(parser_e_overloaded_must_be_all_global);
  593. end;
  594. end;
  595. end;
  596. { set return type here, becuase the aktprocsym^.definition can be
  597. changed by check_identical_proc (PFV) }
  598. procinfo^.returntype.def:=aktprocsym^.definition^.rettype.def;
  599. {$ifdef i386}
  600. if (po_interrupt in aktprocsym^.definition^.procoptions) then
  601. begin
  602. { we push Flags and CS as long
  603. to cope with the IRETD
  604. and we save 6 register + 4 selectors }
  605. inc(procinfo^.para_offset,8+6*4+4*2);
  606. end;
  607. {$endif i386}
  608. { pointer to the return value ? }
  609. if ret_in_param(procinfo^.returntype.def) then
  610. begin
  611. procinfo^.return_offset:=procinfo^.para_offset;
  612. inc(procinfo^.para_offset,target_os.size_of_pointer);
  613. end;
  614. { allows to access the parameters of main functions in nested functions }
  615. aktprocsym^.definition^.parast^.address_fixup:=procinfo^.para_offset;
  616. { when it is a value para and it needs a local copy then rename
  617. the parameter and insert a copy in the localst. This is not done
  618. for assembler procedures }
  619. if (not parse_only) and (not aktprocsym^.definition^.forwarddef) then
  620. aktprocsym^.definition^.parast^.foreach({$ifdef FPCPROCVAR}@{$endif}checkvaluepara);
  621. { restore file pos }
  622. aktfilepos:=oldfilepos;
  623. { compile procedure when a body is needed }
  624. if (pdflags and pd_body)<>0 then
  625. begin
  626. Message1(parser_p_procedure_start,
  627. aktprocsym^.definition^.fullprocname);
  628. names^.insert(aktprocsym^.definition^.mangledname);
  629. { set _FAIL as keyword if constructor }
  630. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  631. tokeninfo^[_FAIL].keyword:=m_all;
  632. if assigned(aktprocsym^.definition^._class) then
  633. tokeninfo^[_SELF].keyword:=m_all;
  634. compile_proc_body(names^,((pdflags and pd_global)<>0),assigned(oldprocinfo^._class));
  635. { reset _FAIL as normal }
  636. if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
  637. tokeninfo^[_FAIL].keyword:=m_none;
  638. if assigned(aktprocsym^.definition^._class) and (lexlevel=main_program_level) then
  639. tokeninfo^[_SELF].keyword:=m_none;
  640. consume(_SEMICOLON);
  641. end;
  642. { close }
  643. {$ifdef fixLeaksOnError}
  644. if names <> strContStack.pop then
  645. writeln('problem with strContStack in psub!');
  646. {$endif fixLeaksOnError}
  647. dispose(names,done);
  648. codegen_doneprocedure;
  649. { Restore old state }
  650. constsymtable:=oldconstsymtable;
  651. { from now on all refernece to mangledname means
  652. that the function is already used }
  653. aktprocsym^.definition^.count:=true;
  654. { restore the interface order to maintain CRC values PM }
  655. if assigned(prevdef) and assigned(aktprocsym^.definition^.nextoverloaded) then
  656. begin
  657. stdef:=aktprocsym^.definition;
  658. aktprocsym^.definition:=stdef^.nextoverloaded;
  659. stdef^.nextoverloaded:=prevdef^.nextoverloaded;
  660. prevdef^.nextoverloaded:=stdef;
  661. end;
  662. aktprocsym:=oldprocsym;
  663. procprefix:=oldprefix;
  664. procinfo:=oldprocinfo;
  665. opsym:=nil;
  666. end;
  667. {****************************************************************************
  668. DECLARATION PARSING
  669. ****************************************************************************}
  670. procedure read_declarations(islibrary : boolean);
  671. procedure Not_supported_for_inline(t : ttoken);
  672. begin
  673. if assigned(aktprocsym) and
  674. (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  675. Begin
  676. Message1(parser_w_not_supported_for_inline,tokenstring(t));
  677. Message(parser_w_inlining_disabled);
  678. exclude(aktprocsym^.definition^.proccalloptions,pocall_inline);
  679. End;
  680. end;
  681. begin
  682. repeat
  683. case token of
  684. _LABEL:
  685. begin
  686. Not_supported_for_inline(token);
  687. label_dec;
  688. end;
  689. _CONST:
  690. begin
  691. Not_supported_for_inline(token);
  692. const_dec;
  693. end;
  694. _TYPE:
  695. begin
  696. Not_supported_for_inline(token);
  697. type_dec;
  698. end;
  699. _VAR:
  700. var_dec;
  701. _THREADVAR:
  702. threadvar_dec;
  703. _CONSTRUCTOR,_DESTRUCTOR,
  704. _FUNCTION,_PROCEDURE,_OPERATOR,_CLASS:
  705. begin
  706. Not_supported_for_inline(token);
  707. read_proc;
  708. end;
  709. _RESOURCESTRING:
  710. resourcestring_dec;
  711. _EXPORTS:
  712. begin
  713. Not_supported_for_inline(token);
  714. { here we should be at lexlevel 1, no ? PM }
  715. if (lexlevel<>main_program_level) or
  716. (current_module^.is_unit) then
  717. begin
  718. Message(parser_e_syntax_error);
  719. consume_all_until(_SEMICOLON);
  720. end
  721. else if islibrary or (target_info.target=target_i386_WIN32)
  722. or (target_info.target=target_i386_Netware) then // AD
  723. read_exports;
  724. end
  725. else break;
  726. end;
  727. until false;
  728. end;
  729. procedure read_interface_declarations;
  730. begin
  731. {Since the body is now parsed at lexlevel 1, and the declarations
  732. must be parsed at the same lexlevel we increase the lexlevel.}
  733. inc(lexlevel);
  734. repeat
  735. case token of
  736. _CONST :
  737. const_dec;
  738. _TYPE :
  739. type_dec;
  740. _VAR :
  741. var_dec;
  742. _THREADVAR :
  743. threadvar_dec;
  744. _RESOURCESTRING:
  745. resourcestring_dec;
  746. _FUNCTION,
  747. _PROCEDURE,
  748. _OPERATOR :
  749. read_proc;
  750. else
  751. break;
  752. end;
  753. until false;
  754. dec(lexlevel);
  755. end;
  756. end.
  757. {
  758. $Log$
  759. Revision 1.23 2000-11-29 00:30:37 florian
  760. * unused units removed from uses clause
  761. * some changes for widestrings
  762. Revision 1.22 2000/11/08 16:38:24 jonas
  763. * if a procedure uses exceptions (be it implicit or explicit), the
  764. usedregisters are set to all (because FPC_POPADDRSTACK doesn't save
  765. any registers) ("merged", fixes make cycle woth -Or)
  766. Revision 1.21 2000/11/01 23:04:38 peter
  767. * tprocdef.fullprocname added for better casesensitve writing of
  768. procedures
  769. Revision 1.20 2000/10/31 22:02:50 peter
  770. * symtable splitted, no real code changes
  771. Revision 1.19 2000/10/24 22:21:25 peter
  772. * set usedregisters after writing entry and exit code (merged)
  773. Revision 1.18 2000/10/21 18:16:12 florian
  774. * a lot of changes:
  775. - basic dyn. array support
  776. - basic C++ support
  777. - some work for interfaces done
  778. ....
  779. Revision 1.17 2000/10/15 07:47:51 peter
  780. * unit names and procedure names are stored mixed case
  781. Revision 1.16 2000/10/14 10:14:52 peter
  782. * moehrendorf oct 2000 rewrite
  783. Revision 1.15 2000/09/24 21:33:47 peter
  784. * message updates merges
  785. Revision 1.14 2000/09/24 21:19:51 peter
  786. * delphi compile fixes
  787. Revision 1.13 2000/09/24 15:06:24 peter
  788. * use defines.inc
  789. Revision 1.12 2000/09/10 20:11:07 peter
  790. * overload checking in implementation removed (merged)
  791. Revision 1.11 2000/09/04 20:15:19 peter
  792. * fixed operator overloading
  793. Revision 1.10 2000/08/27 16:11:52 peter
  794. * moved some util functions from globals,cobjects to cutils
  795. * splitted files into finput,fmodule
  796. Revision 1.9 2000/08/16 18:33:54 peter
  797. * splitted namedobjectitem.next into indexnext and listnext so it
  798. can be used in both lists
  799. * don't allow "word = word" type definitions (merged)
  800. Revision 1.8 2000/08/13 12:54:56 peter
  801. * class member decl wrong then no other error after it
  802. * -vb has now also line numbering
  803. * -vb is also used for interface/implementation different decls and
  804. doesn't list the current function (merged)
  805. Revision 1.7 2000/08/08 19:28:57 peter
  806. * memdebug/memory patches (merged)
  807. * only once illegal directive (merged)
  808. Revision 1.6 2000/08/06 19:39:28 peter
  809. * default parameters working !
  810. Revision 1.5 2000/08/06 14:17:15 peter
  811. * overload fixes (merged)
  812. Revision 1.4 2000/07/30 17:04:43 peter
  813. * merged fixes
  814. Revision 1.3 2000/07/13 12:08:27 michael
  815. + patched to 1.1.0 with former 1.09patch from peter
  816. Revision 1.2 2000/07/13 11:32:46 michael
  817. + removed logs
  818. }