psub.pas 32 KB

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