pdecsub.pas 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl, Daniel Mantione
  4. Does the parsing of the procedures/functions
  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 pdecsub;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. tokens,symconst,symtype,symdef,symsym;
  23. const
  24. pd_global = $1; { directive must be global }
  25. pd_body = $2; { directive needs a body }
  26. pd_implemen = $4; { directive can be used implementation section }
  27. pd_interface = $8; { directive can be used interface section }
  28. pd_object = $10; { directive can be used object declaration }
  29. pd_procvar = $20; { directive can be used procvar declaration }
  30. pd_notobject = $40; { directive can not be used object declaration }
  31. pd_notobjintf= $80; { directive can not be used interface declaration }
  32. function is_proc_directive(tok:ttoken):boolean;
  33. procedure parameter_dec(aktprocdef:tabstractprocdef);
  34. procedure parse_proc_directives(var pdflags:word);
  35. procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
  36. procedure calc_parasymtable_addresses(def:tprocdef);
  37. procedure parse_proc_head(options:tproctypeoption);
  38. procedure parse_proc_dec;
  39. procedure parse_var_proc_directives(var sym : tsym);
  40. procedure parse_object_proc_directives(var sym : tprocsym);
  41. function proc_add_definition(aprocsym:tprocsym;var aprocdef : tprocdef) : boolean;
  42. implementation
  43. uses
  44. {$ifdef delphi}
  45. sysutils,
  46. {$else delphi}
  47. strings,
  48. {$endif delphi}
  49. { common }
  50. cutils,cclasses,
  51. { global }
  52. globtype,globals,verbose,
  53. systems,cpubase,
  54. { aasm }
  55. aasmbase,aasmtai,aasmcpu,
  56. { symtable }
  57. symbase,symtable,defbase,paramgr,
  58. { pass 1 }
  59. node,htypechk,
  60. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  61. { parser }
  62. fmodule,scanner,
  63. pbase,pexpr,ptype,pdecl,
  64. { linking }
  65. import,gendef,
  66. { codegen }
  67. cpuinfo,cgbase
  68. ;
  69. procedure resetvaluepara(p:tnamedindexitem;arg:pointer);
  70. begin
  71. if tsym(p).typ=varsym then
  72. with tvarsym(p) do
  73. if copy(name,1,3)='val' then
  74. aktprocdef.parast.symsearch.rename(name,copy(name,4,length(name)));
  75. end;
  76. procedure parameter_dec(aktprocdef:tabstractprocdef);
  77. {
  78. handle_procvar needs the same changes
  79. }
  80. var
  81. is_procvar : boolean;
  82. sc : tidstringlist;
  83. s : string;
  84. hpos,
  85. storetokenpos : tfileposinfo;
  86. htype,
  87. tt : ttype;
  88. hvs,
  89. vs : tvarsym;
  90. srsym : tsym;
  91. hs1 : string;
  92. varspez : Tvarspez;
  93. inserthigh : boolean;
  94. tdefaultvalue : tconstsym;
  95. defaultrequired : boolean;
  96. old_object_option : tsymoptions;
  97. begin
  98. { reset }
  99. defaultrequired:=false;
  100. { parsing a proc or procvar ? }
  101. is_procvar:=(aktprocdef.deftype=procvardef);
  102. consume(_LKLAMMER);
  103. { Delphi/Kylix supports nonsense like }
  104. { procedure p(); }
  105. if try_to_consume(_RKLAMMER) and
  106. not(m_tp7 in aktmodeswitches) then
  107. exit;
  108. { the variables are always public }
  109. old_object_option:=current_object_option;
  110. current_object_option:=[sp_public];
  111. inc(testcurobject);
  112. repeat
  113. if try_to_consume(_VAR) then
  114. varspez:=vs_var
  115. else
  116. if try_to_consume(_CONST) then
  117. varspez:=vs_const
  118. else
  119. if (idtoken=_OUT) and (m_out in aktmodeswitches) then
  120. begin
  121. consume(_OUT);
  122. varspez:=vs_out
  123. end
  124. else
  125. varspez:=vs_value;
  126. inserthigh:=false;
  127. tdefaultvalue:=nil;
  128. tt.reset;
  129. { self is only allowed in procvars and class methods }
  130. if (idtoken=_SELF) and
  131. (is_procvar or
  132. (assigned(procinfo._class) and is_class(procinfo._class))) then
  133. begin
  134. if varspez <> vs_value then
  135. CGMessage(parser_e_self_call_by_value);
  136. if not is_procvar then
  137. begin
  138. htype.setdef(procinfo._class);
  139. vs:=tvarsym.create('@',htype);
  140. vs.varspez:=vs_var;
  141. { insert the sym in the parasymtable }
  142. tprocdef(aktprocdef).parast.insert(vs);
  143. inc(procinfo.selfpointer_offset,vs.address);
  144. end
  145. else
  146. vs:=nil;
  147. { must also be included for procvars to allow the proc2procvar }
  148. { type conversions (po_containsself is in po_comp) (JM) }
  149. include(aktprocdef.procoptions,po_containsself);
  150. consume(idtoken);
  151. consume(_COLON);
  152. single_type(tt,hs1,false);
  153. { this must be call-by-value, but we generate already an }
  154. { an error above if that's not the case (JM) }
  155. aktprocdef.concatpara(tt,vs,varspez,nil);
  156. { check the types for procedures only }
  157. if not is_procvar then
  158. CheckTypes(tt.def,procinfo._class);
  159. end
  160. else
  161. begin
  162. { read identifiers }
  163. sc:=consume_idlist;
  164. {$ifdef fixLeaksOnError}
  165. strContStack.push(sc);
  166. {$endif fixLeaksOnError}
  167. { read type declaration, force reading for value and const paras }
  168. if (token=_COLON) or (varspez=vs_value) then
  169. begin
  170. consume(_COLON);
  171. { check for an open array }
  172. if token=_ARRAY then
  173. begin
  174. consume(_ARRAY);
  175. consume(_OF);
  176. { define range and type of range }
  177. tt.setdef(tarraydef.create(0,-1,s32bittype));
  178. { array of const ? }
  179. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  180. begin
  181. consume(_CONST);
  182. srsym:=searchsymonlyin(systemunit,'TVARREC');
  183. if not assigned(srsym) then
  184. InternalError(1234124);
  185. tarraydef(tt.def).elementtype:=ttypesym(srsym).restype;
  186. tarraydef(tt.def).IsArrayOfConst:=true;
  187. end
  188. else
  189. begin
  190. { define field type }
  191. single_type(tarraydef(tt.def).elementtype,hs1,false);
  192. end;
  193. inserthigh:=true;
  194. end
  195. else
  196. begin
  197. { open string ? }
  198. if (varspez=vs_var) and
  199. (
  200. (
  201. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  202. (cs_openstring in aktmoduleswitches) and
  203. not(cs_ansistrings in aktlocalswitches)
  204. ) or
  205. (idtoken=_OPENSTRING)) then
  206. begin
  207. consume(token);
  208. tt:=openshortstringtype;
  209. hs1:='openstring';
  210. inserthigh:=true;
  211. end
  212. else
  213. begin
  214. { everything else }
  215. single_type(tt,hs1,false);
  216. end;
  217. { default parameter }
  218. if (m_default_para in aktmodeswitches) then
  219. begin
  220. if try_to_consume(_EQUAL) then
  221. begin
  222. s:=sc.get(hpos);
  223. if not sc.empty then
  224. Comment(V_Error,'default value only allowed for one parameter');
  225. sc.add(s,hpos);
  226. { prefix 'def' to the parameter name }
  227. tdefaultvalue:=ReadConstant('$def'+Upper(s),hpos);
  228. if assigned(tdefaultvalue) then
  229. tprocdef(aktprocdef).parast.insert(tdefaultvalue);
  230. defaultrequired:=true;
  231. end
  232. else
  233. begin
  234. if defaultrequired then
  235. Comment(V_Error,'default parameter required');
  236. end;
  237. end;
  238. end;
  239. end
  240. else
  241. begin
  242. {$ifndef UseNiceNames}
  243. hs1:='$$$';
  244. {$else UseNiceNames}
  245. hs1:='var';
  246. {$endif UseNiceNames}
  247. tt:=cformaltype;
  248. end;
  249. storetokenpos:=akttokenpos;
  250. while not sc.empty do
  251. begin
  252. s:=sc.get(akttokenpos);
  253. { For proc vars we only need the definitions }
  254. if not is_procvar then
  255. begin
  256. vs:=tvarsym.create(s,tt);
  257. vs.varspez:=varspez;
  258. { we have to add this to avoid var param to be in registers !!!}
  259. { I don't understand the comment above, }
  260. { but I suppose the comment is wrong and }
  261. { it means that the address of var parameters can be placed }
  262. { in a register (FK) }
  263. if (varspez in [vs_var,vs_const,vs_out]) and
  264. paramanager.push_addr_param(tt.def,false) then
  265. include(vs.varoptions,vo_regable);
  266. { insert the sym in the parasymtable }
  267. tprocdef(aktprocdef).parast.insert(vs);
  268. { do we need a local copy? Then rename the varsym, do this after the
  269. insert so the dup id checking is done correctly }
  270. if (varspez=vs_value) and
  271. paramanager.push_addr_param(tt.def,aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  272. not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
  273. tprocdef(aktprocdef).parast.rename(vs.name,'val'+vs.name);
  274. { also need to push a high value? }
  275. if inserthigh then
  276. begin
  277. hvs:=tvarsym.create('$high'+Upper(s),s32bittype);
  278. hvs.varspez:=vs_const;
  279. tprocdef(aktprocdef).parast.insert(hvs);
  280. end;
  281. end
  282. else
  283. vs:=nil;
  284. aktprocdef.concatpara(tt,vs,varspez,tdefaultvalue);
  285. end;
  286. {$ifdef fixLeaksOnError}
  287. if PStringContainer(strContStack.pop) <> sc then
  288. writeln('problem with strContStack in pdecl (1)');
  289. {$endif fixLeaksOnError}
  290. sc.free;
  291. akttokenpos:=storetokenpos;
  292. end;
  293. { set the new mangled name }
  294. until not try_to_consume(_SEMICOLON);
  295. dec(testcurobject);
  296. current_object_option:=old_object_option;
  297. consume(_RKLAMMER);
  298. end;
  299. procedure parse_proc_head(options:tproctypeoption);
  300. var
  301. orgsp,sp:stringid;
  302. paramoffset:longint;
  303. sym:tsym;
  304. st : tsymtable;
  305. srsymtable : tsymtable;
  306. pdl : pprocdeflist;
  307. storepos,procstartfilepos : tfileposinfo;
  308. i: longint;
  309. begin
  310. { Save the position where this procedure really starts }
  311. procstartfilepos:=akttokenpos;
  312. aktprocdef:=nil;
  313. if (options=potype_operator) then
  314. begin
  315. sp:=overloaded_names[optoken];
  316. orgsp:=sp;
  317. end
  318. else
  319. begin
  320. sp:=pattern;
  321. orgsp:=orgpattern;
  322. consume(_ID);
  323. end;
  324. { examine interface map: function/procedure iname.functionname=locfuncname }
  325. if parse_only and
  326. assigned(procinfo._class) and
  327. assigned(procinfo._class.implementedinterfaces) and
  328. (procinfo._class.implementedinterfaces.count>0) and
  329. try_to_consume(_POINT) then
  330. begin
  331. storepos:=akttokenpos;
  332. akttokenpos:=procstartfilepos;
  333. { get interface syms}
  334. searchsym(sp,sym,srsymtable);
  335. if not assigned(sym) then
  336. begin
  337. identifier_not_found(orgsp);
  338. sym:=generrorsym;
  339. end;
  340. akttokenpos:=storepos;
  341. { load proc name }
  342. if sym.typ=typesym then
  343. i:=procinfo._class.implementedinterfaces.searchintf(ttypesym(sym).restype.def);
  344. { qualifier is interface name? }
  345. if (sym.typ<>typesym) or (ttypesym(sym).restype.def.deftype<>objectdef) or
  346. (i=-1) then
  347. begin
  348. Message(parser_e_interface_id_expected);
  349. aktprocsym:=nil;
  350. end
  351. else
  352. begin
  353. aktprocsym:=tprocsym(procinfo._class.implementedinterfaces.interfaces(i).symtable.search(sp));
  354. { the method can be declared after the mapping FK
  355. if not(assigned(aktprocsym)) then
  356. Message(parser_e_methode_id_expected);
  357. }
  358. end;
  359. consume(_ID);
  360. consume(_EQUAL);
  361. if (token=_ID) { and assigned(aktprocsym) } then
  362. procinfo._class.implementedinterfaces.addmappings(i,sp,pattern);
  363. consume(_ID);
  364. exit;
  365. end;
  366. { method ? }
  367. if not(parse_only) and
  368. (lexlevel=normal_function_level) and
  369. try_to_consume(_POINT) then
  370. begin
  371. { search for object name }
  372. storepos:=akttokenpos;
  373. akttokenpos:=procstartfilepos;
  374. searchsym(sp,sym,srsymtable);
  375. if not assigned(sym) then
  376. begin
  377. identifier_not_found(orgsp);
  378. sym:=generrorsym;
  379. end;
  380. akttokenpos:=storepos;
  381. { consume proc name }
  382. sp:=pattern;
  383. orgsp:=orgpattern;
  384. procstartfilepos:=akttokenpos;
  385. consume(_ID);
  386. { qualifier is class name ? }
  387. if (sym.typ<>typesym) or
  388. (ttypesym(sym).restype.def.deftype<>objectdef) then
  389. begin
  390. Message(parser_e_class_id_expected);
  391. aktprocsym:=nil;
  392. aktprocdef:=nil;
  393. end
  394. else
  395. begin
  396. { used to allow private syms to be seen }
  397. aktobjectdef:=tobjectdef(ttypesym(sym).restype.def);
  398. procinfo._class:=tobjectdef(ttypesym(sym).restype.def);
  399. aktprocsym:=tprocsym(procinfo._class.symtable.search(sp));
  400. {The procedure has been found. So it is
  401. a global one. Set the flags to mark this.}
  402. procinfo.flags:=procinfo.flags or pi_is_global;
  403. aktobjectdef:=nil;
  404. { we solve this below }
  405. if not(assigned(aktprocsym)) then
  406. Message(parser_e_methode_id_expected);
  407. end;
  408. end
  409. else
  410. begin
  411. { check for constructor/destructor which is not allowed here }
  412. if (not parse_only) and
  413. (options in [potype_constructor,potype_destructor]) then
  414. Message(parser_e_constructors_always_objects);
  415. akttokenpos:=procstartfilepos;
  416. aktprocsym:=tprocsym(symtablestack.search(sp));
  417. if not(parse_only) then
  418. begin
  419. {The procedure we prepare for is in the implementation
  420. part of the unit we compile. It is also possible that we
  421. are compiling a program, which is also some kind of
  422. implementaion part.
  423. We need to find out if the procedure is global. If it is
  424. global, it is in the global symtable.}
  425. if not assigned(aktprocsym) and
  426. (symtablestack.symtabletype=staticsymtable) and
  427. assigned(symtablestack.next) and
  428. (symtablestack.next.unitid=0) then
  429. begin
  430. {Search the procedure in the global symtable.}
  431. aktprocsym:=tprocsym(symtablestack.next.search(sp));
  432. if assigned(aktprocsym) then
  433. begin
  434. {Check if it is a procedure.}
  435. if aktprocsym.typ<>procsym then
  436. DuplicateSym(aktprocsym);
  437. {The procedure has been found. So it is
  438. a global one. Set the flags to mark this.}
  439. procinfo.flags:=procinfo.flags or pi_is_global;
  440. end;
  441. end;
  442. end;
  443. end;
  444. if assigned(aktprocsym) then
  445. begin
  446. { Check if overloaded is a procsym }
  447. if aktprocsym.typ<>procsym then
  448. begin
  449. { when the other symbol is a unit symbol then hide the unit
  450. symbol. Only in tp mode because it's bad programming }
  451. if (m_duplicate_names in aktmodeswitches) and
  452. (aktprocsym.typ=unitsym) then
  453. begin
  454. aktprocsym.owner.rename(aktprocsym.name,'hidden'+aktprocsym.name);
  455. end
  456. else
  457. begin
  458. { we use a different error message for tp7 so it looks more compatible }
  459. if (m_fpc in aktmodeswitches) then
  460. Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
  461. else
  462. DuplicateSym(aktprocsym);
  463. { rename the name to an unique name to avoid an
  464. error when inserting the symbol in the symtable }
  465. orgsp:=orgsp+'$'+tostr(aktfilepos.line);
  466. end;
  467. { generate a new aktprocsym }
  468. aktprocsym:=nil;
  469. end;
  470. end;
  471. { test again if assigned, it can be reset to recover }
  472. if not assigned(aktprocsym) then
  473. begin
  474. { create a new procsym and set the real filepos }
  475. akttokenpos:=procstartfilepos;
  476. { for operator we have only one procsym for each overloaded
  477. operation }
  478. if (options=potype_operator) then
  479. begin
  480. { is the current overload sym already in the current unit }
  481. if assigned(overloaded_operators[optoken]) and
  482. (overloaded_operators[optoken].owner=symtablestack) then
  483. aktprocsym:=overloaded_operators[optoken]
  484. else
  485. begin
  486. { create the procsym with saving the original case }
  487. aktprocsym:=tprocsym.create('$'+sp);
  488. { add already known overloaded defs }
  489. if assigned(overloaded_operators[optoken]) then
  490. begin
  491. pdl:=overloaded_operators[optoken].defs;
  492. while assigned(pdl) do
  493. begin
  494. aktprocsym.addprocdef(pdl^.def);
  495. pdl:=pdl^.next;
  496. end;
  497. end;
  498. end;
  499. end
  500. else
  501. aktprocsym:=tprocsym.create(orgsp);
  502. symtablestack.insert(aktprocsym);
  503. end;
  504. st:=symtablestack;
  505. aktprocdef:=tprocdef.create;
  506. aktprocdef.symtablelevel:=symtablestack.symtablelevel;
  507. if assigned(procinfo._class) then
  508. aktprocdef._class := procinfo._class;
  509. { set the options from the caller (podestructor or poconstructor) }
  510. aktprocdef.proctypeoption:=options;
  511. { calculate the offset of the parameters }
  512. paramoffset:=target_info.first_parm_offset;
  513. { calculate frame pointer offset }
  514. if lexlevel>normal_function_level then
  515. begin
  516. procinfo.framepointer_offset:=paramoffset;
  517. inc(paramoffset,pointer_size);
  518. { this is needed to get correct framepointer push for local
  519. forward functions !! }
  520. aktprocdef.parast.symtablelevel:=lexlevel;
  521. end;
  522. if assigned (procinfo._Class) and
  523. is_object(procinfo._Class) and
  524. (aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) then
  525. inc(paramoffset,pointer_size);
  526. { self pointer offset }
  527. { self isn't pushed in nested procedure of methods }
  528. if assigned(procinfo._class) and (lexlevel=normal_function_level) then
  529. begin
  530. procinfo.selfpointer_offset:=paramoffset;
  531. if assigned(aktprocdef) and
  532. not(po_containsself in aktprocdef.procoptions) then
  533. inc(paramoffset,pointer_size);
  534. end;
  535. { con/-destructor flag ? }
  536. if assigned (procinfo._Class) and
  537. is_class(procinfo._class) and
  538. (aktprocdef.proctypeoption in [potype_destructor,potype_constructor]) then
  539. inc(paramoffset,pointer_size);
  540. procinfo.para_offset:=paramoffset;
  541. aktprocdef.parast.datasize:=0;
  542. { add procsym to the procdef }
  543. aktprocdef.procsym:=aktprocsym;
  544. { save file position }
  545. aktprocdef.fileinfo:=procstartfilepos;
  546. { this must also be inserted in the right symtable !! PM }
  547. { otherwise we get subbtle problems with
  548. definitions of args defs in staticsymtable for
  549. implementation of a global method }
  550. if token=_LKLAMMER then
  551. parameter_dec(aktprocdef);
  552. { so we only restore the symtable now }
  553. symtablestack:=st;
  554. if (options=potype_operator) then
  555. overloaded_operators[optoken]:=aktprocsym;
  556. end;
  557. procedure parse_proc_dec;
  558. var
  559. hs : string;
  560. isclassmethod : boolean;
  561. begin
  562. inc(lexlevel);
  563. { read class method }
  564. if token=_CLASS then
  565. begin
  566. consume(_CLASS);
  567. isclassmethod:=true;
  568. end
  569. else
  570. isclassmethod:=false;
  571. case token of
  572. _FUNCTION : begin
  573. consume(_FUNCTION);
  574. parse_proc_head(potype_none);
  575. if token<>_COLON then
  576. begin
  577. if assigned(aktprocsym) and
  578. not(is_interface(aktprocdef._class)) and
  579. not(aktprocdef.forwarddef) or
  580. (m_repeat_forward in aktmodeswitches) then
  581. begin
  582. consume(_COLON);
  583. consume_all_until(_SEMICOLON);
  584. end;
  585. end
  586. else
  587. begin
  588. consume(_COLON);
  589. inc(testcurobject);
  590. single_type(aktprocdef.rettype,hs,false);
  591. aktprocdef.test_if_fpu_result;
  592. dec(testcurobject);
  593. end;
  594. end;
  595. _PROCEDURE : begin
  596. consume(_PROCEDURE);
  597. parse_proc_head(potype_none);
  598. if assigned(aktprocsym) then
  599. aktprocdef.rettype:=voidtype;
  600. end;
  601. _CONSTRUCTOR : begin
  602. consume(_CONSTRUCTOR);
  603. parse_proc_head(potype_constructor);
  604. if assigned(procinfo._class) and
  605. is_class(procinfo._class) then
  606. begin
  607. { CLASS constructors return the created instance }
  608. aktprocdef.rettype.setdef(procinfo._class);
  609. end
  610. else
  611. begin
  612. { OBJECT constructors return a boolean }
  613. aktprocdef.rettype:=booltype;
  614. end;
  615. end;
  616. _DESTRUCTOR : begin
  617. consume(_DESTRUCTOR);
  618. parse_proc_head(potype_destructor);
  619. aktprocdef.rettype:=voidtype;
  620. end;
  621. _OPERATOR : begin
  622. if lexlevel>normal_function_level then
  623. Message(parser_e_no_local_operator);
  624. consume(_OPERATOR);
  625. if (token in [first_overloaded..last_overloaded]) then
  626. begin
  627. procinfo.flags:=procinfo.flags or pi_operator;
  628. optoken:=token;
  629. end
  630. else
  631. begin
  632. Message(parser_e_overload_operator_failed);
  633. { Use the dummy NOTOKEN that is also declared
  634. for the overloaded_operator[] }
  635. optoken:=NOTOKEN;
  636. end;
  637. consume(Token);
  638. parse_proc_head(potype_operator);
  639. if token<>_ID then
  640. begin
  641. otsym:=nil;
  642. if not(m_result in aktmodeswitches) then
  643. consume(_ID);
  644. end
  645. else
  646. begin
  647. otsym:=tvarsym.create(pattern,voidtype);
  648. consume(_ID);
  649. end;
  650. if not try_to_consume(_COLON) then
  651. begin
  652. consume(_COLON);
  653. aktprocdef.rettype:=generrortype;
  654. consume_all_until(_SEMICOLON);
  655. end
  656. else
  657. begin
  658. single_type(aktprocdef.rettype,hs,false);
  659. aktprocdef.test_if_fpu_result;
  660. if (optoken in [_EQUAL,_GT,_LT,_GTE,_LTE]) and
  661. ((aktprocdef.rettype.def.deftype<>
  662. orddef) or (torddef(aktprocdef.
  663. rettype.def).typ<>bool8bit)) then
  664. Message(parser_e_comparative_operator_return_boolean);
  665. if assigned(otsym) then
  666. otsym.vartype.def:=aktprocdef.rettype.def;
  667. if (optoken=_ASSIGNMENT) and
  668. is_equal(aktprocdef.rettype.def,
  669. tvarsym(aktprocdef.parast.symindex.first).vartype.def) then
  670. message(parser_e_no_such_assignment)
  671. else if not isoperatoracceptable(aktprocdef,optoken) then
  672. Message(parser_e_overload_impossible);
  673. end;
  674. end;
  675. end;
  676. if isclassmethod and
  677. assigned(aktprocsym) then
  678. include(aktprocdef.procoptions,po_classmethod);
  679. { support procedure proc;stdcall export; in Delphi mode only }
  680. if not((m_delphi in aktmodeswitches) and
  681. is_proc_directive(token)) then
  682. consume(_SEMICOLON);
  683. dec(lexlevel);
  684. end;
  685. {****************************************************************************
  686. Procedure directive handlers
  687. ****************************************************************************}
  688. procedure pd_far;
  689. begin
  690. Message(parser_w_proc_far_ignored);
  691. end;
  692. procedure pd_near;
  693. begin
  694. Message(parser_w_proc_near_ignored);
  695. end;
  696. procedure pd_export;
  697. begin
  698. if assigned(procinfo._class) then
  699. Message(parser_e_methods_dont_be_export);
  700. if lexlevel<>normal_function_level then
  701. Message(parser_e_dont_nest_export);
  702. { only os/2 needs this }
  703. if target_info.system=system_i386_os2 then
  704. begin
  705. aktprocdef.aliasnames.insert(aktprocsym.realname);
  706. procinfo.exported:=true;
  707. if cs_link_deffile in aktglobalswitches then
  708. deffile.AddExport(aktprocdef.mangledname);
  709. end;
  710. end;
  711. procedure pd_forward;
  712. begin
  713. aktprocdef.forwarddef:=true;
  714. end;
  715. procedure pd_alias;
  716. begin
  717. consume(_COLON);
  718. aktprocdef.aliasnames.insert(get_stringconst);
  719. end;
  720. procedure pd_asmname;
  721. begin
  722. aktprocdef.setmangledname(target_info.Cprefix+pattern);
  723. aktprocdef.has_mangledname:=true;
  724. if token=_CCHAR then
  725. consume(_CCHAR)
  726. else
  727. consume(_CSTRING);
  728. { we don't need anything else }
  729. aktprocdef.forwarddef:=false;
  730. end;
  731. procedure pd_intern;
  732. begin
  733. consume(_COLON);
  734. aktprocdef.extnumber:=get_intconst;
  735. end;
  736. procedure pd_interrupt;
  737. begin
  738. if lexlevel<>normal_function_level then
  739. Message(parser_e_dont_nest_interrupt);
  740. end;
  741. procedure pd_abstract;
  742. begin
  743. if (po_virtualmethod in aktprocdef.procoptions) then
  744. include(aktprocdef.procoptions,po_abstractmethod)
  745. else
  746. Message(parser_e_only_virtual_methods_abstract);
  747. { the method is defined }
  748. aktprocdef.forwarddef:=false;
  749. end;
  750. procedure pd_virtual;
  751. {$ifdef WITHDMT}
  752. var
  753. pt : tnode;
  754. {$endif WITHDMT}
  755. begin
  756. if (aktprocdef.proctypeoption=potype_constructor) and
  757. is_object(aktprocdef._class) then
  758. Message(parser_e_constructor_cannot_be_not_virtual);
  759. {$ifdef WITHDMT}
  760. if is_object(aktprocdef._class) and
  761. (token<>_SEMICOLON) then
  762. begin
  763. { any type of parameter is allowed here! }
  764. pt:=comp_expr(true);
  765. if is_constintnode(pt) then
  766. begin
  767. include(aktprocdef.procoptions,po_msgint);
  768. aktprocdef.messageinf.i:=pt^.value;
  769. end
  770. else
  771. Message(parser_e_ill_msg_expr);
  772. disposetree(pt);
  773. end;
  774. {$endif WITHDMT}
  775. end;
  776. procedure pd_static;
  777. begin
  778. if (cs_static_keyword in aktmoduleswitches) then
  779. begin
  780. include(aktprocsym.symoptions,sp_static);
  781. include(aktprocdef.procoptions,po_staticmethod);
  782. end;
  783. end;
  784. procedure pd_override;
  785. begin
  786. if not(is_class_or_interface(aktprocdef._class)) then
  787. Message(parser_e_no_object_override);
  788. end;
  789. procedure pd_overload;
  790. begin
  791. include(aktprocsym.symoptions,sp_has_overloaded);
  792. end;
  793. procedure pd_message;
  794. var
  795. pt : tnode;
  796. begin
  797. { check parameter type }
  798. if not(po_containsself in aktprocdef.procoptions) and
  799. ((aktprocdef.minparacount<>1) or
  800. (aktprocdef.maxparacount<>1) or
  801. (TParaItem(aktprocdef.Para.first).paratyp<>vs_var)) then
  802. Message(parser_e_ill_msg_param);
  803. pt:=comp_expr(true);
  804. if pt.nodetype=stringconstn then
  805. begin
  806. include(aktprocdef.procoptions,po_msgstr);
  807. aktprocdef.messageinf.str:=strnew(tstringconstnode(pt).value_str);
  808. end
  809. else
  810. if is_constintnode(pt) then
  811. begin
  812. include(aktprocdef.procoptions,po_msgint);
  813. aktprocdef.messageinf.i:=tordconstnode(pt).value;
  814. end
  815. else
  816. Message(parser_e_ill_msg_expr);
  817. pt.free;
  818. end;
  819. procedure pd_reintroduce;
  820. begin
  821. Message1(parser_w_proc_directive_ignored,'REINTRODUCE');
  822. end;
  823. procedure pd_syscall;
  824. begin
  825. aktprocdef.forwarddef:=false;
  826. aktprocdef.extnumber:=get_intconst;
  827. end;
  828. procedure pd_external;
  829. {
  830. If import_dll=nil the procedure is assumed to be in another
  831. object file. In that object file it should have the name to
  832. which import_name is pointing to. Otherwise, the procedure is
  833. assumed to be in the DLL to which import_dll is pointing to. In
  834. that case either import_nr<>0 or import_name<>nil is true, so
  835. the procedure is either imported by number or by name. (DM)
  836. }
  837. var
  838. import_dll,
  839. import_name : string;
  840. import_nr : word;
  841. begin
  842. aktprocdef.forwarddef:=false;
  843. { forbid local external procedures }
  844. if lexlevel>normal_function_level then
  845. Message(parser_e_no_local_external);
  846. { If the procedure should be imported from a DLL, a constant string follows.
  847. This isn't really correct, an contant string expression follows
  848. so we check if an semicolon follows, else a string constant have to
  849. follow (FK) }
  850. import_nr:=0;
  851. import_name:='';
  852. if not(token=_SEMICOLON) and not(idtoken=_NAME) then
  853. begin
  854. import_dll:=get_stringconst;
  855. if (idtoken=_NAME) then
  856. begin
  857. consume(_NAME);
  858. import_name:=get_stringconst;
  859. end;
  860. if (idtoken=_INDEX) then
  861. begin
  862. {After the word index follows the index number in the DLL.}
  863. consume(_INDEX);
  864. import_nr:=get_intconst;
  865. end;
  866. { default is to used the realname of the procedure }
  867. if (import_nr=0) and (import_name='') then
  868. import_name:=aktprocsym.realname;
  869. { create importlib if not already done }
  870. if not(current_module.uses_imports) then
  871. begin
  872. current_module.uses_imports:=true;
  873. importlib.preparelib(current_module.modulename^);
  874. end;
  875. {$ifdef notused}
  876. if not(m_repeat_forward in aktmodeswitches) and
  877. { if the procedure is declared with the overload option }
  878. { it requires a full declaration in the implementation part }
  879. not(sp_has_overloaded in aktprocsym.symoptions) then
  880. begin
  881. { we can only have one overloaded here ! }
  882. if assigned(aktprocdef.defs.next) then
  883. importlib.importprocedure(aktprocdef.defs.next.mangledname,
  884. import_dll,import_nr,import_name)
  885. else
  886. importlib.importprocedure(aktprocdef.mangledname,import_dll,import_nr,import_name);
  887. end
  888. else
  889. {$endif notused}
  890. importlib.importprocedure(aktprocdef.mangledname,import_dll,import_nr,import_name);
  891. end
  892. else
  893. begin
  894. if (idtoken=_NAME) then
  895. begin
  896. consume(_NAME);
  897. import_name:=get_stringconst;
  898. aktprocdef.setmangledname(import_name);
  899. aktprocdef.has_mangledname:=true;
  900. end;
  901. end;
  902. end;
  903. type
  904. pd_handler=procedure;
  905. proc_dir_rec=record
  906. idtok : ttoken;
  907. pd_flags : longint;
  908. handler : pd_handler;
  909. pocall : tproccalloption;
  910. pooption : tprocoptions;
  911. mutexclpocall : tproccalloptions;
  912. mutexclpotype : tproctypeoptions;
  913. mutexclpo : tprocoptions;
  914. end;
  915. const
  916. {Should contain the number of procedure directives we support.}
  917. num_proc_directives=36;
  918. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  919. (
  920. (
  921. idtok:_ABSTRACT;
  922. pd_flags : pd_interface+pd_object+pd_notobjintf;
  923. handler : {$ifdef FPCPROCVAR}@{$endif}pd_abstract;
  924. pocall : pocall_none;
  925. pooption : [po_abstractmethod];
  926. mutexclpocall : [pocall_internproc,pocall_inline];
  927. mutexclpotype : [potype_constructor,potype_destructor];
  928. mutexclpo : [po_exports,po_interrupt,po_external]
  929. ),(
  930. idtok:_ALIAS;
  931. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  932. handler : {$ifdef FPCPROCVAR}@{$endif}pd_alias;
  933. pocall : pocall_none;
  934. pooption : [];
  935. mutexclpocall : [pocall_inline];
  936. mutexclpotype : [];
  937. mutexclpo : [po_external]
  938. ),(
  939. idtok:_ASMNAME;
  940. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  941. handler : {$ifdef FPCPROCVAR}@{$endif}pd_asmname;
  942. pocall : pocall_cdecl;
  943. pooption : [po_external];
  944. mutexclpocall : [pocall_internproc,pocall_inline];
  945. mutexclpotype : [];
  946. mutexclpo : [po_external]
  947. ),(
  948. idtok:_ASSEMBLER;
  949. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  950. handler : nil;
  951. pocall : pocall_none;
  952. pooption : [po_assembler];
  953. mutexclpocall : [];
  954. mutexclpotype : [];
  955. mutexclpo : [po_external]
  956. ),(
  957. idtok:_CDECL;
  958. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  959. handler : nil;
  960. pocall : pocall_cdecl;
  961. pooption : [];
  962. mutexclpocall : [];
  963. mutexclpotype : [];
  964. mutexclpo : [po_assembler,po_external]
  965. ),(
  966. idtok:_DYNAMIC;
  967. pd_flags : pd_interface+pd_object+pd_notobjintf;
  968. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  969. pocall : pocall_none;
  970. pooption : [po_virtualmethod];
  971. mutexclpocall : [pocall_internproc,pocall_inline];
  972. mutexclpotype : [];
  973. mutexclpo : [po_exports,po_interrupt,po_external]
  974. ),(
  975. idtok:_EXPORT;
  976. pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??}+pd_notobjintf;
  977. handler : {$ifdef FPCPROCVAR}@{$endif}pd_export;
  978. pocall : pocall_none;
  979. pooption : [po_exports];
  980. mutexclpocall : [pocall_internproc,pocall_inline];
  981. mutexclpotype : [];
  982. mutexclpo : [po_external,po_interrupt]
  983. ),(
  984. idtok:_EXTERNAL;
  985. pd_flags : pd_implemen+pd_interface+pd_notobjintf;
  986. handler : {$ifdef FPCPROCVAR}@{$endif}pd_external;
  987. pocall : pocall_none;
  988. pooption : [po_external];
  989. mutexclpocall : [pocall_internproc,pocall_inline,pocall_palmossyscall];
  990. mutexclpotype : [];
  991. mutexclpo : [po_exports,po_interrupt,po_assembler]
  992. ),(
  993. idtok:_FAR;
  994. pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar+pd_notobjintf;
  995. handler : {$ifdef FPCPROCVAR}@{$endif}pd_far;
  996. pocall : pocall_none;
  997. pooption : [];
  998. mutexclpocall : [pocall_internproc,pocall_inline];
  999. mutexclpotype : [];
  1000. mutexclpo : []
  1001. ),(
  1002. idtok:_FAR16;
  1003. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1004. handler : nil;
  1005. pocall : pocall_far16;
  1006. pooption : [];
  1007. mutexclpocall : [];
  1008. mutexclpotype : [];
  1009. mutexclpo : [po_external,po_leftright]
  1010. ),(
  1011. idtok:_FORWARD;
  1012. pd_flags : pd_implemen+pd_notobjintf;
  1013. handler : {$ifdef FPCPROCVAR}@{$endif}pd_forward;
  1014. pocall : pocall_none;
  1015. pooption : [];
  1016. mutexclpocall : [pocall_internproc,pocall_inline];
  1017. mutexclpotype : [];
  1018. mutexclpo : [po_external]
  1019. ),(
  1020. idtok:_FPCCALL;
  1021. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1022. handler : nil;
  1023. pocall : pocall_fpccall;
  1024. pooption : [];
  1025. mutexclpocall : [];
  1026. mutexclpotype : [];
  1027. mutexclpo : [po_leftright]
  1028. ),(
  1029. idtok:_INLINE;
  1030. pd_flags : pd_interface+pd_implemen+pd_body+pd_notobjintf;
  1031. handler : nil;
  1032. pocall : pocall_inline;
  1033. pooption : [];
  1034. mutexclpocall : [];
  1035. mutexclpotype : [potype_constructor,potype_destructor];
  1036. mutexclpo : [po_exports,po_external,po_interrupt]
  1037. ),(
  1038. idtok:_INTERNCONST;
  1039. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1040. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1041. pocall : pocall_none;
  1042. pooption : [po_internconst];
  1043. mutexclpocall : [];
  1044. mutexclpotype : [potype_operator];
  1045. mutexclpo : []
  1046. ),(
  1047. idtok:_INTERNPROC;
  1048. pd_flags : pd_implemen+pd_notobjintf;
  1049. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1050. pocall : pocall_internproc;
  1051. pooption : [];
  1052. mutexclpocall : [];
  1053. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1054. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_leftright]
  1055. ),(
  1056. idtok:_INTERRUPT;
  1057. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1058. handler : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
  1059. pocall : pocall_none;
  1060. pooption : [po_interrupt];
  1061. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,
  1062. pocall_inline,pocall_pascal,pocall_system,pocall_far16,pocall_fpccall];
  1063. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1064. mutexclpo : [po_external,po_leftright,po_clearstack]
  1065. ),(
  1066. idtok:_IOCHECK;
  1067. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1068. handler : nil;
  1069. pocall : pocall_none;
  1070. pooption : [po_iocheck];
  1071. mutexclpocall : [pocall_internproc];
  1072. mutexclpotype : [];
  1073. mutexclpo : [po_external]
  1074. ),(
  1075. idtok:_MESSAGE;
  1076. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1077. handler : {$ifdef FPCPROCVAR}@{$endif}pd_message;
  1078. pocall : pocall_none;
  1079. pooption : []; { can be po_msgstr or po_msgint }
  1080. mutexclpocall : [pocall_inline,pocall_internproc];
  1081. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1082. mutexclpo : [po_interrupt,po_external]
  1083. ),(
  1084. idtok:_NEAR;
  1085. pd_flags : pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1086. handler : {$ifdef FPCPROCVAR}@{$endif}pd_near;
  1087. pocall : pocall_none;
  1088. pooption : [];
  1089. mutexclpocall : [pocall_internproc];
  1090. mutexclpotype : [];
  1091. mutexclpo : []
  1092. ),(
  1093. idtok:_OVERLOAD;
  1094. pd_flags : pd_implemen+pd_interface+pd_body;
  1095. handler : {$ifdef FPCPROCVAR}@{$endif}pd_overload;
  1096. pocall : pocall_none;
  1097. pooption : [po_overload];
  1098. mutexclpocall : [pocall_internproc];
  1099. mutexclpotype : [];
  1100. mutexclpo : []
  1101. ),(
  1102. idtok:_OVERRIDE;
  1103. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1104. handler : {$ifdef FPCPROCVAR}@{$endif}pd_override;
  1105. pocall : pocall_none;
  1106. pooption : [po_overridingmethod,po_virtualmethod];
  1107. mutexclpocall : [pocall_inline,pocall_internproc];
  1108. mutexclpotype : [];
  1109. mutexclpo : [po_exports,po_external,po_interrupt]
  1110. ),(
  1111. idtok:_PASCAL;
  1112. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1113. handler : nil;
  1114. pocall : pocall_pascal;
  1115. pooption : [];
  1116. mutexclpocall : [];
  1117. mutexclpotype : [];
  1118. mutexclpo : [po_external]
  1119. ),(
  1120. idtok:_POPSTACK;
  1121. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1122. handler : nil;
  1123. pocall : pocall_none;
  1124. pooption : [po_clearstack];
  1125. mutexclpocall : [pocall_inline,pocall_internproc,pocall_stdcall];
  1126. mutexclpotype : [];
  1127. mutexclpo : [po_assembler,po_external]
  1128. ),(
  1129. idtok:_PUBLIC;
  1130. pd_flags : pd_implemen+pd_body+pd_global+pd_notobject+pd_notobjintf;
  1131. handler : nil;
  1132. pocall : pocall_none;
  1133. pooption : [];
  1134. mutexclpocall : [pocall_internproc,pocall_inline];
  1135. mutexclpotype : [];
  1136. mutexclpo : [po_external]
  1137. ),(
  1138. idtok:_REGISTER;
  1139. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1140. handler : nil;
  1141. pocall : pocall_register;
  1142. pooption : [];
  1143. mutexclpocall : [];
  1144. mutexclpotype : [];
  1145. mutexclpo : [po_external]
  1146. ),(
  1147. idtok:_REINTRODUCE;
  1148. pd_flags : pd_interface+pd_object;
  1149. handler : {$ifdef FPCPROCVAR}@{$endif}pd_reintroduce;
  1150. pocall : pocall_none;
  1151. pooption : [];
  1152. mutexclpocall : [];
  1153. mutexclpotype : [];
  1154. mutexclpo : []
  1155. ),(
  1156. idtok:_SAFECALL;
  1157. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1158. handler : nil;
  1159. pocall : pocall_safecall;
  1160. pooption : [];
  1161. mutexclpocall : [];
  1162. mutexclpotype : [];
  1163. mutexclpo : [po_external]
  1164. ),(
  1165. idtok:_SAVEREGISTERS;
  1166. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1167. handler : nil;
  1168. pocall : pocall_none;
  1169. pooption : [po_saveregisters];
  1170. mutexclpocall : [pocall_internproc];
  1171. mutexclpotype : [];
  1172. mutexclpo : [po_external]
  1173. ),(
  1174. idtok:_STATIC;
  1175. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1176. handler : {$ifdef FPCPROCVAR}@{$endif}pd_static;
  1177. pocall : pocall_none;
  1178. pooption : [po_staticmethod];
  1179. mutexclpocall : [pocall_inline,pocall_internproc];
  1180. mutexclpotype : [potype_constructor,potype_destructor];
  1181. mutexclpo : [po_external,po_interrupt,po_exports]
  1182. ),(
  1183. idtok:_STDCALL;
  1184. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1185. handler : nil;
  1186. pocall : pocall_stdcall;
  1187. pooption : [];
  1188. mutexclpocall : [];
  1189. mutexclpotype : [];
  1190. mutexclpo : [po_external]
  1191. ),(
  1192. idtok:_SYSCALL;
  1193. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  1194. handler : {$ifdef FPCPROCVAR}@{$endif}pd_syscall;
  1195. pocall : pocall_palmossyscall;
  1196. pooption : [];
  1197. mutexclpocall : [];
  1198. mutexclpotype : [];
  1199. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  1200. ),(
  1201. idtok:_SYSTEM;
  1202. pd_flags : pd_implemen+pd_notobjintf;
  1203. handler : nil;
  1204. pocall : pocall_system;
  1205. pooption : [];
  1206. mutexclpocall : [];
  1207. mutexclpotype : [];
  1208. mutexclpo : [po_external,po_assembler,po_interrupt]
  1209. ),(
  1210. idtok:_VIRTUAL;
  1211. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1212. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  1213. pocall : pocall_none;
  1214. pooption : [po_virtualmethod];
  1215. mutexclpocall : [pocall_inline,pocall_internproc];
  1216. mutexclpotype : [];
  1217. mutexclpo : [po_external,po_interrupt,po_exports]
  1218. ),(
  1219. idtok:_CPPDECL;
  1220. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1221. handler : nil;
  1222. pocall : pocall_cppdecl;
  1223. pooption : [po_savestdregs];
  1224. mutexclpocall : [];
  1225. mutexclpotype : [];
  1226. mutexclpo : [po_assembler,po_external]
  1227. ),(
  1228. idtok:_VARARGS;
  1229. pd_flags : pd_interface+pd_implemen+pd_procvar;
  1230. handler : nil;
  1231. pocall : pocall_none;
  1232. pooption : [po_varargs];
  1233. mutexclpocall : [pocall_internproc,pocall_stdcall,pocall_register,
  1234. pocall_inline,pocall_far16,pocall_fpccall];
  1235. mutexclpotype : [];
  1236. mutexclpo : [po_assembler,po_interrupt,po_leftright]
  1237. ),(
  1238. idtok:_COMPILERPROC;
  1239. pd_flags : pd_interface+pd_implemen+pd_body+pd_notobjintf;
  1240. handler : nil;
  1241. pocall : pocall_compilerproc;
  1242. pooption : [];
  1243. mutexclpocall : [];
  1244. mutexclpotype : [];
  1245. mutexclpo : [po_interrupt]
  1246. )
  1247. );
  1248. function is_proc_directive(tok:ttoken):boolean;
  1249. var
  1250. i : longint;
  1251. begin
  1252. is_proc_directive:=false;
  1253. for i:=1 to num_proc_directives do
  1254. if proc_direcdata[i].idtok=idtoken then
  1255. begin
  1256. is_proc_directive:=true;
  1257. exit;
  1258. end;
  1259. end;
  1260. function parse_proc_direc(var pdflags:word):boolean;
  1261. {
  1262. Parse the procedure directive, returns true if a correct directive is found
  1263. }
  1264. var
  1265. p : longint;
  1266. found : boolean;
  1267. name : stringid;
  1268. begin
  1269. parse_proc_direc:=false;
  1270. name:=tokeninfo^[idtoken].str;
  1271. found:=false;
  1272. { Hint directive? Then exit immediatly }
  1273. if (m_hintdirective in aktmodeswitches) then
  1274. begin
  1275. case idtoken of
  1276. _LIBRARY,
  1277. _PLATFORM,
  1278. _DEPRECATED :
  1279. exit;
  1280. end;
  1281. end;
  1282. { retrieve data for directive if found }
  1283. for p:=1 to num_proc_directives do
  1284. if proc_direcdata[p].idtok=idtoken then
  1285. begin
  1286. found:=true;
  1287. break;
  1288. end;
  1289. { Check if the procedure directive is known }
  1290. if not found then
  1291. begin
  1292. { parsing a procvar type the name can be any
  1293. next variable !! }
  1294. if (pdflags and (pd_procvar or pd_object))=0 then
  1295. Message1(parser_w_unknown_proc_directive_ignored,name);
  1296. exit;
  1297. end;
  1298. { static needs a special treatment }
  1299. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  1300. exit;
  1301. { Conflicts between directives ? }
  1302. if (aktprocdef.proctypeoption in proc_direcdata[p].mutexclpotype) or
  1303. (aktprocdef.proccalloption in proc_direcdata[p].mutexclpocall) or
  1304. ((aktprocdef.procoptions*proc_direcdata[p].mutexclpo)<>[]) then
  1305. begin
  1306. Message1(parser_e_proc_dir_conflict,name);
  1307. exit;
  1308. end;
  1309. { set calling convention }
  1310. if proc_direcdata[p].pocall<>pocall_none then
  1311. begin
  1312. if aktprocdef.proccalloption<>pocall_none then
  1313. begin
  1314. Message2(parser_w_proc_overriding_calling,
  1315. proccalloptionStr[aktprocdef.proccalloption],
  1316. proccalloptionStr[proc_direcdata[p].pocall]);
  1317. end;
  1318. aktprocdef.proccalloption:=proc_direcdata[p].pocall;
  1319. end;
  1320. if aktprocdef.deftype=procdef then
  1321. begin
  1322. { Check if the directive is only for objects }
  1323. if ((proc_direcdata[p].pd_flags and pd_object)<>0) and
  1324. not assigned(aktprocdef._class) then
  1325. exit;
  1326. { check if method and directive not for object public }
  1327. if ((proc_direcdata[p].pd_flags and pd_notobject)<>0) and
  1328. assigned(aktprocdef._class) then
  1329. exit;
  1330. { check if method and directive not for interface }
  1331. if ((proc_direcdata[p].pd_flags and pd_notobjintf)<>0) and
  1332. is_interface(aktprocdef._class) then
  1333. exit;
  1334. end;
  1335. { consume directive, and turn flag on }
  1336. consume(token);
  1337. parse_proc_direc:=true;
  1338. { Check the pd_flags if the directive should be allowed }
  1339. if ((pdflags and pd_interface)<>0) and
  1340. ((proc_direcdata[p].pd_flags and pd_interface)=0) then
  1341. begin
  1342. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1343. exit;
  1344. end;
  1345. if ((pdflags and pd_implemen)<>0) and
  1346. ((proc_direcdata[p].pd_flags and pd_implemen)=0) then
  1347. begin
  1348. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1349. exit;
  1350. end;
  1351. if ((pdflags and pd_procvar)<>0) and
  1352. ((proc_direcdata[p].pd_flags and pd_procvar)=0) then
  1353. begin
  1354. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1355. exit;
  1356. end;
  1357. { Return the new pd_flags }
  1358. if (proc_direcdata[p].pd_flags and pd_body)=0 then
  1359. pdflags:=pdflags and (not pd_body);
  1360. if (proc_direcdata[p].pd_flags and pd_global)<>0 then
  1361. pdflags:=pdflags or pd_global;
  1362. { Add the correct flag }
  1363. aktprocdef.procoptions:=aktprocdef.procoptions+proc_direcdata[p].pooption;
  1364. { Call the handler }
  1365. if pointer({$ifndef FPCPROCVAR}@{$endif}proc_direcdata[p].handler)<>nil then
  1366. proc_direcdata[p].handler{$ifdef FPCPROCVAR}(){$endif};
  1367. end;
  1368. procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
  1369. begin
  1370. { set the default calling convention }
  1371. if def.proccalloption=pocall_none then
  1372. def.proccalloption:=aktdefproccall;
  1373. case def.proccalloption of
  1374. pocall_cdecl :
  1375. begin
  1376. { use popstack and save std registers }
  1377. include(def.procoptions,po_clearstack);
  1378. include(def.procoptions,po_savestdregs);
  1379. { set mangledname }
  1380. if (def.deftype=procdef) then
  1381. begin
  1382. if not tprocdef(def).has_mangledname then
  1383. tprocdef(def).setmangledname(target_info.Cprefix+sym.realname);
  1384. if not assigned(tprocdef(def).parast) then
  1385. internalerror(200110234);
  1386. { do not copy on local !! }
  1387. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
  1388. { Adjust alignment to match cdecl or stdcall }
  1389. tprocdef(def).parast.dataalignment:=std_param_align;
  1390. end;
  1391. end;
  1392. pocall_cppdecl :
  1393. begin
  1394. if not assigned(sym) then
  1395. internalerror(200110231);
  1396. { use popstack and save std registers }
  1397. include(def.procoptions,po_clearstack);
  1398. include(def.procoptions,po_savestdregs);
  1399. { set mangledname }
  1400. if (def.deftype=procdef) then
  1401. begin
  1402. if not tprocdef(def).has_mangledname then
  1403. tprocdef(def).setmangledname(target_info.Cprefix+tprocdef(def).cplusplusmangledname);
  1404. if not assigned(tprocdef(def).parast) then
  1405. internalerror(200110235);
  1406. { do not copy on local !! }
  1407. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
  1408. { Adjust alignment to match cdecl or stdcall }
  1409. tprocdef(def).parast.dataalignment:=std_param_align;
  1410. end;
  1411. end;
  1412. pocall_stdcall :
  1413. begin
  1414. include(def.procoptions,po_savestdregs);
  1415. if (def.deftype=procdef) then
  1416. begin
  1417. if not assigned(tprocdef(def).parast) then
  1418. internalerror(200110236);
  1419. { Adjust alignment to match cdecl or stdcall }
  1420. tprocdef(def).parast.dataalignment:=std_param_align;
  1421. end;
  1422. end;
  1423. pocall_safecall :
  1424. begin
  1425. include(def.procoptions,po_savestdregs);
  1426. end;
  1427. pocall_compilerproc :
  1428. begin
  1429. if (not assigned(sym)) or
  1430. (def.deftype<>procdef) then
  1431. internalerror(200110232);
  1432. tprocdef(def).setmangledname(lower(sym.name));
  1433. end;
  1434. pocall_pascal :
  1435. begin
  1436. include(def.procoptions,po_leftright);
  1437. end;
  1438. pocall_register :
  1439. begin
  1440. Message1(parser_w_proc_directive_ignored,'REGISTER');
  1441. end;
  1442. pocall_far16 :
  1443. begin
  1444. { Temporary stub, must be rewritten to support OS/2 far16 }
  1445. Message1(parser_w_proc_directive_ignored,'FAR16');
  1446. end;
  1447. pocall_system :
  1448. begin
  1449. include(def.procoptions,po_clearstack);
  1450. if (not assigned(sym)) or
  1451. (def.deftype<>procdef) then
  1452. internalerror(200110233);
  1453. if not tprocdef(def).has_mangledname then
  1454. tprocdef(def).setmangledname(sym.realname);
  1455. end;
  1456. pocall_palmossyscall :
  1457. begin
  1458. { use popstack and save std registers }
  1459. include(def.procoptions,po_clearstack);
  1460. include(def.procoptions,po_savestdregs);
  1461. if (def.deftype=procdef) then
  1462. begin
  1463. if not assigned(tprocdef(def).parast) then
  1464. internalerror(200110236);
  1465. { do not copy on local !! }
  1466. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
  1467. { Adjust positions of args for cdecl or stdcall }
  1468. tprocdef(def).parast.dataalignment:=std_param_align;
  1469. end;
  1470. end;
  1471. pocall_inline :
  1472. begin
  1473. if not(cs_support_inline in aktmoduleswitches) then
  1474. begin
  1475. Message(parser_e_proc_inline_not_supported);
  1476. def.proccalloption:=pocall_fpccall;
  1477. end;
  1478. end;
  1479. end;
  1480. { add mangledname to external list }
  1481. if (def.deftype=procdef) and
  1482. (po_external in def.procoptions) and
  1483. target_info.DllScanSupported then
  1484. current_module.externals.insert(tExternalsItem.create(tprocdef(def).mangledname));
  1485. end;
  1486. procedure calc_parasymtable_addresses(def:tprocdef);
  1487. var
  1488. lastps,
  1489. highps,ps : tsym;
  1490. st : tsymtable;
  1491. begin
  1492. st:=def.parast;
  1493. if po_leftright in def.procoptions then
  1494. begin
  1495. { pushed in reversed order, left to right }
  1496. highps:=nil;
  1497. lastps:=nil;
  1498. while assigned(st.symindex.first) and (lastps<>tsym(st.symindex.first)) do
  1499. begin
  1500. ps:=tsym(st.symindex.first);
  1501. while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
  1502. ps:=tsym(ps.indexnext);
  1503. if ps.typ=varsym then
  1504. begin
  1505. { Wait with inserting the high value, it needs to be inserted
  1506. after the corresponding parameter }
  1507. if Copy(ps.name,1,4)='high' then
  1508. highps:=ps
  1509. else
  1510. begin
  1511. st.insertvardata(ps);
  1512. { add also the high tree if it was saved }
  1513. if assigned(highps) then
  1514. begin
  1515. st.insertvardata(highps);
  1516. highps:=nil;
  1517. end;
  1518. end;
  1519. end;
  1520. lastps:=ps;
  1521. end;
  1522. if assigned(highps) then
  1523. internalerror(200208257);
  1524. end
  1525. else
  1526. begin
  1527. { pushed in normal order, right to left }
  1528. ps:=tsym(st.symindex.first);
  1529. while assigned(ps) do
  1530. begin
  1531. if ps.typ=varsym then
  1532. st.insertvardata(ps);
  1533. ps:=tsym(ps.indexnext);
  1534. end;
  1535. end;
  1536. end;
  1537. procedure parse_proc_directives(var pdflags:word);
  1538. {
  1539. Parse the procedure directives. It does not matter if procedure directives
  1540. are written using ;procdir; or ['procdir'] syntax.
  1541. }
  1542. var
  1543. res : boolean;
  1544. begin
  1545. while token in [_ID,_LECKKLAMMER] do
  1546. begin
  1547. if try_to_consume(_LECKKLAMMER) then
  1548. begin
  1549. repeat
  1550. parse_proc_direc(pdflags);
  1551. until not try_to_consume(_COMMA);
  1552. consume(_RECKKLAMMER);
  1553. { we always expect at least '[];' }
  1554. res:=true;
  1555. end
  1556. else
  1557. begin
  1558. res:=parse_proc_direc(pdflags);
  1559. end;
  1560. { A procedure directive normally followed by a semicolon, but in
  1561. a const section we should stop when _EQUAL is found }
  1562. if res then
  1563. begin
  1564. if (block_type=bt_const) and
  1565. (token=_EQUAL) then
  1566. break;
  1567. { support procedure proc;stdcall export; in Delphi mode only }
  1568. if not((m_delphi in aktmodeswitches) and
  1569. is_proc_directive(token)) then
  1570. consume(_SEMICOLON);
  1571. end
  1572. else
  1573. break;
  1574. end;
  1575. handle_calling_convention(aktprocsym,aktprocdef);
  1576. { calculate addresses in parasymtable }
  1577. if aktprocdef.deftype=procdef then
  1578. calc_parasymtable_addresses(aktprocdef);
  1579. end;
  1580. procedure parse_var_proc_directives(var sym : tsym);
  1581. var
  1582. pdflags : word;
  1583. oldsym : tprocsym;
  1584. olddef : tprocdef;
  1585. pd : tabstractprocdef;
  1586. begin
  1587. oldsym:=aktprocsym;
  1588. olddef:=aktprocdef;
  1589. pdflags:=pd_procvar;
  1590. { we create a temporary aktprocsym to read the directives }
  1591. aktprocsym:=tprocsym.create(sym.name);
  1592. case sym.typ of
  1593. varsym :
  1594. pd:=tabstractprocdef(tvarsym(sym).vartype.def);
  1595. typedconstsym :
  1596. pd:=tabstractprocdef(ttypedconstsym(sym).typedconsttype.def);
  1597. typesym :
  1598. pd:=tabstractprocdef(ttypesym(sym).restype.def);
  1599. else
  1600. internalerror(994932432);
  1601. end;
  1602. if pd.deftype<>procvardef then
  1603. internalerror(994932433);
  1604. tabstractprocdef(aktprocdef):=pd;
  1605. { names should never be used anyway }
  1606. inc(lexlevel);
  1607. parse_proc_directives(pdflags);
  1608. dec(lexlevel);
  1609. aktprocsym.free;
  1610. aktprocsym:=oldsym;
  1611. aktprocdef:=olddef;
  1612. end;
  1613. procedure parse_object_proc_directives(var sym : tprocsym);
  1614. var
  1615. pdflags : word;
  1616. begin
  1617. pdflags:=pd_object;
  1618. inc(lexlevel);
  1619. parse_proc_directives(pdflags);
  1620. dec(lexlevel);
  1621. if (po_containsself in aktprocdef.procoptions) and
  1622. (([po_msgstr,po_msgint]*aktprocdef.procoptions)=[]) then
  1623. Message(parser_e_self_in_non_message_handler);
  1624. end;
  1625. function proc_add_definition(aprocsym:tprocsym;var aprocdef : tprocdef) : boolean;
  1626. {
  1627. Add definition aprocdef to the overloaded definitions of aprocsym. If a
  1628. forwarddef is found and reused it returns true
  1629. }
  1630. var
  1631. hd : tprocdef;
  1632. pdl : pprocdeflist;
  1633. ad,fd : tsym;
  1634. forwardfound : boolean;
  1635. begin
  1636. forwardfound:=false;
  1637. { check overloaded functions if the same function already exists }
  1638. pdl:=aprocsym.defs;
  1639. while assigned(pdl) do
  1640. begin
  1641. hd:=pdl^.def;
  1642. { check the parameters, for delphi/tp it is possible to
  1643. leave the parameters away in the implementation (forwarddef=false).
  1644. But for an overload declared function this is not allowed }
  1645. if { check if empty implementation arguments match is allowed }
  1646. (
  1647. not(m_repeat_forward in aktmodeswitches) and
  1648. not(aprocdef.forwarddef) and
  1649. (aprocdef.maxparacount=0) and
  1650. not(po_overload in hd.procoptions)
  1651. ) or
  1652. { check arguments }
  1653. (
  1654. equal_paras(aprocdef.para,hd.para,cp_none) and
  1655. { for operators equal_paras is not enough !! }
  1656. ((aprocdef.proctypeoption<>potype_operator) or (optoken<>_ASSIGNMENT) or
  1657. is_equal(hd.rettype.def,aprocdef.rettype.def))
  1658. ) then
  1659. begin
  1660. { Check if we've found the forwarddef, if found then
  1661. we need to update the forward def with the current
  1662. implementation settings }
  1663. if hd.forwarddef then
  1664. begin
  1665. forwardfound:=true;
  1666. { Check if the procedure type and return type are correct,
  1667. also the parameters must match also with the type }
  1668. if (hd.proctypeoption<>aprocdef.proctypeoption) or
  1669. (
  1670. (m_repeat_forward in aktmodeswitches) and
  1671. (
  1672. not(is_equal(hd.rettype.def,aprocdef.rettype.def) and
  1673. ((aprocdef.maxparacount=0) or
  1674. equal_paras(aprocdef.para,hd.para,cp_all))
  1675. )
  1676. )
  1677. ) then
  1678. begin
  1679. MessagePos1(aprocdef.fileinfo,parser_e_header_dont_match_forward,
  1680. aprocdef.fullprocname);
  1681. break;
  1682. end;
  1683. { Check if both are declared forward }
  1684. if hd.forwarddef and aprocdef.forwarddef then
  1685. begin
  1686. MessagePos1(aprocdef.fileinfo,parser_e_function_already_declared_public_forward,
  1687. aprocdef.fullprocname);
  1688. end;
  1689. { internconst or internproc only need to be defined once }
  1690. if (hd.proccalloption=pocall_internproc) then
  1691. aprocdef.proccalloption:=hd.proccalloption
  1692. else
  1693. if (aprocdef.proccalloption=pocall_internproc) then
  1694. hd.proccalloption:=aprocdef.proccalloption;
  1695. if (po_internconst in hd.procoptions) then
  1696. include(aprocdef.procoptions,po_internconst)
  1697. else if (po_internconst in aprocdef.procoptions) then
  1698. include(hd.procoptions,po_internconst);
  1699. { Check calling convention }
  1700. if (hd.proccalloption<>aprocdef.proccalloption) then
  1701. begin
  1702. { For delphi check if the current implementation has no proccalloption, then
  1703. take the options from the interface }
  1704. if not(m_delphi in aktmodeswitches) or
  1705. (aprocdef.proccalloption<>pocall_none) then
  1706. MessagePos(aprocdef.fileinfo,parser_e_call_convention_dont_match_forward);
  1707. { restore interface settings }
  1708. aprocdef.proccalloption:=hd.proccalloption;
  1709. aprocdef.has_mangledname:=hd.has_mangledname;
  1710. if hd.has_mangledname then
  1711. aprocdef.setmangledname(hd.mangledname);
  1712. end;
  1713. { Check manglednames }
  1714. if (m_repeat_forward in aktmodeswitches) or
  1715. aprocdef.haspara then
  1716. begin
  1717. { If mangled names are equal then they have the same amount of arguments }
  1718. { We can check the names of the arguments }
  1719. { both symtables are in the same order from left to right }
  1720. ad:=tsym(hd.parast.symindex.first);
  1721. fd:=tsym(aprocdef.parast.symindex.first);
  1722. repeat
  1723. { skip default parameter constsyms }
  1724. while assigned(ad) and (ad.typ<>varsym) do
  1725. ad:=tsym(ad.indexnext);
  1726. while assigned(fd) and (fd.typ<>varsym) do
  1727. fd:=tsym(fd.indexnext);
  1728. { stop when one of the two lists is at the end }
  1729. if not assigned(ad) or not assigned(fd) then
  1730. break;
  1731. if (ad.name<>fd.name) then
  1732. begin
  1733. MessagePos3(aprocdef.fileinfo,parser_e_header_different_var_names,
  1734. aprocsym.name,ad.name,fd.name);
  1735. break;
  1736. end;
  1737. ad:=tsym(ad.indexnext);
  1738. fd:=tsym(fd.indexnext);
  1739. until false;
  1740. if assigned(ad) or assigned(fd) then
  1741. internalerror(200204178);
  1742. end;
  1743. { Everything is checked, now we can update the forward declaration
  1744. with the new data from the implementation }
  1745. hd.forwarddef:=aprocdef.forwarddef;
  1746. hd.hasforward:=true;
  1747. hd.parast.address_fixup:=aprocdef.parast.address_fixup;
  1748. hd.procoptions:=hd.procoptions+aprocdef.procoptions;
  1749. if hd.extnumber=65535 then
  1750. hd.extnumber:=aprocdef.extnumber;
  1751. while not aprocdef.aliasnames.empty do
  1752. hd.aliasnames.insert(aprocdef.aliasnames.getfirst);
  1753. { update mangledname if the implementation has a fixed mangledname set }
  1754. if aprocdef.has_mangledname then
  1755. begin
  1756. { rename also asmsymbol first, because the name can already be used }
  1757. objectlibrary.renameasmsymbol(hd.mangledname,aprocdef.mangledname);
  1758. { update the mangledname }
  1759. hd.has_mangledname:=true;
  1760. hd.setmangledname(aprocdef.mangledname);
  1761. end;
  1762. { for compilerproc defines we need to rename and update the
  1763. symbolname to lowercase }
  1764. if (aprocdef.proccalloption=pocall_compilerproc) then
  1765. begin
  1766. { rename to lowercase so users can't access it }
  1767. aprocsym.owner.rename(aprocsym.name,lower(aprocsym.name));
  1768. { also update the realname that is stored in the ppu }
  1769. stringdispose(aprocsym._realname);
  1770. aprocsym._realname:=stringdup('$'+aprocsym.name);
  1771. { the mangeled name is already changed by the pd_compilerproc }
  1772. { handler. It must be done immediately because if we have a }
  1773. { call to a compilerproc before it's implementation is }
  1774. { encountered, it must already use the new mangled name (JM) }
  1775. end;
  1776. { return the forwarddef }
  1777. aprocdef:=hd;
  1778. end
  1779. else
  1780. begin
  1781. { abstract methods aren't forward defined, but this }
  1782. { needs another error message }
  1783. if (po_abstractmethod in hd.procoptions) then
  1784. MessagePos(aprocdef.fileinfo,parser_e_abstract_no_definition)
  1785. else
  1786. MessagePos(aprocdef.fileinfo,parser_e_overloaded_have_same_parameters);
  1787. end;
  1788. { we found one proc with the same arguments, there are no others
  1789. so we can stop }
  1790. break;
  1791. end;
  1792. { check for allowing overload directive }
  1793. if not(m_fpc in aktmodeswitches) then
  1794. begin
  1795. { overload directive turns on overloading }
  1796. if ((po_overload in aprocdef.procoptions) or
  1797. (po_overload in hd.procoptions)) then
  1798. begin
  1799. { check if all procs have overloading, but not if the proc was
  1800. already declared forward, then the check is already done }
  1801. if not(hd.hasforward or
  1802. (aprocdef.forwarddef<>hd.forwarddef) or
  1803. ((po_overload in aprocdef.procoptions) and
  1804. (po_overload in hd.procoptions))) then
  1805. begin
  1806. MessagePos1(aprocdef.fileinfo,parser_e_no_overload_for_all_procs,aprocsym.realname);
  1807. break;
  1808. end;
  1809. end
  1810. else
  1811. begin
  1812. if not(hd.forwarddef) then
  1813. begin
  1814. MessagePos(aprocdef.fileinfo,parser_e_procedure_overloading_is_off);
  1815. break;
  1816. end;
  1817. end;
  1818. end; { equal arguments }
  1819. { try next overloaded }
  1820. pdl:=pdl^.next;
  1821. end;
  1822. { if we didn't reuse a forwarddef then we add the procdef to the overloaded
  1823. list }
  1824. if not forwardfound then
  1825. begin
  1826. aprocsym.addprocdef(aprocdef);
  1827. { add overloadnumber for unique naming, the overloadcount is
  1828. counted per module and 0 for the first procedure }
  1829. aprocdef.overloadnumber:=aprocsym.overloadcount;
  1830. inc(aprocsym.overloadcount);
  1831. end;
  1832. { insert otsym only in the right symtable }
  1833. if ((procinfo.flags and pi_operator)<>0) and
  1834. assigned(otsym) then
  1835. begin
  1836. if not parse_only then
  1837. begin
  1838. if paramanager.ret_in_param(aprocdef.rettype.def) then
  1839. begin
  1840. aprocdef.parast.insert(otsym);
  1841. { this allows to read the funcretoffset }
  1842. otsym.address:=-4;
  1843. otsym.varspez:=vs_var;
  1844. end
  1845. else
  1846. begin
  1847. aprocdef.localst.insert(otsym);
  1848. aprocdef.localst.insertvardata(otsym);
  1849. end;
  1850. end
  1851. else
  1852. begin
  1853. { this is not required anymore }
  1854. otsym.free;
  1855. otsym:=nil;
  1856. end;
  1857. end;
  1858. paramanager.create_param_loc_info(aprocdef);
  1859. proc_add_definition:=forwardfound;
  1860. end;
  1861. end.
  1862. {
  1863. $Log$
  1864. Revision 1.68 2002-08-25 19:25:20 peter
  1865. * sym.insert_in_data removed
  1866. * symtable.insertvardata/insertconstdata added
  1867. * removed insert_in_data call from symtable.insert, it needs to be
  1868. called separatly. This allows to deref the address calculation
  1869. * procedures now calculate the parast addresses after the procedure
  1870. directives are parsed. This fixes the cdecl parast problem
  1871. * push_addr_param has an extra argument that specifies if cdecl is used
  1872. or not
  1873. Revision 1.67 2002/08/25 11:33:06 peter
  1874. * also check the paratypes when a forward was found
  1875. Revision 1.66 2002/08/19 19:36:44 peter
  1876. * More fixes for cross unit inlining, all tnodes are now implemented
  1877. * Moved pocall_internconst to po_internconst because it is not a
  1878. calling type at all and it conflicted when inlining of these small
  1879. functions was requested
  1880. Revision 1.65 2002/08/18 20:06:24 peter
  1881. * inlining is now also allowed in interface
  1882. * renamed write/load to ppuwrite/ppuload
  1883. * tnode storing in ppu
  1884. * nld,ncon,nbas are already updated for storing in ppu
  1885. Revision 1.64 2002/08/17 09:23:39 florian
  1886. * first part of procinfo rewrite
  1887. Revision 1.63 2002/08/11 14:32:27 peter
  1888. * renamed current_library to objectlibrary
  1889. Revision 1.62 2002/08/11 13:24:12 peter
  1890. * saving of asmsymbols in ppu supported
  1891. * asmsymbollist global is removed and moved into a new class
  1892. tasmlibrarydata that will hold the info of a .a file which
  1893. corresponds with a single module. Added librarydata to tmodule
  1894. to keep the library info stored for the module. In the future the
  1895. objectfiles will also be stored to the tasmlibrarydata class
  1896. * all getlabel/newasmsymbol and friends are moved to the new class
  1897. Revision 1.61 2002/07/26 21:15:40 florian
  1898. * rewrote the system handling
  1899. Revision 1.60 2002/07/20 11:57:55 florian
  1900. * types.pas renamed to defbase.pas because D6 contains a types
  1901. unit so this would conflicts if D6 programms are compiled
  1902. + Willamette/SSE2 instructions to assembler added
  1903. Revision 1.59 2002/07/11 14:41:28 florian
  1904. * start of the new generic parameter handling
  1905. Revision 1.58 2002/07/01 18:46:25 peter
  1906. * internal linker
  1907. * reorganized aasm layer
  1908. Revision 1.57 2002/05/18 13:34:12 peter
  1909. * readded missing revisions
  1910. Revision 1.56 2002/05/16 19:46:42 carl
  1911. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1912. + try to fix temp allocation (still in ifdef)
  1913. + generic constructor calls
  1914. + start of tassembler / tmodulebase class cleanup
  1915. Revision 1.54 2002/05/12 16:53:08 peter
  1916. * moved entry and exitcode to ncgutil and cgobj
  1917. * foreach gets extra argument for passing local data to the
  1918. iterator function
  1919. * -CR checks also class typecasts at runtime by changing them
  1920. into as
  1921. * fixed compiler to cycle with the -CR option
  1922. * fixed stabs with elf writer, finally the global variables can
  1923. be watched
  1924. * removed a lot of routines from cga unit and replaced them by
  1925. calls to cgobj
  1926. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1927. u32bit then the other is typecasted also to u32bit without giving
  1928. a rangecheck warning/error.
  1929. * fixed pascal calling method with reversing also the high tree in
  1930. the parast, detected by tcalcst3 test
  1931. Revision 1.53 2002/04/21 19:02:04 peter
  1932. * removed newn and disposen nodes, the code is now directly
  1933. inlined from pexpr
  1934. * -an option that will write the secondpass nodes to the .s file, this
  1935. requires EXTDEBUG define to actually write the info
  1936. * fixed various internal errors and crashes due recent code changes
  1937. Revision 1.52 2002/04/20 21:32:24 carl
  1938. + generic FPC_CHECKPOINTER
  1939. + first parameter offset in stack now portable
  1940. * rename some constants
  1941. + move some cpu stuff to other units
  1942. - remove unused constents
  1943. * fix stacksize for some targets
  1944. * fix generic size problems which depend now on EXTEND_SIZE constant
  1945. Revision 1.51 2002/04/20 15:27:05 carl
  1946. - remove ifdef i386 define
  1947. Revision 1.50 2002/04/19 15:46:02 peter
  1948. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  1949. in most cases and not written to the ppu
  1950. * add mangeledname_prefix() routine to generate the prefix of
  1951. manglednames depending on the current procedure, object and module
  1952. * removed static procprefix since the mangledname is now build only
  1953. on demand from tprocdef.mangledname
  1954. Revision 1.49 2002/04/15 19:00:33 carl
  1955. + target_info.size_of_pointer -> pointer_Size
  1956. Revision 1.48 2002/03/29 13:29:32 peter
  1957. * fixed memory corruption created by previous fix
  1958. Revision 1.47 2002/03/29 11:23:24 michael
  1959. + Patch from Pavel Ozerski
  1960. Revision 1.46 2002/01/24 18:25:49 peter
  1961. * implicit result variable generation for assembler routines
  1962. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  1963. Revision 1.45 2002/01/09 07:38:03 michael
  1964. + Patch from peter for library imports
  1965. Revision 1.44 2002/01/06 21:54:07 peter
  1966. * fixed external <dll> name <c-name> manglednames
  1967. }