pdecsub.pas 74 KB

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