pdecsub.pas 67 KB

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