psub.pas 34 KB

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