psub.pas 32 KB

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