pdecsub.pas 67 KB

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