pdecsub.pas 76 KB

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