pdecsub.pas 68 KB

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