pdecsub.pas 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  20. interface
  21. uses
  22. cobjects,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. function check_identical_proc(var p : pprocdef) : boolean;
  34. procedure parameter_dec(aktprocdef:pabstractprocdef);
  35. procedure parse_proc_directives(Anames:Pstringcontainer;var pdflags:word);
  36. procedure parse_proc_head(options:tproctypeoption);
  37. procedure parse_proc_dec;
  38. procedure parse_var_proc_directives(var sym : psym);
  39. procedure parse_object_proc_directives(var sym : pprocsym);
  40. implementation
  41. uses
  42. {$ifdef delphi}
  43. sysutils,
  44. {$else delphi}
  45. strings,
  46. {$endif delphi}
  47. { common }
  48. cutils,
  49. { global }
  50. globtype,globals,verbose,
  51. systems,cpuinfo,
  52. { aasm }
  53. aasm,
  54. { symtable }
  55. symbase,symtable,types,
  56. {$ifdef GDB}
  57. gdb,
  58. {$endif}
  59. { pass 1 }
  60. node,pass_1,htypechk,
  61. nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
  62. { parser }
  63. fmodule,scanner,
  64. pbase,pexpr,ptype,pdecl,
  65. { linking }
  66. import,gendef,
  67. { codegen }
  68. {$ifdef newcg}
  69. cgbase
  70. {$else}
  71. hcodegen
  72. {$endif}
  73. ;
  74. procedure parameter_dec(aktprocdef:pabstractprocdef);
  75. {
  76. handle_procvar needs the same changes
  77. }
  78. var
  79. is_procvar : boolean;
  80. sc : Pstringcontainer;
  81. s : string;
  82. hpos,
  83. storetokenpos : tfileposinfo;
  84. tt : ttype;
  85. hvs,
  86. vs : Pvarsym;
  87. hs1,hs2 : string;
  88. varspez : Tvarspez;
  89. inserthigh : boolean;
  90. pdefaultvalue : pconstsym;
  91. defaultrequired : boolean;
  92. begin
  93. { reset }
  94. defaultrequired:=false;
  95. { parsing a proc or procvar ? }
  96. is_procvar:=(aktprocdef^.deftype=procvardef);
  97. consume(_LKLAMMER);
  98. inc(testcurobject);
  99. repeat
  100. if try_to_consume(_VAR) then
  101. varspez:=vs_var
  102. else
  103. if try_to_consume(_CONST) then
  104. varspez:=vs_const
  105. else
  106. if try_to_consume(_OUT) then
  107. varspez:=vs_out
  108. else
  109. varspez:=vs_value;
  110. inserthigh:=false;
  111. pdefaultvalue:=nil;
  112. tt.reset;
  113. { self is only allowed in procvars and class methods }
  114. if (idtoken=_SELF) and
  115. (is_procvar or
  116. (assigned(procinfo^._class) and is_class(procinfo^._class))) then
  117. begin
  118. if not is_procvar then
  119. begin
  120. {$ifndef UseNiceNames}
  121. hs2:=hs2+'$'+'self';
  122. {$else UseNiceNames}
  123. hs2:=hs2+tostr(length('self'))+'self';
  124. {$endif UseNiceNames}
  125. vs:=new(Pvarsym,initdef('@',procinfo^._class));
  126. vs^.varspez:=vs_var;
  127. { insert the sym in the parasymtable }
  128. pprocdef(aktprocdef)^.parast^.insert(vs);
  129. include(aktprocdef^.procoptions,po_containsself);
  130. inc(procinfo^.selfpointer_offset,vs^.address);
  131. end;
  132. consume(idtoken);
  133. consume(_COLON);
  134. single_type(tt,hs1,false);
  135. aktprocdef^.concatpara(tt,vs_value,nil);
  136. { check the types for procedures only }
  137. if not is_procvar then
  138. CheckTypes(tt.def,procinfo^._class);
  139. end
  140. else
  141. begin
  142. { read identifiers }
  143. sc:=idlist;
  144. {$ifdef fixLeaksOnError}
  145. strContStack.push(sc);
  146. {$endif fixLeaksOnError}
  147. { read type declaration, force reading for value and const paras }
  148. if (token=_COLON) or (varspez=vs_value) then
  149. begin
  150. consume(_COLON);
  151. { check for an open array }
  152. if token=_ARRAY then
  153. begin
  154. consume(_ARRAY);
  155. consume(_OF);
  156. { define range and type of range }
  157. tt.setdef(new(Parraydef,init(0,-1,s32bitdef)));
  158. { array of const ? }
  159. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  160. begin
  161. consume(_CONST);
  162. srsym:=nil;
  163. getsymonlyin(systemunit,'TVARREC');
  164. if not assigned(srsym) then
  165. InternalError(1234124);
  166. Parraydef(tt.def)^.elementtype:=ptypesym(srsym)^.restype;
  167. Parraydef(tt.def)^.IsArrayOfConst:=true;
  168. hs1:='array_of_const';
  169. end
  170. else
  171. begin
  172. { define field type }
  173. single_type(parraydef(tt.def)^.elementtype,hs1,false);
  174. hs1:='array_of_'+hs1;
  175. end;
  176. inserthigh:=true;
  177. end
  178. else
  179. begin
  180. { open string ? }
  181. if (varspez=vs_var) and
  182. (
  183. (
  184. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  185. (cs_openstring in aktmoduleswitches) and
  186. not(cs_ansistrings in aktlocalswitches)
  187. ) or
  188. (idtoken=_OPENSTRING)) then
  189. begin
  190. consume(token);
  191. tt.setdef(openshortstringdef);
  192. hs1:='openstring';
  193. inserthigh:=true;
  194. end
  195. else
  196. begin
  197. { everything else }
  198. single_type(tt,hs1,false);
  199. end;
  200. { default parameter }
  201. if (m_default_para in aktmodeswitches) then
  202. begin
  203. if try_to_consume(_EQUAL) then
  204. begin
  205. s:=sc^.get_with_tokeninfo(hpos);
  206. if not sc^.empty then
  207. Comment(V_Error,'default value only allowed for one parameter');
  208. sc^.insert_with_tokeninfo(s,hpos);
  209. { prefix 'def' to the parameter name }
  210. pdefaultvalue:=ReadConstant('$def'+Upper(s),hpos);
  211. if assigned(pdefaultvalue) then
  212. pprocdef(aktprocdef)^.parast^.insert(pdefaultvalue);
  213. defaultrequired:=true;
  214. end
  215. else
  216. begin
  217. if defaultrequired then
  218. Comment(V_Error,'default parameter required');
  219. end;
  220. end;
  221. end;
  222. end
  223. else
  224. begin
  225. {$ifndef UseNiceNames}
  226. hs1:='$$$';
  227. {$else UseNiceNames}
  228. hs1:='var';
  229. {$endif UseNiceNames}
  230. tt.setdef(cformaldef);
  231. end;
  232. if not is_procvar then
  233. hs2:=pprocdef(aktprocdef)^.mangledname;
  234. storetokenpos:=akttokenpos;
  235. while not sc^.empty do
  236. begin
  237. s:=sc^.get_with_tokeninfo(akttokenpos);
  238. aktprocdef^.concatpara(tt,varspez,pdefaultvalue);
  239. { For proc vars we only need the definitions }
  240. if not is_procvar then
  241. begin
  242. {$ifndef UseNiceNames}
  243. hs2:=hs2+'$'+hs1;
  244. {$else UseNiceNames}
  245. hs2:=hs2+tostr(length(hs1))+hs1;
  246. {$endif UseNiceNames}
  247. vs:=new(pvarsym,init(s,tt));
  248. vs^.varspez:=varspez;
  249. { we have to add this to avoid var param to be in registers !!!}
  250. { I don't understand the comment above, }
  251. { but I suppose the comment is wrong and }
  252. { it means that the address of var parameters can be placed }
  253. { in a register (FK) }
  254. if (varspez in [vs_var,vs_const,vs_out]) and push_addr_param(tt.def) then
  255. include(vs^.varoptions,vo_regable);
  256. { insert the sym in the parasymtable }
  257. pprocdef(aktprocdef)^.parast^.insert(vs);
  258. { do we need a local copy? Then rename the varsym, do this after the
  259. insert so the dup id checking is done correctly }
  260. if (varspez=vs_value) and
  261. push_addr_param(tt.def) and
  262. not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
  263. pprocdef(aktprocdef)^.parast^.rename(vs^.name,'val'+vs^.name);
  264. { also need to push a high value? }
  265. if inserthigh then
  266. begin
  267. hvs:=new(Pvarsym,initdef('$high'+Upper(s),s32bitdef));
  268. hvs^.varspez:=vs_const;
  269. pprocdef(aktprocdef)^.parast^.insert(hvs);
  270. end;
  271. end;
  272. end;
  273. {$ifdef fixLeaksOnError}
  274. if PStringContainer(strContStack.pop) <> sc then
  275. writeln('problem with strContStack in pdecl (1)');
  276. {$endif fixLeaksOnError}
  277. dispose(sc,done);
  278. akttokenpos:=storetokenpos;
  279. end;
  280. { set the new mangled name }
  281. if not is_procvar then
  282. pprocdef(aktprocdef)^.setmangledname(hs2);
  283. until not try_to_consume(_SEMICOLON);
  284. dec(testcurobject);
  285. consume(_RKLAMMER);
  286. end;
  287. procedure parse_proc_head(options:tproctypeoption);
  288. var orgsp,sp:stringid;
  289. pd:Pprocdef;
  290. paramoffset:longint;
  291. sym:Psym;
  292. hs:string;
  293. st : psymtable;
  294. overloaded_level:word;
  295. storepos,procstartfilepos : tfileposinfo;
  296. i: longint;
  297. begin
  298. { Save the position where this procedure really starts and set col to 1 which
  299. looks nicer }
  300. procstartfilepos:=akttokenpos;
  301. { procstartfilepos.column:=1; I do not agree here !!
  302. lets keep excat position PM }
  303. if (options=potype_operator) then
  304. begin
  305. sp:=overloaded_names[optoken];
  306. orgsp:=sp;
  307. end
  308. else
  309. begin
  310. sp:=pattern;
  311. orgsp:=orgpattern;
  312. consume(_ID);
  313. end;
  314. { examine interface map: function/procedure iname.functionname=locfuncname }
  315. if parse_only and assigned(procinfo^._class) and
  316. assigned(procinfo^._class^.implementedinterfaces) and
  317. (procinfo^._class^.implementedinterfaces^.count>0) and
  318. try_to_consume(_POINT) then
  319. begin
  320. storepos:=akttokenpos;
  321. akttokenpos:=procstartfilepos;
  322. { get interface syms}
  323. getsym(sp,true);
  324. sym:=srsym;
  325. akttokenpos:=storepos;
  326. { load proc name }
  327. sp:=pattern;
  328. if sym^.typ=typesym then
  329. i:=procinfo^._class^.implementedinterfaces^.searchintf(ptypesym(sym)^.restype.def);
  330. { qualifier is interface name? }
  331. if (sym^.typ<>typesym) or (ptypesym(sym)^.restype.def^.deftype<>objectdef) or
  332. (i=-1) then
  333. begin
  334. Message(parser_e_interface_id_expected);
  335. aktprocsym:=nil;
  336. end
  337. else
  338. begin
  339. aktprocsym:=pprocsym(procinfo^._class^.implementedinterfaces^.interfaces(i)^.symtable^.search(sp));
  340. if not(assigned(aktprocsym)) then
  341. Message(parser_e_methode_id_expected);
  342. end;
  343. consume(_ID);
  344. consume(_EQUAL);
  345. if (token=_ID) and assigned(aktprocsym) then
  346. procinfo^._class^.implementedinterfaces^.addmappings(i,sp,pattern);
  347. consume(_ID);
  348. exit;
  349. end;
  350. { method ? }
  351. if not(parse_only) and
  352. (lexlevel=normal_function_level) and
  353. try_to_consume(_POINT) then
  354. begin
  355. storepos:=akttokenpos;
  356. akttokenpos:=procstartfilepos;
  357. getsym(sp,true);
  358. sym:=srsym;
  359. akttokenpos:=storepos;
  360. { load proc name }
  361. sp:=pattern;
  362. orgsp:=orgpattern;
  363. procstartfilepos:=akttokenpos;
  364. { qualifier is class name ? }
  365. if (sym^.typ<>typesym) or
  366. (ptypesym(sym)^.restype.def^.deftype<>objectdef) then
  367. begin
  368. Message(parser_e_class_id_expected);
  369. aktprocsym:=nil;
  370. consume(_ID);
  371. end
  372. else
  373. begin
  374. { used to allow private syms to be seen }
  375. aktobjectdef:=pobjectdef(ptypesym(sym)^.restype.def);
  376. procinfo^._class:=pobjectdef(ptypesym(sym)^.restype.def);
  377. aktprocsym:=pprocsym(procinfo^._class^.symtable^.search(sp));
  378. consume(_ID);
  379. {The procedure has been found. So it is
  380. a global one. Set the flags to mark this.}
  381. procinfo^.flags:=procinfo^.flags or pi_is_global;
  382. aktobjectdef:=nil;
  383. { we solve this below }
  384. if not(assigned(aktprocsym)) then
  385. Message(parser_e_methode_id_expected);
  386. end;
  387. end
  388. else
  389. begin
  390. { check for constructor/destructor which is not allowed here }
  391. if (not parse_only) and
  392. (options in [potype_constructor,potype_destructor]) then
  393. Message(parser_e_constructors_always_objects);
  394. akttokenpos:=procstartfilepos;
  395. aktprocsym:=pprocsym(symtablestack^.search(sp));
  396. if not(parse_only) then
  397. begin
  398. {The procedure we prepare for is in the implementation
  399. part of the unit we compile. It is also possible that we
  400. are compiling a program, which is also some kind of
  401. implementaion part.
  402. We need to find out if the procedure is global. If it is
  403. global, it is in the global symtable.}
  404. if not assigned(aktprocsym) and
  405. (symtablestack^.symtabletype=staticsymtable) then
  406. begin
  407. {Search the procedure in the global symtable.}
  408. aktprocsym:=Pprocsym(search_a_symtable(sp,globalsymtable));
  409. if assigned(aktprocsym) then
  410. begin
  411. {Check if it is a procedure.}
  412. if aktprocsym^.typ<>procsym then
  413. DuplicateSym(aktprocsym);
  414. {The procedure has been found. So it is
  415. a global one. Set the flags to mark this.}
  416. procinfo^.flags:=procinfo^.flags or pi_is_global;
  417. end;
  418. end;
  419. end;
  420. end;
  421. { Create the mangledname }
  422. {$ifndef UseNiceNames}
  423. if assigned(procinfo^._class) then
  424. begin
  425. if (pos('_$$_',procprefix)=0) then
  426. hs:=procprefix+'_$$_'+procinfo^._class^.objname^+'_$$_'+sp
  427. else
  428. hs:=procprefix+'_$'+sp;
  429. end
  430. else
  431. begin
  432. if lexlevel=normal_function_level then
  433. hs:=procprefix+'_'+sp
  434. else
  435. hs:=procprefix+'_$'+sp;
  436. end;
  437. {$else UseNiceNames}
  438. if assigned(procinfo^._class) then
  439. begin
  440. if (pos('_5Class_',procprefix)=0) then
  441. hs:=procprefix+'_5Class_'+procinfo^._class^.name^+'_'+tostr(length(sp))+sp
  442. else
  443. hs:=procprefix+'_'+tostr(length(sp))+sp;
  444. end
  445. else
  446. begin
  447. if lexlevel=normal_function_level then
  448. hs:=procprefix+'_'+tostr(length(sp))+sp
  449. else
  450. hs:=lowercase(procprefix)+'_'+tostr(length(sp))+sp;
  451. end;
  452. {$endif UseNiceNames}
  453. if assigned(aktprocsym) then
  454. begin
  455. { Check if overloaded is a procsym, we use a different error message
  456. for tp7 so it looks more compatible }
  457. if aktprocsym^.typ<>procsym then
  458. begin
  459. if (m_fpc in aktmodeswitches) then
  460. Message1(parser_e_overloaded_no_procedure,aktprocsym^.realname)
  461. else
  462. DuplicateSym(aktprocsym);
  463. { try to recover by creating a new aktprocsym }
  464. akttokenpos:=procstartfilepos;
  465. aktprocsym:=new(pprocsym,init(orgsp));
  466. end;
  467. end
  468. else
  469. begin
  470. { create a new procsym and set the real filepos }
  471. akttokenpos:=procstartfilepos;
  472. { for operator we have only one definition for each overloaded
  473. operation }
  474. if (options=potype_operator) then
  475. begin
  476. { create the procsym with saving the original case }
  477. aktprocsym:=new(pprocsym,init('$'+sp));
  478. { the only problem is that nextoverloaded might not be in a unit
  479. known for the unit itself }
  480. { not anymore PM }
  481. if assigned(overloaded_operators[optoken]) then
  482. aktprocsym^.definition:=overloaded_operators[optoken]^.definition;
  483. {$ifndef DONOTCHAINOPERATORS}
  484. overloaded_operators[optoken]:=aktprocsym;
  485. {$endif DONOTCHAINOPERATORS}
  486. end
  487. else
  488. aktprocsym:=new(pprocsym,init(orgsp));
  489. symtablestack^.insert(aktprocsym);
  490. end;
  491. st:=symtablestack;
  492. pd:=new(pprocdef,init);
  493. pd^.symtablelevel:=symtablestack^.symtablelevel;
  494. if assigned(procinfo^._class) then
  495. pd^._class := procinfo^._class;
  496. { set the options from the caller (podestructor or poconstructor) }
  497. pd^.proctypeoption:=options;
  498. { calculate the offset of the parameters }
  499. paramoffset:=8;
  500. { calculate frame pointer offset }
  501. if lexlevel>normal_function_level then
  502. begin
  503. procinfo^.framepointer_offset:=paramoffset;
  504. inc(paramoffset,target_os.size_of_pointer);
  505. { this is needed to get correct framepointer push for local
  506. forward functions !! }
  507. pd^.parast^.symtablelevel:=lexlevel;
  508. end;
  509. if assigned (procinfo^._Class) and
  510. is_object(procinfo^._Class) and
  511. (pd^.proctypeoption in [potype_constructor,potype_destructor]) then
  512. inc(paramoffset,target_os.size_of_pointer);
  513. { self pointer offset }
  514. { self isn't pushed in nested procedure of methods }
  515. if assigned(procinfo^._class) and (lexlevel=normal_function_level) then
  516. begin
  517. procinfo^.selfpointer_offset:=paramoffset;
  518. if assigned(aktprocsym^.definition) and
  519. not(po_containsself in aktprocsym^.definition^.procoptions) then
  520. inc(paramoffset,target_os.size_of_pointer);
  521. end;
  522. { con/-destructor flag ? }
  523. if assigned (procinfo^._Class) and
  524. is_class(procinfo^._class) and
  525. (pd^.proctypeoption in [potype_destructor,potype_constructor]) then
  526. inc(paramoffset,target_os.size_of_pointer);
  527. procinfo^.para_offset:=paramoffset;
  528. pd^.parast^.datasize:=0;
  529. pd^.nextoverloaded:=aktprocsym^.definition;
  530. aktprocsym^.definition:=pd;
  531. { this is probably obsolete now PM }
  532. aktprocsym^.definition^.fileinfo:=procstartfilepos;
  533. aktprocsym^.definition^.setmangledname(hs);
  534. aktprocsym^.definition^.procsym:=aktprocsym;
  535. if not parse_only then
  536. begin
  537. overloaded_level:=0;
  538. { we need another procprefix !!! }
  539. { count, but only those in the same unit !!}
  540. while assigned(pd) and
  541. (pd^.owner^.symtabletype in [globalsymtable,staticsymtable]) do
  542. begin
  543. { only count already implemented functions }
  544. if not(pd^.forwarddef) then
  545. inc(overloaded_level);
  546. pd:=pd^.nextoverloaded;
  547. end;
  548. if overloaded_level>0 then
  549. procprefix:=hs+'$'+tostr(overloaded_level)+'$'
  550. else
  551. procprefix:=hs+'$';
  552. end;
  553. { this must also be inserted in the right symtable !! PM }
  554. { otherwise we get subbtle problems with
  555. definitions of args defs in staticsymtable for
  556. implementation of a global method }
  557. if token=_LKLAMMER then
  558. parameter_dec(aktprocsym^.definition);
  559. { so we only restore the symtable now }
  560. symtablestack:=st;
  561. if (options=potype_operator) then
  562. overloaded_operators[optoken]:=aktprocsym;
  563. end;
  564. procedure parse_proc_dec;
  565. var
  566. hs : string;
  567. isclassmethod : boolean;
  568. begin
  569. inc(lexlevel);
  570. { read class method }
  571. if token=_CLASS then
  572. begin
  573. consume(_CLASS);
  574. isclassmethod:=true;
  575. end
  576. else
  577. isclassmethod:=false;
  578. case token of
  579. _FUNCTION : begin
  580. consume(_FUNCTION);
  581. parse_proc_head(potype_none);
  582. if token<>_COLON then
  583. begin
  584. if not(is_interface(aktprocsym^.definition^._class)) and
  585. not(aktprocsym^.definition^.forwarddef) or
  586. (m_repeat_forward in aktmodeswitches) then
  587. begin
  588. consume(_COLON);
  589. consume_all_until(_SEMICOLON);
  590. end;
  591. end
  592. else
  593. begin
  594. consume(_COLON);
  595. inc(testcurobject);
  596. single_type(aktprocsym^.definition^.rettype,hs,false);
  597. aktprocsym^.definition^.test_if_fpu_result;
  598. dec(testcurobject);
  599. end;
  600. end;
  601. _PROCEDURE : begin
  602. consume(_PROCEDURE);
  603. parse_proc_head(potype_none);
  604. aktprocsym^.definition^.rettype.def:=voiddef;
  605. end;
  606. _CONSTRUCTOR : begin
  607. consume(_CONSTRUCTOR);
  608. parse_proc_head(potype_constructor);
  609. if assigned(procinfo^._class) and
  610. is_class(procinfo^._class) then
  611. begin
  612. { CLASS constructors return the created instance }
  613. aktprocsym^.definition^.rettype.def:=procinfo^._class;
  614. end
  615. else
  616. begin
  617. { OBJECT constructors return a boolean }
  618. {$IfDef GDB}
  619. { GDB doesn't like unnamed types !}
  620. aktprocsym^.definition^.rettype.def:=globaldef('boolean');
  621. {$else GDB}
  622. aktprocsym^.definition^.rettype.def:=new(porddef,init(bool8bit,0,1));
  623. {$Endif GDB}
  624. end;
  625. end;
  626. _DESTRUCTOR : begin
  627. consume(_DESTRUCTOR);
  628. parse_proc_head(potype_destructor);
  629. aktprocsym^.definition^.rettype.def:=voiddef;
  630. end;
  631. _OPERATOR : begin
  632. if lexlevel>normal_function_level then
  633. Message(parser_e_no_local_operator);
  634. consume(_OPERATOR);
  635. if not(token in [_PLUS..last_overloaded]) then
  636. Message(parser_e_overload_operator_failed);
  637. optoken:=token;
  638. consume(Token);
  639. procinfo^.flags:=procinfo^.flags or pi_operator;
  640. parse_proc_head(potype_operator);
  641. if token<>_ID then
  642. begin
  643. opsym:=nil;
  644. if not(m_result in aktmodeswitches) then
  645. consume(_ID);
  646. end
  647. else
  648. begin
  649. opsym:=new(pvarsym,initdef(pattern,voiddef));
  650. consume(_ID);
  651. end;
  652. if not try_to_consume(_COLON) then
  653. begin
  654. consume(_COLON);
  655. aktprocsym^.definition^.rettype.def:=generrordef;
  656. consume_all_until(_SEMICOLON);
  657. end
  658. else
  659. begin
  660. single_type(aktprocsym^.definition^.rettype,hs,false);
  661. aktprocsym^.definition^.test_if_fpu_result;
  662. if (optoken in [_EQUAL,_GT,_LT,_GTE,_LTE]) and
  663. ((aktprocsym^.definition^.rettype.def^.deftype<>
  664. orddef) or (porddef(aktprocsym^.definition^.
  665. rettype.def)^.typ<>bool8bit)) then
  666. Message(parser_e_comparative_operator_return_boolean);
  667. if assigned(opsym) then
  668. opsym^.vartype.def:=aktprocsym^.definition^.rettype.def;
  669. { We need to add the return type in the mangledname
  670. to allow overloading with just different results !! (PM) }
  671. aktprocsym^.definition^.setmangledname(
  672. aktprocsym^.definition^.mangledname+'$$'+hs);
  673. if (optoken=_ASSIGNMENT) and
  674. is_equal(aktprocsym^.definition^.rettype.def,
  675. pvarsym(aktprocsym^.definition^.parast^.symindex^.first)^.vartype.def) then
  676. message(parser_e_no_such_assignment)
  677. else if not isoperatoracceptable(aktprocsym^.definition,optoken) then
  678. Message(parser_e_overload_impossible);
  679. end;
  680. end;
  681. end;
  682. if isclassmethod and
  683. assigned(aktprocsym) then
  684. include(aktprocsym^.definition^.procoptions,po_classmethod);
  685. { support procedure proc;stdcall export; in Delphi mode only }
  686. if not((m_delphi in aktmodeswitches) and
  687. is_proc_directive(token)) then
  688. consume(_SEMICOLON);
  689. dec(lexlevel);
  690. end;
  691. {****************************************************************************
  692. Procedure directive handlers
  693. ****************************************************************************}
  694. procedure pd_far(const procnames:Tstringcontainer);
  695. begin
  696. Message(parser_w_proc_far_ignored);
  697. end;
  698. procedure pd_near(const procnames:Tstringcontainer);
  699. begin
  700. Message(parser_w_proc_near_ignored);
  701. end;
  702. procedure pd_export(const procnames:Tstringcontainer);
  703. begin
  704. if assigned(procinfo^._class) then
  705. Message(parser_e_methods_dont_be_export);
  706. if lexlevel<>normal_function_level then
  707. Message(parser_e_dont_nest_export);
  708. { only os/2 needs this }
  709. if target_info.target=target_i386_os2 then
  710. begin
  711. procnames.insert(aktprocsym^.realname);
  712. procinfo^.exported:=true;
  713. if cs_link_deffile in aktglobalswitches then
  714. deffile.AddExport(aktprocsym^.definition^.mangledname);
  715. end;
  716. end;
  717. procedure pd_inline(const procnames:Tstringcontainer);
  718. begin
  719. if not(cs_support_inline in aktmoduleswitches) then
  720. Message(parser_e_proc_inline_not_supported);
  721. end;
  722. procedure pd_forward(const procnames:Tstringcontainer);
  723. begin
  724. aktprocsym^.definition^.forwarddef:=true;
  725. end;
  726. procedure pd_stdcall(const procnames:Tstringcontainer);
  727. begin
  728. end;
  729. procedure pd_safecall(const procnames:Tstringcontainer);
  730. begin
  731. end;
  732. procedure pd_alias(const procnames:Tstringcontainer);
  733. begin
  734. consume(_COLON);
  735. procnames.insert(get_stringconst);
  736. end;
  737. procedure pd_asmname(const procnames:Tstringcontainer);
  738. begin
  739. aktprocsym^.definition^.setmangledname(target_os.Cprefix+pattern);
  740. if token=_CCHAR then
  741. consume(_CCHAR)
  742. else
  743. consume(_CSTRING);
  744. { we don't need anything else }
  745. aktprocsym^.definition^.forwarddef:=false;
  746. end;
  747. procedure pd_intern(const procnames:Tstringcontainer);
  748. begin
  749. consume(_COLON);
  750. aktprocsym^.definition^.extnumber:=get_intconst;
  751. end;
  752. procedure pd_interrupt(const procnames:Tstringcontainer);
  753. begin
  754. {$ifndef i386}
  755. Message(parser_w_proc_interrupt_ignored);
  756. {$else i386}
  757. if lexlevel<>normal_function_level then
  758. Message(parser_e_dont_nest_interrupt);
  759. {$endif i386}
  760. end;
  761. procedure pd_system(const procnames:Tstringcontainer);
  762. begin
  763. aktprocsym^.definition^.setmangledname(aktprocsym^.realname);
  764. end;
  765. procedure pd_abstract(const procnames:Tstringcontainer);
  766. begin
  767. if (po_virtualmethod in aktprocsym^.definition^.procoptions) then
  768. include(aktprocsym^.definition^.procoptions,po_abstractmethod)
  769. else
  770. Message(parser_e_only_virtual_methods_abstract);
  771. { the method is defined }
  772. aktprocsym^.definition^.forwarddef:=false;
  773. end;
  774. procedure pd_virtual(const procnames:Tstringcontainer);
  775. {$ifdef WITHDMT}
  776. var
  777. pt : tnode;
  778. {$endif WITHDMT}
  779. begin
  780. if (aktprocsym^.definition^.proctypeoption=potype_constructor) and
  781. is_object(aktprocsym^.definition^._class) then
  782. Message(parser_e_constructor_cannot_be_not_virtual);
  783. {$ifdef WITHDMT}
  784. if is_object(aktprocsym^.definition^._class) and
  785. (token<>_SEMICOLON) then
  786. begin
  787. { any type of parameter is allowed here! }
  788. pt:=comp_expr(true);
  789. do_firstpass(pt);
  790. if is_constintnode(pt) then
  791. begin
  792. include(aktprocsym^.definition^.procoptions,po_msgint);
  793. aktprocsym^.definition^.messageinf.i:=pt^.value;
  794. end
  795. else
  796. Message(parser_e_ill_msg_expr);
  797. disposetree(pt);
  798. end;
  799. {$endif WITHDMT}
  800. end;
  801. procedure pd_static(const procnames:Tstringcontainer);
  802. begin
  803. if (cs_static_keyword in aktmoduleswitches) then
  804. begin
  805. include(aktprocsym^.symoptions,sp_static);
  806. include(aktprocsym^.definition^.procoptions,po_staticmethod);
  807. end;
  808. end;
  809. procedure pd_override(const procnames:Tstringcontainer);
  810. begin
  811. if not(is_class_or_interface(aktprocsym^.definition^._class)) then
  812. Message(parser_e_no_object_override);
  813. end;
  814. procedure pd_overload(const procnames:Tstringcontainer);
  815. begin
  816. end;
  817. procedure pd_message(const procnames:Tstringcontainer);
  818. var
  819. pt : tnode;
  820. begin
  821. { check parameter type }
  822. if not(po_containsself in aktprocsym^.definition^.procoptions) and
  823. ((aktprocsym^.definition^.minparacount<>1) or
  824. (aktprocsym^.definition^.maxparacount<>1) or
  825. (pparaitem(aktprocsym^.definition^.para^.first)^.paratyp<>vs_var)) then
  826. Message(parser_e_ill_msg_param);
  827. pt:=comp_expr(true);
  828. do_firstpass(pt);
  829. if pt.nodetype=stringconstn then
  830. begin
  831. include(aktprocsym^.definition^.procoptions,po_msgstr);
  832. aktprocsym^.definition^.messageinf.str:=strnew(tstringconstnode(pt).value_str);
  833. end
  834. else
  835. if is_constintnode(pt) then
  836. begin
  837. include(aktprocsym^.definition^.procoptions,po_msgint);
  838. aktprocsym^.definition^.messageinf.i:=tordconstnode(pt).value;
  839. end
  840. else
  841. Message(parser_e_ill_msg_expr);
  842. pt.free;
  843. end;
  844. procedure resetvaluepara(p:pnamedindexobject);
  845. begin
  846. if psym(p)^.typ=varsym then
  847. with pvarsym(p)^ do
  848. if copy(name,1,3)='val' then
  849. aktprocsym^.definition^.parast^.symsearch^.rename(name,copy(name,4,length(name)));
  850. end;
  851. procedure pd_cdecl(const procnames:Tstringcontainer);
  852. begin
  853. if aktprocsym^.definition^.deftype<>procvardef then
  854. aktprocsym^.definition^.setmangledname(target_os.Cprefix+aktprocsym^.realname);
  855. { do not copy on local !! }
  856. if (aktprocsym^.definition^.deftype=procdef) and
  857. assigned(aktprocsym^.definition^.parast) then
  858. aktprocsym^.definition^.parast^.foreach({$ifdef FPCPROCVAR}@{$endif}resetvaluepara);
  859. end;
  860. procedure pd_cppdecl(const procnames:Tstringcontainer);
  861. begin
  862. if aktprocsym^.definition^.deftype<>procvardef then
  863. aktprocsym^.definition^.setmangledname(
  864. target_os.Cprefix+aktprocsym^.definition^.cplusplusmangledname);
  865. { do not copy on local !! }
  866. if (aktprocsym^.definition^.deftype=procdef) and
  867. assigned(aktprocsym^.definition^.parast) then
  868. aktprocsym^.definition^.parast^.foreach({$ifdef FPCPROCVAR}@{$endif}resetvaluepara);
  869. end;
  870. procedure pd_pascal(const procnames:Tstringcontainer);
  871. var st,parast : psymtable;
  872. lastps,ps : psym;
  873. begin
  874. new(st,init(parasymtable));
  875. parast:=aktprocsym^.definition^.parast;
  876. lastps:=nil;
  877. while assigned(parast^.symindex^.first) and (lastps<>psym(parast^.symindex^.first)) do
  878. begin
  879. ps:=psym(parast^.symindex^.first);
  880. while assigned(ps^.indexnext) and (psym(ps^.indexnext)<>lastps) do
  881. ps:=psym(ps^.indexnext);
  882. ps^.owner:=st;
  883. { recalculate the corrected offset }
  884. { the really_insert_in_data procedure
  885. for parasymtable should only calculateoffset PM }
  886. pstoredsym(ps)^.insert_in_data;
  887. { reset the owner correctly }
  888. ps^.owner:=parast;
  889. lastps:=ps;
  890. end;
  891. end;
  892. procedure pd_register(const procnames:Tstringcontainer);
  893. begin
  894. Message1(parser_w_proc_directive_ignored,'REGISTER');
  895. end;
  896. procedure pd_reintroduce(const procnames:Tstringcontainer);
  897. begin
  898. Message1(parser_w_proc_directive_ignored,'REINTRODUCE');
  899. end;
  900. procedure pd_syscall(const procnames:Tstringcontainer);
  901. begin
  902. aktprocsym^.definition^.forwarddef:=false;
  903. aktprocsym^.definition^.extnumber:=get_intconst;
  904. end;
  905. procedure pd_external(const procnames:Tstringcontainer);
  906. {
  907. If import_dll=nil the procedure is assumed to be in another
  908. object file. In that object file it should have the name to
  909. which import_name is pointing to. Otherwise, the procedure is
  910. assumed to be in the DLL to which import_dll is pointing to. In
  911. that case either import_nr<>0 or import_name<>nil is true, so
  912. the procedure is either imported by number or by name. (DM)
  913. }
  914. var
  915. import_dll,
  916. import_name : string;
  917. import_nr : word;
  918. begin
  919. aktprocsym^.definition^.forwarddef:=false;
  920. { If the procedure should be imported from a DLL, a constant string follows.
  921. This isn't really correct, an contant string expression follows
  922. so we check if an semicolon follows, else a string constant have to
  923. follow (FK) }
  924. import_nr:=0;
  925. import_name:='';
  926. if not(token=_SEMICOLON) and not(idtoken=_NAME) then
  927. begin
  928. import_dll:=get_stringconst;
  929. if (idtoken=_NAME) then
  930. begin
  931. consume(_NAME);
  932. import_name:=get_stringconst;
  933. end;
  934. if (idtoken=_INDEX) then
  935. begin
  936. {After the word index follows the index number in the DLL.}
  937. consume(_INDEX);
  938. import_nr:=get_intconst;
  939. end;
  940. if (import_nr=0) and (import_name='') then
  941. {if (aktprocsym^.definition^.options and pocdecl)<>0 then
  942. import_name:=aktprocsym^.definition^.mangledname
  943. else
  944. Message(parser_w_empty_import_name);}
  945. { this should work both for win32 and Linux !! PM }
  946. import_name:=aktprocsym^.realname;
  947. if not(current_module^.uses_imports) then
  948. begin
  949. current_module^.uses_imports:=true;
  950. importlib^.preparelib(current_module^.modulename^);
  951. end;
  952. if not(m_repeat_forward in aktmodeswitches) then
  953. begin
  954. { we can only have one overloaded here ! }
  955. if assigned(aktprocsym^.definition^.nextoverloaded) then
  956. importlib^.importprocedure(aktprocsym^.definition^.nextoverloaded^.mangledname,
  957. import_dll,import_nr,import_name)
  958. else
  959. importlib^.importprocedure(aktprocsym^.mangledname,import_dll,import_nr,import_name);
  960. end
  961. else
  962. importlib^.importprocedure(aktprocsym^.mangledname,import_dll,import_nr,import_name);
  963. end
  964. else
  965. begin
  966. if (idtoken=_NAME) then
  967. begin
  968. consume(_NAME);
  969. import_name:=get_stringconst;
  970. aktprocsym^.definition^.setmangledname(import_name);
  971. end
  972. else
  973. begin
  974. { external shouldn't override the cdecl/system name }
  975. if not (pocall_clearstack in aktprocsym^.definition^.proccalloptions) then
  976. aktprocsym^.definition^.setmangledname(aktprocsym^.realname);
  977. end;
  978. end;
  979. end;
  980. type
  981. pd_handler=procedure(const procnames:Tstringcontainer);
  982. proc_dir_rec=record
  983. idtok : ttoken;
  984. pd_flags : longint;
  985. handler : pd_handler;
  986. pocall : tproccalloptions;
  987. pooption : tprocoptions;
  988. mutexclpocall : tproccalloptions;
  989. mutexclpotype : tproctypeoptions;
  990. mutexclpo : tprocoptions;
  991. end;
  992. const
  993. {Should contain the number of procedure directives we support.}
  994. num_proc_directives=32;
  995. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  996. (
  997. (
  998. idtok:_ABSTRACT;
  999. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1000. handler : {$ifdef FPCPROCVAR}@{$endif}pd_abstract;
  1001. pocall : [];
  1002. pooption : [po_abstractmethod];
  1003. mutexclpocall : [pocall_internproc,pocall_inline];
  1004. mutexclpotype : [potype_constructor,potype_destructor];
  1005. mutexclpo : [po_exports,po_interrupt,po_external]
  1006. ),(
  1007. idtok:_ALIAS;
  1008. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1009. handler : {$ifdef FPCPROCVAR}@{$endif}pd_alias;
  1010. pocall : [];
  1011. pooption : [];
  1012. mutexclpocall : [pocall_inline];
  1013. mutexclpotype : [];
  1014. mutexclpo : [po_external]
  1015. ),(
  1016. idtok:_ASMNAME;
  1017. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  1018. handler : {$ifdef FPCPROCVAR}@{$endif}pd_asmname;
  1019. pocall : [pocall_cdecl,pocall_clearstack];
  1020. pooption : [po_external];
  1021. mutexclpocall : [pocall_internproc];
  1022. mutexclpotype : [];
  1023. mutexclpo : [po_external]
  1024. ),(
  1025. idtok:_ASSEMBLER;
  1026. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1027. handler : nil;
  1028. pocall : [];
  1029. pooption : [po_assembler];
  1030. mutexclpocall : [];
  1031. mutexclpotype : [];
  1032. mutexclpo : [po_external]
  1033. ),(
  1034. idtok:_CDECL;
  1035. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1036. handler : {$ifdef FPCPROCVAR}@{$endif}pd_cdecl;
  1037. pocall : [pocall_cdecl,pocall_clearstack];
  1038. pooption : [po_savestdregs];
  1039. mutexclpocall : [pocall_cppdecl,pocall_internproc,pocall_leftright,pocall_inline];
  1040. mutexclpotype : [];
  1041. mutexclpo : [po_assembler,po_external]
  1042. ),(
  1043. idtok:_DYNAMIC;
  1044. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1045. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  1046. pocall : [];
  1047. pooption : [po_virtualmethod];
  1048. mutexclpocall : [pocall_internproc,pocall_inline];
  1049. mutexclpotype : [];
  1050. mutexclpo : [po_exports,po_interrupt,po_external]
  1051. ),(
  1052. idtok:_EXPORT;
  1053. pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??}+pd_notobjintf;
  1054. handler : {$ifdef FPCPROCVAR}@{$endif}pd_export;
  1055. pocall : [];
  1056. pooption : [po_exports];
  1057. mutexclpocall : [pocall_internproc,pocall_inline];
  1058. mutexclpotype : [];
  1059. mutexclpo : [po_external,po_interrupt]
  1060. ),(
  1061. idtok:_EXTERNAL;
  1062. pd_flags : pd_implemen+pd_interface+pd_notobjintf;
  1063. handler : {$ifdef FPCPROCVAR}@{$endif}pd_external;
  1064. pocall : [];
  1065. pooption : [po_external];
  1066. mutexclpocall : [pocall_internproc,pocall_inline,pocall_palmossyscall];
  1067. mutexclpotype : [];
  1068. mutexclpo : [po_exports,po_interrupt,po_assembler]
  1069. ),(
  1070. idtok:_FAR;
  1071. pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar+pd_notobjintf;
  1072. handler : {$ifdef FPCPROCVAR}@{$endif}pd_far;
  1073. pocall : [];
  1074. pooption : [];
  1075. mutexclpocall : [pocall_internproc,pocall_inline];
  1076. mutexclpotype : [];
  1077. mutexclpo : []
  1078. ),(
  1079. idtok:_FORWARD;
  1080. pd_flags : pd_implemen+pd_notobjintf;
  1081. handler : {$ifdef FPCPROCVAR}@{$endif}pd_forward;
  1082. pocall : [];
  1083. pooption : [];
  1084. mutexclpocall : [pocall_internproc,pocall_inline];
  1085. mutexclpotype : [];
  1086. mutexclpo : [po_external]
  1087. ),(
  1088. idtok:_INLINE;
  1089. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1090. handler : {$ifdef FPCPROCVAR}@{$endif}pd_inline;
  1091. pocall : [pocall_inline];
  1092. pooption : [];
  1093. mutexclpocall : [pocall_internproc];
  1094. mutexclpotype : [potype_constructor,potype_destructor];
  1095. mutexclpo : [po_exports,po_external,po_interrupt]
  1096. ),(
  1097. idtok:_INTERNCONST;
  1098. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1099. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1100. pocall : [pocall_internconst];
  1101. pooption : [];
  1102. mutexclpocall : [];
  1103. mutexclpotype : [potype_operator];
  1104. mutexclpo : []
  1105. ),(
  1106. idtok:_INTERNPROC;
  1107. pd_flags : pd_implemen+pd_notobjintf;
  1108. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1109. pocall : [pocall_internproc];
  1110. pooption : [];
  1111. mutexclpocall : [pocall_inline,pocall_clearstack,pocall_leftright,pocall_cdecl,pocall_cppdecl];
  1112. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1113. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck]
  1114. ),(
  1115. idtok:_INTERRUPT;
  1116. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1117. handler : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
  1118. pocall : [];
  1119. pooption : [po_interrupt];
  1120. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,pocall_clearstack,pocall_leftright,pocall_inline];
  1121. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1122. mutexclpo : [po_external]
  1123. ),(
  1124. idtok:_IOCHECK;
  1125. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1126. handler : nil;
  1127. pocall : [];
  1128. pooption : [po_iocheck];
  1129. mutexclpocall : [pocall_internproc];
  1130. mutexclpotype : [];
  1131. mutexclpo : [po_external]
  1132. ),(
  1133. idtok:_MESSAGE;
  1134. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1135. handler : {$ifdef FPCPROCVAR}@{$endif}pd_message;
  1136. pocall : [];
  1137. pooption : []; { can be po_msgstr or po_msgint }
  1138. mutexclpocall : [pocall_inline,pocall_internproc];
  1139. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1140. mutexclpo : [po_interrupt,po_external]
  1141. ),(
  1142. idtok:_NEAR;
  1143. pd_flags : pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1144. handler : {$ifdef FPCPROCVAR}@{$endif}pd_near;
  1145. pocall : [];
  1146. pooption : [];
  1147. mutexclpocall : [pocall_internproc];
  1148. mutexclpotype : [];
  1149. mutexclpo : []
  1150. ),(
  1151. idtok:_OVERLOAD;
  1152. pd_flags : pd_implemen+pd_interface+pd_body;
  1153. handler : {$ifdef FPCPROCVAR}@{$endif}pd_overload;
  1154. pocall : [];
  1155. pooption : [po_overload];
  1156. mutexclpocall : [pocall_internproc];
  1157. mutexclpotype : [];
  1158. mutexclpo : []
  1159. ),(
  1160. idtok:_OVERRIDE;
  1161. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1162. handler : {$ifdef FPCPROCVAR}@{$endif}pd_override;
  1163. pocall : [];
  1164. pooption : [po_overridingmethod,po_virtualmethod];
  1165. mutexclpocall : [pocall_inline,pocall_internproc];
  1166. mutexclpotype : [];
  1167. mutexclpo : [po_exports,po_external,po_interrupt]
  1168. ),(
  1169. idtok:_PASCAL;
  1170. pd_flags : pd_implemen+pd_body+pd_procvar;
  1171. handler : {$ifdef FPCPROCVAR}@{$endif}pd_pascal;
  1172. pocall : [pocall_leftright];
  1173. pooption : [];
  1174. mutexclpocall : [pocall_internproc];
  1175. mutexclpotype : [];
  1176. mutexclpo : [po_external]
  1177. ),(
  1178. idtok:_POPSTACK;
  1179. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1180. handler : nil;
  1181. pocall : [pocall_clearstack];
  1182. pooption : [];
  1183. mutexclpocall : [pocall_inline,pocall_internproc];
  1184. mutexclpotype : [];
  1185. mutexclpo : [po_assembler,po_external]
  1186. ),(
  1187. idtok:_PUBLIC;
  1188. pd_flags : pd_implemen+pd_body+pd_global+pd_notobject+pd_notobjintf;
  1189. handler : nil;
  1190. pocall : [];
  1191. pooption : [];
  1192. mutexclpocall : [pocall_internproc,pocall_inline];
  1193. mutexclpotype : [];
  1194. mutexclpo : [po_external]
  1195. ),(
  1196. idtok:_REGISTER;
  1197. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1198. handler : {$ifdef FPCPROCVAR}@{$endif}pd_register;
  1199. pocall : [pocall_register];
  1200. pooption : [];
  1201. mutexclpocall : [pocall_leftright,pocall_cdecl,pocall_internproc,pocall_cppdecl];
  1202. mutexclpotype : [];
  1203. mutexclpo : [po_external]
  1204. ),(
  1205. idtok:_REINTRODUCE;
  1206. pd_flags : pd_interface+pd_object;
  1207. handler : {$ifdef FPCPROCVAR}@{$endif}pd_reintroduce;
  1208. pocall : [];
  1209. pooption : [];
  1210. mutexclpocall : [];
  1211. mutexclpotype : [];
  1212. mutexclpo : []
  1213. ),(
  1214. idtok:_SAFECALL;
  1215. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1216. handler : {$ifdef FPCPROCVAR}@{$endif}pd_safecall;
  1217. pocall : [pocall_safecall];
  1218. pooption : [po_savestdregs];
  1219. mutexclpocall : [pocall_leftright,pocall_cdecl,pocall_cppdecl,pocall_internproc,pocall_inline];
  1220. mutexclpotype : [];
  1221. mutexclpo : [po_external]
  1222. ),(
  1223. idtok:_SAVEREGISTERS;
  1224. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1225. handler : nil;
  1226. pocall : [];
  1227. pooption : [po_saveregisters];
  1228. mutexclpocall : [pocall_internproc];
  1229. mutexclpotype : [];
  1230. mutexclpo : [po_external]
  1231. ),(
  1232. idtok:_STATIC;
  1233. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1234. handler : {$ifdef FPCPROCVAR}@{$endif}pd_static;
  1235. pocall : [];
  1236. pooption : [po_staticmethod];
  1237. mutexclpocall : [pocall_inline,pocall_internproc];
  1238. mutexclpotype : [potype_constructor,potype_destructor];
  1239. mutexclpo : [po_external,po_interrupt,po_exports]
  1240. ),(
  1241. idtok:_STDCALL;
  1242. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1243. handler : {$ifdef FPCPROCVAR}@{$endif}pd_stdcall;
  1244. pocall : [pocall_stdcall];
  1245. pooption : [po_savestdregs];
  1246. mutexclpocall : [pocall_leftright,pocall_cdecl,pocall_cppdecl,pocall_inline,pocall_internproc];
  1247. mutexclpotype : [];
  1248. mutexclpo : [po_external]
  1249. ),(
  1250. idtok:_SYSCALL;
  1251. pd_flags : pd_interface+pd_notobjintf;
  1252. handler : {$ifdef FPCPROCVAR}@{$endif}pd_syscall;
  1253. pocall : [pocall_palmossyscall];
  1254. pooption : [];
  1255. mutexclpocall : [pocall_cdecl,pocall_cppdecl,pocall_inline,pocall_internproc];
  1256. mutexclpotype : [];
  1257. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  1258. ),(
  1259. idtok:_SYSTEM;
  1260. pd_flags : pd_implemen+pd_notobjintf;
  1261. handler : {$ifdef FPCPROCVAR}@{$endif}pd_system;
  1262. pocall : [pocall_clearstack];
  1263. pooption : [];
  1264. mutexclpocall : [pocall_leftright,pocall_inline,pocall_internproc];
  1265. mutexclpotype : [];
  1266. mutexclpo : [po_external,po_assembler,po_interrupt]
  1267. ),(
  1268. idtok:_VIRTUAL;
  1269. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1270. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  1271. pocall : [];
  1272. pooption : [po_virtualmethod];
  1273. mutexclpocall : [pocall_inline,pocall_internproc];
  1274. mutexclpotype : [];
  1275. mutexclpo : [po_external,po_interrupt,po_exports]
  1276. ),(
  1277. idtok:_CPPDECL;
  1278. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1279. handler : {$ifdef FPCPROCVAR}@{$endif}pd_cppdecl;
  1280. pocall : [pocall_cppdecl,pocall_clearstack];
  1281. pooption : [po_savestdregs];
  1282. mutexclpocall : [pocall_cdecl,pocall_internproc,pocall_leftright,pocall_inline];
  1283. mutexclpotype : [];
  1284. mutexclpo : [po_assembler,po_external]
  1285. )
  1286. );
  1287. function is_proc_directive(tok:ttoken):boolean;
  1288. var
  1289. i : longint;
  1290. begin
  1291. is_proc_directive:=false;
  1292. for i:=1 to num_proc_directives do
  1293. if proc_direcdata[i].idtok=idtoken then
  1294. begin
  1295. is_proc_directive:=true;
  1296. exit;
  1297. end;
  1298. end;
  1299. function parse_proc_direc(const proc_names:Tstringcontainer;var pdflags:word):boolean;
  1300. {
  1301. Parse the procedure directive, returns true if a correct directive is found
  1302. }
  1303. var
  1304. p : longint;
  1305. found : boolean;
  1306. name : string;
  1307. begin
  1308. parse_proc_direc:=false;
  1309. name:=pattern;
  1310. found:=false;
  1311. for p:=1 to num_proc_directives do
  1312. if proc_direcdata[p].idtok=idtoken then
  1313. begin
  1314. found:=true;
  1315. break;
  1316. end;
  1317. { Check if the procedure directive is known }
  1318. if not found then
  1319. begin
  1320. { parsing a procvar type the name can be any
  1321. next variable !! }
  1322. if (pdflags and (pd_procvar or pd_object))=0 then
  1323. Message1(parser_w_unknown_proc_directive_ignored,name);
  1324. exit;
  1325. end;
  1326. { static needs a special treatment }
  1327. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  1328. exit;
  1329. { Conflicts between directives ? }
  1330. if (aktprocsym^.definition^.proctypeoption in proc_direcdata[p].mutexclpotype) or
  1331. ((aktprocsym^.definition^.proccalloptions*proc_direcdata[p].mutexclpocall)<>[]) or
  1332. ((aktprocsym^.definition^.procoptions*proc_direcdata[p].mutexclpo)<>[]) then
  1333. begin
  1334. Message1(parser_e_proc_dir_conflict,name);
  1335. exit;
  1336. end;
  1337. { Check if the directive is only for objects }
  1338. if ((proc_direcdata[p].pd_flags and pd_object)<>0) and
  1339. not assigned(aktprocsym^.definition^._class) then
  1340. begin
  1341. exit;
  1342. end;
  1343. { check if method and directive not for object public }
  1344. if ((proc_direcdata[p].pd_flags and pd_notobject)<>0) and
  1345. assigned(aktprocsym^.definition^._class) then
  1346. begin
  1347. exit;
  1348. end;
  1349. { check if method and directive not for interface }
  1350. if ((proc_direcdata[p].pd_flags and pd_notobjintf)<>0) and
  1351. is_interface(aktprocsym^.definition^._class) then
  1352. begin
  1353. exit;
  1354. end;
  1355. { consume directive, and turn flag on }
  1356. consume(token);
  1357. parse_proc_direc:=true;
  1358. { Check the pd_flags if the directive should be allowed }
  1359. if ((pdflags and pd_interface)<>0) and
  1360. ((proc_direcdata[p].pd_flags and pd_interface)=0) then
  1361. begin
  1362. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1363. exit;
  1364. end;
  1365. if ((pdflags and pd_implemen)<>0) and
  1366. ((proc_direcdata[p].pd_flags and pd_implemen)=0) then
  1367. begin
  1368. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1369. exit;
  1370. end;
  1371. if ((pdflags and pd_procvar)<>0) and
  1372. ((proc_direcdata[p].pd_flags and pd_procvar)=0) then
  1373. begin
  1374. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1375. exit;
  1376. end;
  1377. { Return the new pd_flags }
  1378. if (proc_direcdata[p].pd_flags and pd_body)=0 then
  1379. pdflags:=pdflags and (not pd_body);
  1380. if (proc_direcdata[p].pd_flags and pd_global)<>0 then
  1381. pdflags:=pdflags or pd_global;
  1382. { Add the correct flag }
  1383. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions+proc_direcdata[p].pocall;
  1384. aktprocsym^.definition^.procoptions:=aktprocsym^.definition^.procoptions+proc_direcdata[p].pooption;
  1385. { Adjust positions of args for cdecl or stdcall }
  1386. if (aktprocsym^.definition^.deftype=procdef) and
  1387. (([pocall_cdecl,pocall_cppdecl,pocall_stdcall]*aktprocsym^.definition^.proccalloptions)<>[]) then
  1388. pstoredsymtable(aktprocsym^.definition^.parast)^.set_alignment(target_os.size_of_longint);
  1389. { Call the handler }
  1390. if pointer({$ifndef FPC}@{$endif}proc_direcdata[p].handler)<>nil then
  1391. proc_direcdata[p].handler(proc_names);
  1392. end;
  1393. procedure parse_proc_directives(Anames:Pstringcontainer;var pdflags:word);
  1394. {
  1395. Parse the procedure directives. It does not matter if procedure directives
  1396. are written using ;procdir; or ['procdir'] syntax.
  1397. }
  1398. var
  1399. res : boolean;
  1400. begin
  1401. while token in [_ID,_LECKKLAMMER] do
  1402. begin
  1403. if try_to_consume(_LECKKLAMMER) then
  1404. begin
  1405. repeat
  1406. parse_proc_direc(Anames^,pdflags);
  1407. until not try_to_consume(_COMMA);
  1408. consume(_RECKKLAMMER);
  1409. { we always expect at least '[];' }
  1410. res:=true;
  1411. end
  1412. else
  1413. res:=parse_proc_direc(Anames^,pdflags);
  1414. { A procedure directive normally followed by a semicolon, but in
  1415. a const section we should stop when _EQUAL is found }
  1416. if res then
  1417. begin
  1418. if (block_type=bt_const) and
  1419. (token=_EQUAL) then
  1420. break;
  1421. { support procedure proc;stdcall export; in Delphi mode only }
  1422. if not((m_delphi in aktmodeswitches) and
  1423. is_proc_directive(token)) then
  1424. consume(_SEMICOLON);
  1425. end
  1426. else
  1427. break;
  1428. end;
  1429. end;
  1430. procedure parse_var_proc_directives(var sym : psym);
  1431. var
  1432. anames : pstringcontainer;
  1433. pdflags : word;
  1434. oldsym : pprocsym;
  1435. pd : pabstractprocdef;
  1436. begin
  1437. oldsym:=aktprocsym;
  1438. anames:=new(pstringcontainer,init);
  1439. pdflags:=pd_procvar;
  1440. { we create a temporary aktprocsym to read the directives }
  1441. aktprocsym:=new(pprocsym,init(sym^.name));
  1442. case sym^.typ of
  1443. varsym :
  1444. pd:=pabstractprocdef(pvarsym(sym)^.vartype.def);
  1445. typedconstsym :
  1446. pd:=pabstractprocdef(ptypedconstsym(sym)^.typedconsttype.def);
  1447. typesym :
  1448. pd:=pabstractprocdef(ptypesym(sym)^.restype.def);
  1449. else
  1450. internalerror(994932432);
  1451. end;
  1452. if pd^.deftype<>procvardef then
  1453. internalerror(994932433);
  1454. pabstractprocdef(aktprocsym^.definition):=pd;
  1455. { names should never be used anyway }
  1456. inc(lexlevel);
  1457. parse_proc_directives(anames,pdflags);
  1458. dec(lexlevel);
  1459. aktprocsym^.definition:=nil;
  1460. dispose(aktprocsym,done);
  1461. dispose(anames,done);
  1462. aktprocsym:=oldsym;
  1463. end;
  1464. procedure parse_object_proc_directives(var sym : pprocsym);
  1465. var
  1466. anames : pstringcontainer;
  1467. pdflags : word;
  1468. begin
  1469. pdflags:=pd_object;
  1470. anames:=new(pstringcontainer,init);
  1471. inc(lexlevel);
  1472. parse_proc_directives(anames,pdflags);
  1473. dec(lexlevel);
  1474. dispose(anames,done);
  1475. if (po_containsself in aktprocsym^.definition^.procoptions) and
  1476. (([po_msgstr,po_msgint]*aktprocsym^.definition^.procoptions)=[]) then
  1477. Message(parser_e_self_in_non_message_handler);
  1478. end;
  1479. {***************************************************************************}
  1480. function check_identical_proc(var p : pprocdef) : boolean;
  1481. {
  1482. Search for idendical definitions,
  1483. if there is a forward, then kill this.
  1484. Returns the result of the forward check.
  1485. Removed from unter_dec to keep the source readable
  1486. }
  1487. var
  1488. hd,pd : Pprocdef;
  1489. storeparast : psymtable;
  1490. ad,fd : psym;
  1491. s : string;
  1492. begin
  1493. check_identical_proc:=false;
  1494. p:=nil;
  1495. pd:=aktprocsym^.definition;
  1496. if assigned(pd) then
  1497. begin
  1498. { Is there an overload/forward ? }
  1499. if assigned(pd^.nextoverloaded) then
  1500. begin
  1501. { walk the procdef list }
  1502. while (assigned(pd)) and (assigned(pd^.nextoverloaded)) do
  1503. begin
  1504. hd:=pd^.nextoverloaded;
  1505. { check the parameters }
  1506. if (not(m_repeat_forward in aktmodeswitches) and
  1507. (aktprocsym^.definition^.maxparacount=0)) or
  1508. (equal_paras(aktprocsym^.definition^.para,hd^.para,cp_none) and
  1509. { for operators equal_paras is not enough !! }
  1510. ((aktprocsym^.definition^.proctypeoption<>potype_operator) or (optoken<>_ASSIGNMENT) or
  1511. is_equal(hd^.rettype.def,aktprocsym^.definition^.rettype.def))) then
  1512. begin
  1513. if not equal_paras(aktprocsym^.definition^.para,hd^.para,cp_all) and
  1514. ((m_repeat_forward in aktmodeswitches) or
  1515. (aktprocsym^.definition^.maxparacount>0)) then
  1516. begin
  1517. MessagePos1(aktprocsym^.definition^.fileinfo,parser_e_header_dont_match_forward,
  1518. aktprocsym^.definition^.fullprocname);
  1519. exit;
  1520. end;
  1521. if hd^.forwarddef then
  1522. { remove the forward definition but don't delete it, }
  1523. { the symtable is the owner !! }
  1524. begin
  1525. { Check if the procedure type and return type are correct }
  1526. if (hd^.proctypeoption<>aktprocsym^.definition^.proctypeoption) or
  1527. (not(is_equal(hd^.rettype.def,aktprocsym^.definition^.rettype.def)) and
  1528. (m_repeat_forward in aktmodeswitches)) then
  1529. begin
  1530. MessagePos1(aktprocsym^.definition^.fileinfo,parser_e_header_dont_match_forward,
  1531. aktprocsym^.definition^.fullprocname);
  1532. exit;
  1533. end;
  1534. { Check calling convention, no check for internconst,internproc which
  1535. are only defined in interface or implementation }
  1536. if (hd^.proccalloptions-[pocall_internconst,pocall_internproc]<>
  1537. aktprocsym^.definition^.proccalloptions-[pocall_internconst,pocall_internproc]) then
  1538. begin
  1539. { only trigger an error, becuase it doesn't hurt, for delphi check
  1540. if the current implementation has no proccalloptions, then
  1541. take the options from the interface }
  1542. if (m_delphi in aktmodeswitches) then
  1543. begin
  1544. if (aktprocsym^.definition^.proccalloptions=[]) then
  1545. aktprocsym^.definition^.proccalloptions:=hd^.proccalloptions
  1546. else
  1547. MessagePos(aktprocsym^.definition^.fileinfo,parser_e_call_convention_dont_match_forward);
  1548. end
  1549. else
  1550. MessagePos(aktprocsym^.definition^.fileinfo,parser_e_call_convention_dont_match_forward);
  1551. { set the mangledname to the interface name so it doesn't trigger
  1552. the Note about different manglednames (PFV) }
  1553. aktprocsym^.definition^.setmangledname(hd^.mangledname);
  1554. end;
  1555. { manglednames are equal? }
  1556. hd^.count:=false;
  1557. if (m_repeat_forward in aktmodeswitches) or
  1558. aktprocsym^.definition^.haspara then
  1559. begin
  1560. if (hd^.mangledname<>aktprocsym^.definition^.mangledname) then
  1561. begin
  1562. if not(po_external in aktprocsym^.definition^.procoptions) then
  1563. MessagePos2(aktprocsym^.definition^.fileinfo,parser_n_interface_name_diff_implementation_name,hd^.mangledname,
  1564. aktprocsym^.definition^.mangledname);
  1565. { reset the mangledname of the interface part to be sure }
  1566. { this is wrong because the mangled name might have been used already !! }
  1567. if hd^.is_used then
  1568. renameasmsymbol(hd^.mangledname,aktprocsym^.definition^.mangledname);
  1569. hd^.setmangledname(aktprocsym^.definition^.mangledname);
  1570. { so we need to keep the name of interface !!
  1571. No!!!! The procedure directives can change the mangledname.
  1572. I fixed this by first calling check_identical_proc and then doing
  1573. the proc directives, but this is not a good solution.(DM)}
  1574. { this is also wrong (PM)
  1575. aktprocsym^.definition^.setmangledname(hd^.mangledname);}
  1576. end
  1577. else
  1578. begin
  1579. { If mangled names are equal, therefore }
  1580. { they have the same number of parameters }
  1581. { Therefore we can check the name of these }
  1582. { parameters... }
  1583. if hd^.forwarddef and aktprocsym^.definition^.forwarddef then
  1584. begin
  1585. MessagePos1(aktprocsym^.definition^.fileinfo,
  1586. parser_e_function_already_declared_public_forward,
  1587. aktprocsym^.definition^.fullprocname);
  1588. check_identical_proc:=true;
  1589. { Remove other forward from the list to reduce errors }
  1590. pd^.nextoverloaded:=pd^.nextoverloaded^.nextoverloaded;
  1591. exit;
  1592. end;
  1593. ad:=psym(hd^.parast^.symindex^.first);
  1594. fd:=psym(aktprocsym^.definition^.parast^.symindex^.first);
  1595. if assigned(ad) and assigned(fd) then
  1596. begin
  1597. while assigned(ad) and assigned(fd) do
  1598. begin
  1599. s:=ad^.name;
  1600. if s<>fd^.name then
  1601. begin
  1602. MessagePos3(aktprocsym^.definition^.fileinfo,parser_e_header_different_var_names,
  1603. aktprocsym^.name,s,fd^.name);
  1604. break;
  1605. end;
  1606. { it is impossible to have a nil pointer }
  1607. { for only one parameter - since they }
  1608. { have the same number of parameters. }
  1609. { Left = next parameter. }
  1610. ad:=psym(ad^.left);
  1611. fd:=psym(fd^.left);
  1612. end;
  1613. end;
  1614. end;
  1615. end;
  1616. { also the para_offset }
  1617. hd^.parast^.address_fixup:=aktprocsym^.definition^.parast^.address_fixup;
  1618. hd^.count:=true;
  1619. { remove pd^.nextoverloaded from the list }
  1620. { and add aktprocsym^.definition }
  1621. pd^.nextoverloaded:=pd^.nextoverloaded^.nextoverloaded;
  1622. hd^.nextoverloaded:=aktprocsym^.definition^.nextoverloaded;
  1623. { Alert! All fields of aktprocsym^.definition that are modified
  1624. by the procdir handlers must be copied here!.}
  1625. hd^.forwarddef:=false;
  1626. hd^.hasforward:=true;
  1627. hd^.proccalloptions:=hd^.proccalloptions + aktprocsym^.definition^.proccalloptions;
  1628. hd^.procoptions:=hd^.procoptions + aktprocsym^.definition^.procoptions;
  1629. if aktprocsym^.definition^.extnumber=-1 then
  1630. aktprocsym^.definition^.extnumber:=hd^.extnumber
  1631. else
  1632. if hd^.extnumber=-1 then
  1633. hd^.extnumber:=aktprocsym^.definition^.extnumber;
  1634. { switch parast for warning in implementation PM }
  1635. if (m_repeat_forward in aktmodeswitches) or
  1636. aktprocsym^.definition^.haspara then
  1637. begin
  1638. storeparast:=hd^.parast;
  1639. hd^.parast:=aktprocsym^.definition^.parast;
  1640. aktprocsym^.definition^.parast:=storeparast;
  1641. end;
  1642. if pd=aktprocsym^.definition then
  1643. p:=nil
  1644. else
  1645. p:=pd;
  1646. aktprocsym^.definition:=hd;
  1647. check_identical_proc:=true;
  1648. end
  1649. else
  1650. { abstract methods aren't forward defined, but this }
  1651. { needs another error message }
  1652. if not(po_abstractmethod in pd^.nextoverloaded^.procoptions) then
  1653. MessagePos(aktprocsym^.definition^.fileinfo,parser_e_overloaded_have_same_parameters)
  1654. else
  1655. MessagePos(aktprocsym^.definition^.fileinfo,parser_e_abstract_no_definition);
  1656. break;
  1657. end;
  1658. { check for allowing overload directive }
  1659. if not(m_fpc in aktmodeswitches) then
  1660. begin
  1661. { overload directive turns on overloading }
  1662. if ((po_overload in aktprocsym^.definition^.procoptions) or
  1663. ((po_overload in hd^.procoptions))) then
  1664. begin
  1665. { check if all procs have overloading, but not if the proc was
  1666. already declared forward, then the check is already done }
  1667. if not(hd^.hasforward) and
  1668. (aktprocsym^.definition^.forwarddef=hd^.forwarddef) and
  1669. not((po_overload in aktprocsym^.definition^.procoptions) and
  1670. ((po_overload in hd^.procoptions))) then
  1671. begin
  1672. MessagePos1(aktprocsym^.definition^.fileinfo,parser_e_no_overload_for_all_procs,aktprocsym^.realname);
  1673. break;
  1674. end;
  1675. end
  1676. else
  1677. begin
  1678. if not(hd^.forwarddef) then
  1679. begin
  1680. MessagePos(aktprocsym^.definition^.fileinfo,parser_e_procedure_overloading_is_off);
  1681. break;
  1682. end;
  1683. end;
  1684. end;
  1685. { try next overloaded }
  1686. pd:=pd^.nextoverloaded;
  1687. end;
  1688. end
  1689. else
  1690. begin
  1691. { there is no overloaded, so its always identical with itself }
  1692. check_identical_proc:=true;
  1693. end;
  1694. end;
  1695. { insert opsym only in the right symtable }
  1696. if ((procinfo^.flags and pi_operator)<>0) and assigned(opsym)
  1697. and not parse_only then
  1698. begin
  1699. if ret_in_param(aktprocsym^.definition^.rettype.def) then
  1700. begin
  1701. pprocdef(aktprocsym^.definition)^.parast^.insert(opsym);
  1702. { this increases the data size }
  1703. { correct this to get the right ret $value }
  1704. dec(pprocdef(aktprocsym^.definition)^.parast^.datasize,opsym^.getpushsize);
  1705. { this allows to read the funcretoffset }
  1706. opsym^.address:=-4;
  1707. opsym^.varspez:=vs_var;
  1708. end
  1709. else
  1710. pprocdef(aktprocsym^.definition)^.localst^.insert(opsym);
  1711. end;
  1712. end;
  1713. procedure checkvaluepara(p:pnamedindexobject);
  1714. var
  1715. vs : pvarsym;
  1716. s : string;
  1717. begin
  1718. with pvarsym(p)^ do
  1719. begin
  1720. if copy(name,1,3)='val' then
  1721. begin
  1722. s:=Copy(name,4,255);
  1723. if not(po_assembler in aktprocsym^.definition^.procoptions) then
  1724. begin
  1725. vs:=new(Pvarsym,initdef(s,vartype.def));
  1726. vs^.fileinfo:=fileinfo;
  1727. vs^.varspez:=varspez;
  1728. aktprocsym^.definition^.localst^.insert(vs);
  1729. include(vs^.varoptions,vo_is_local_copy);
  1730. vs^.varstate:=vs_assigned;
  1731. localvarsym:=vs;
  1732. inc(refs); { the para was used to set the local copy ! }
  1733. { warnings only on local copy ! }
  1734. varstate:=vs_used;
  1735. end
  1736. else
  1737. begin
  1738. aktprocsym^.definition^.parast^.rename(name,s);
  1739. end;
  1740. end;
  1741. end;
  1742. end;
  1743. end.
  1744. {
  1745. $Log$
  1746. Revision 1.6 2000-11-04 14:25:20 florian
  1747. + merged Attila's changes for interfaces, not tested yet
  1748. Revision 1.5 2000/11/01 23:04:37 peter
  1749. * tprocdef.fullprocname added for better casesensitve writing of
  1750. procedures
  1751. Revision 1.4 2000/10/31 22:02:49 peter
  1752. * symtable splitted, no real code changes
  1753. Revision 1.3 2000/10/21 18:16:11 florian
  1754. * a lot of changes:
  1755. - basic dyn. array support
  1756. - basic C++ support
  1757. - some work for interfaces done
  1758. ....
  1759. Revision 1.2 2000/10/15 07:47:51 peter
  1760. * unit names and procedure names are stored mixed case
  1761. Revision 1.1 2000/10/14 10:14:51 peter
  1762. * moehrendorf oct 2000 rewrite
  1763. }