pdecsub.pas 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.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. procedure parameter_dec(aktprocdef:tabstractprocdef);
  34. procedure parse_proc_directives(var pdflags:word);
  35. procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
  36. procedure calc_parasymtable_addresses(def:tprocdef);
  37. procedure parse_proc_head(options:tproctypeoption);
  38. procedure parse_proc_dec;
  39. procedure parse_var_proc_directives(var sym : tsym);
  40. procedure parse_object_proc_directives(var sym : tprocsym);
  41. function proc_add_definition(aprocsym:tprocsym;var aprocdef : tprocdef) : boolean;
  42. implementation
  43. uses
  44. {$ifdef delphi}
  45. sysutils,
  46. {$else delphi}
  47. strings,
  48. {$endif delphi}
  49. { common }
  50. cutils,cclasses,
  51. { global }
  52. globtype,globals,verbose,
  53. systems,cpubase,
  54. { aasm }
  55. aasmbase,aasmtai,aasmcpu,
  56. { symtable }
  57. symbase,symtable,defbase,paramgr,
  58. { pass 1 }
  59. node,htypechk,
  60. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  61. { parser }
  62. fmodule,scanner,
  63. pbase,pexpr,ptype,pdecl,
  64. { linking }
  65. import,gendef,
  66. { codegen }
  67. cpuinfo,cgbase
  68. ;
  69. procedure resetvaluepara(p:tnamedindexitem;arg:pointer);
  70. begin
  71. if tsym(p).typ=varsym then
  72. with tvarsym(p) do
  73. if copy(name,1,3)='val' then
  74. aktprocdef.parast.symsearch.rename(name,copy(name,4,length(name)));
  75. end;
  76. procedure parameter_dec(aktprocdef:tabstractprocdef);
  77. {
  78. handle_procvar needs the same changes
  79. }
  80. var
  81. is_procvar : boolean;
  82. sc : tsinglelist;
  83. htype,
  84. tt : ttype;
  85. hvs,
  86. vs : tvarsym;
  87. srsym : tsym;
  88. hs1 : string;
  89. varspez : Tvarspez;
  90. inserthigh : boolean;
  91. tdefaultvalue : tconstsym;
  92. defaultrequired : boolean;
  93. old_object_option : tsymoptions;
  94. dummyst : tparasymtable;
  95. currparast : tparasymtable;
  96. begin
  97. consume(_LKLAMMER);
  98. { Delphi/Kylix supports nonsense like }
  99. { procedure p(); }
  100. if try_to_consume(_RKLAMMER) and
  101. not(m_tp7 in aktmodeswitches) then
  102. exit;
  103. { parsing a proc or procvar ? }
  104. is_procvar:=(aktprocdef.deftype=procvardef);
  105. { create dummy symtable for procvars }
  106. if is_procvar then
  107. begin
  108. { we can't insert the dummyst in the symtablestack,
  109. because definitions will be inserted in the symtablestack. And
  110. this symtable is disposed at the end of the parsing, so the
  111. definitions are lost }
  112. dummyst:=tparasymtable.create;
  113. currparast:=dummyst;
  114. end
  115. else
  116. begin
  117. { parast is available, we can insert in symtablestack }
  118. tprocdef(aktprocdef).parast.next:=symtablestack;
  119. symtablestack:=tprocdef(aktprocdef).parast;
  120. currparast:=tparasymtable(tprocdef(aktprocdef).parast);
  121. end;
  122. { reset }
  123. sc:=tsinglelist.create;
  124. defaultrequired:=false;
  125. { the variables are always public }
  126. old_object_option:=current_object_option;
  127. current_object_option:=[sp_public];
  128. inc(testcurobject);
  129. repeat
  130. if try_to_consume(_VAR) then
  131. varspez:=vs_var
  132. else
  133. if try_to_consume(_CONST) then
  134. varspez:=vs_const
  135. else
  136. if (idtoken=_OUT) and (m_out in aktmodeswitches) then
  137. begin
  138. consume(_OUT);
  139. varspez:=vs_out
  140. end
  141. else
  142. varspez:=vs_value;
  143. inserthigh:=false;
  144. tdefaultvalue:=nil;
  145. tt.reset;
  146. { self is only allowed in procvars and class methods }
  147. if (idtoken=_SELF) and
  148. (is_procvar or
  149. (assigned(procinfo._class) and is_class(procinfo._class))) then
  150. begin
  151. if varspez <> vs_value then
  152. CGMessage(parser_e_self_call_by_value);
  153. if not is_procvar then
  154. begin
  155. htype.setdef(procinfo._class);
  156. vs:=tvarsym.create('@',htype);
  157. vs.varspez:=vs_var;
  158. { insert the sym in the parasymtable }
  159. tprocdef(aktprocdef).parast.insert(vs);
  160. inc(procinfo.selfpointer_offset,vs.address);
  161. end
  162. else
  163. vs:=nil;
  164. { must also be included for procvars to allow the proc2procvar }
  165. { type conversions (po_containsself is in po_comp) (JM) }
  166. include(aktprocdef.procoptions,po_containsself);
  167. consume(idtoken);
  168. consume(_COLON);
  169. single_type(tt,hs1,false);
  170. { this must be call-by-value, but we generate already an }
  171. { an error above if that's not the case (JM) }
  172. aktprocdef.concatpara(tt,vs,varspez,nil);
  173. { check the types for procedures only }
  174. if not is_procvar then
  175. CheckTypes(tt.def,procinfo._class);
  176. end
  177. else
  178. begin
  179. { read identifiers and insert with error type }
  180. sc.reset;
  181. repeat
  182. vs:=tvarsym.create(orgpattern,generrortype);
  183. currparast.insert(vs);
  184. sc.insert(vs);
  185. consume(_ID);
  186. until not try_to_consume(_COMMA);
  187. { read type declaration, force reading for value and const paras }
  188. if (token=_COLON) or (varspez=vs_value) then
  189. begin
  190. consume(_COLON);
  191. { check for an open array }
  192. if token=_ARRAY then
  193. begin
  194. consume(_ARRAY);
  195. consume(_OF);
  196. { define range and type of range }
  197. tt.setdef(tarraydef.create(0,-1,s32bittype));
  198. { array of const ? }
  199. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  200. begin
  201. consume(_CONST);
  202. srsym:=searchsymonlyin(systemunit,'TVARREC');
  203. if not assigned(srsym) then
  204. InternalError(1234124);
  205. tarraydef(tt.def).elementtype:=ttypesym(srsym).restype;
  206. tarraydef(tt.def).IsArrayOfConst:=true;
  207. end
  208. else
  209. begin
  210. { define field type }
  211. single_type(tarraydef(tt.def).elementtype,hs1,false);
  212. end;
  213. inserthigh:=true;
  214. end
  215. else
  216. begin
  217. { open string ? }
  218. if (varspez=vs_var) and
  219. (
  220. (
  221. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  222. (cs_openstring in aktmoduleswitches) and
  223. not(cs_ansistrings in aktlocalswitches)
  224. ) or
  225. (idtoken=_OPENSTRING)) then
  226. begin
  227. consume(token);
  228. tt:=openshortstringtype;
  229. hs1:='openstring';
  230. inserthigh:=true;
  231. end
  232. else
  233. begin
  234. { everything else }
  235. single_type(tt,hs1,false);
  236. end;
  237. { default parameter }
  238. if (m_default_para in aktmodeswitches) then
  239. begin
  240. if try_to_consume(_EQUAL) then
  241. begin
  242. vs:=tvarsym(sc.first);
  243. if assigned(vs.listnext) then
  244. Message(parser_e_default_value_only_one_para);
  245. { prefix 'def' to the parameter name }
  246. tdefaultvalue:=ReadConstant('$def'+vs.name,vs.fileinfo);
  247. if assigned(tdefaultvalue) then
  248. tprocdef(aktprocdef).parast.insert(tdefaultvalue);
  249. defaultrequired:=true;
  250. end
  251. else
  252. begin
  253. if defaultrequired then
  254. Message1(parser_e_default_value_expected_for_para,vs.name);
  255. end;
  256. end;
  257. end;
  258. end
  259. else
  260. begin
  261. {$ifndef UseNiceNames}
  262. hs1:='$$$';
  263. {$else UseNiceNames}
  264. hs1:='var';
  265. {$endif UseNiceNames}
  266. tt:=cformaltype;
  267. end;
  268. { For proc vars we only need the definitions }
  269. if not is_procvar then
  270. begin
  271. vs:=tvarsym(sc.first);
  272. while assigned(vs) do
  273. begin
  274. { update varsym }
  275. vs.vartype:=tt;
  276. vs.varspez:=varspez;
  277. if (varspez in [vs_var,vs_const,vs_out]) and
  278. paramanager.push_addr_param(tt.def,false) then
  279. include(vs.varoptions,vo_regable);
  280. { do we need a local copy? Then rename the varsym, do this after the
  281. insert so the dup id checking is done correctly }
  282. if (varspez=vs_value) and
  283. paramanager.push_addr_param(tt.def,aktprocdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  284. not(is_open_array(tt.def) or is_array_of_const(tt.def)) then
  285. currparast.rename(vs.name,'val'+vs.name);
  286. { also need to push a high value? }
  287. if inserthigh then
  288. begin
  289. hvs:=tvarsym.create('$high'+vs.name,s32bittype);
  290. hvs.varspez:=vs_const;
  291. currparast.insert(hvs);
  292. end;
  293. aktprocdef.concatpara(tt,vs,varspez,tdefaultvalue);
  294. vs:=tvarsym(vs.listnext);
  295. end;
  296. end
  297. else
  298. begin
  299. vs:=tvarsym(sc.first);
  300. while assigned(vs) do
  301. begin
  302. { don't insert a parasym, the varsyms will be
  303. disposed }
  304. aktprocdef.concatpara(tt,nil,varspez,tdefaultvalue);
  305. vs:=tvarsym(vs.listnext);
  306. end;
  307. end;
  308. end;
  309. { set the new mangled name }
  310. until not try_to_consume(_SEMICOLON);
  311. { remove parasymtable from stack }
  312. if is_procvar then
  313. dummyst.free
  314. else
  315. symtablestack:=symtablestack.next;
  316. sc.free;
  317. { reset object options }
  318. dec(testcurobject);
  319. current_object_option:=old_object_option;
  320. consume(_RKLAMMER);
  321. end;
  322. procedure parse_proc_head(options:tproctypeoption);
  323. var
  324. orgsp,sp:stringid;
  325. paramoffset:longint;
  326. sym:tsym;
  327. st : tsymtable;
  328. srsymtable : tsymtable;
  329. pdl : pprocdeflist;
  330. storepos,procstartfilepos : tfileposinfo;
  331. i: longint;
  332. begin
  333. { Save the position where this procedure really starts }
  334. procstartfilepos:=akttokenpos;
  335. aktprocdef:=nil;
  336. if (options=potype_operator) then
  337. begin
  338. sp:=overloaded_names[optoken];
  339. orgsp:=sp;
  340. end
  341. else
  342. begin
  343. sp:=pattern;
  344. orgsp:=orgpattern;
  345. consume(_ID);
  346. end;
  347. { examine interface map: function/procedure iname.functionname=locfuncname }
  348. if parse_only and
  349. assigned(procinfo._class) and
  350. assigned(procinfo._class.implementedinterfaces) and
  351. (procinfo._class.implementedinterfaces.count>0) and
  352. try_to_consume(_POINT) then
  353. begin
  354. storepos:=akttokenpos;
  355. akttokenpos:=procstartfilepos;
  356. { get interface syms}
  357. searchsym(sp,sym,srsymtable);
  358. if not assigned(sym) then
  359. begin
  360. identifier_not_found(orgsp);
  361. sym:=generrorsym;
  362. end;
  363. akttokenpos:=storepos;
  364. { load proc name }
  365. if sym.typ=typesym then
  366. i:=procinfo._class.implementedinterfaces.searchintf(ttypesym(sym).restype.def);
  367. { qualifier is interface name? }
  368. if (sym.typ<>typesym) or (ttypesym(sym).restype.def.deftype<>objectdef) or
  369. (i=-1) then
  370. begin
  371. Message(parser_e_interface_id_expected);
  372. aktprocsym:=nil;
  373. end
  374. else
  375. begin
  376. aktprocsym:=tprocsym(procinfo._class.implementedinterfaces.interfaces(i).symtable.search(sp));
  377. { the method can be declared after the mapping FK
  378. if not(assigned(aktprocsym)) then
  379. Message(parser_e_methode_id_expected);
  380. }
  381. end;
  382. consume(_ID);
  383. consume(_EQUAL);
  384. if (token=_ID) { and assigned(aktprocsym) } then
  385. procinfo._class.implementedinterfaces.addmappings(i,sp,pattern);
  386. consume(_ID);
  387. exit;
  388. end;
  389. { method ? }
  390. if not(parse_only) and
  391. (lexlevel=normal_function_level) and
  392. try_to_consume(_POINT) then
  393. begin
  394. { search for object name }
  395. storepos:=akttokenpos;
  396. akttokenpos:=procstartfilepos;
  397. searchsym(sp,sym,srsymtable);
  398. if not assigned(sym) then
  399. begin
  400. identifier_not_found(orgsp);
  401. sym:=generrorsym;
  402. end;
  403. akttokenpos:=storepos;
  404. { consume proc name }
  405. sp:=pattern;
  406. orgsp:=orgpattern;
  407. procstartfilepos:=akttokenpos;
  408. consume(_ID);
  409. { qualifier is class name ? }
  410. if (sym.typ<>typesym) or
  411. (ttypesym(sym).restype.def.deftype<>objectdef) then
  412. begin
  413. Message(parser_e_class_id_expected);
  414. aktprocsym:=nil;
  415. aktprocdef:=nil;
  416. end
  417. else
  418. begin
  419. { used to allow private syms to be seen }
  420. aktobjectdef:=tobjectdef(ttypesym(sym).restype.def);
  421. procinfo._class:=tobjectdef(ttypesym(sym).restype.def);
  422. aktprocsym:=tprocsym(procinfo._class.symtable.search(sp));
  423. {The procedure has been found. So it is
  424. a global one. Set the flags to mark this.}
  425. procinfo.flags:=procinfo.flags or pi_is_global;
  426. aktobjectdef:=nil;
  427. { we solve this below }
  428. if not(assigned(aktprocsym)) then
  429. Message(parser_e_methode_id_expected);
  430. end;
  431. end
  432. else
  433. begin
  434. { check for constructor/destructor which is not allowed here }
  435. if (not parse_only) and
  436. (options in [potype_constructor,potype_destructor]) then
  437. Message(parser_e_constructors_always_objects);
  438. akttokenpos:=procstartfilepos;
  439. aktprocsym:=tprocsym(symtablestack.search(sp));
  440. if not(parse_only) then
  441. begin
  442. {The procedure we prepare for is in the implementation
  443. part of the unit we compile. It is also possible that we
  444. are compiling a program, which is also some kind of
  445. implementaion part.
  446. We need to find out if the procedure is global. If it is
  447. global, it is in the global symtable.}
  448. if not assigned(aktprocsym) and
  449. (symtablestack.symtabletype=staticsymtable) and
  450. assigned(symtablestack.next) and
  451. (symtablestack.next.unitid=0) then
  452. begin
  453. {Search the procedure in the global symtable.}
  454. aktprocsym:=tprocsym(symtablestack.next.search(sp));
  455. if assigned(aktprocsym) then
  456. begin
  457. {Check if it is a procedure.}
  458. if aktprocsym.typ<>procsym then
  459. DuplicateSym(aktprocsym);
  460. {The procedure has been found. So it is
  461. a global one. Set the flags to mark this.}
  462. procinfo.flags:=procinfo.flags or pi_is_global;
  463. end;
  464. end;
  465. end;
  466. end;
  467. if assigned(aktprocsym) then
  468. begin
  469. { Check if overloaded is a procsym }
  470. if aktprocsym.typ<>procsym then
  471. begin
  472. { when the other symbol is a unit symbol then hide the unit
  473. symbol. Only in tp mode because it's bad programming }
  474. if (m_duplicate_names in aktmodeswitches) and
  475. (aktprocsym.typ=unitsym) then
  476. begin
  477. aktprocsym.owner.rename(aktprocsym.name,'hidden'+aktprocsym.name);
  478. end
  479. else
  480. begin
  481. { we use a different error message for tp7 so it looks more compatible }
  482. if (m_fpc in aktmodeswitches) then
  483. Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
  484. else
  485. DuplicateSym(aktprocsym);
  486. { rename the name to an unique name to avoid an
  487. error when inserting the symbol in the symtable }
  488. orgsp:=orgsp+'$'+tostr(aktfilepos.line);
  489. end;
  490. { generate a new aktprocsym }
  491. aktprocsym:=nil;
  492. end;
  493. end;
  494. { test again if assigned, it can be reset to recover }
  495. if not assigned(aktprocsym) then
  496. begin
  497. { create a new procsym and set the real filepos }
  498. akttokenpos:=procstartfilepos;
  499. { for operator we have only one procsym for each overloaded
  500. operation }
  501. if (options=potype_operator) then
  502. begin
  503. { is the current overload sym already in the current unit }
  504. if assigned(overloaded_operators[optoken]) and
  505. (overloaded_operators[optoken].owner=symtablestack) then
  506. aktprocsym:=overloaded_operators[optoken]
  507. else
  508. begin
  509. { create the procsym with saving the original case }
  510. aktprocsym:=tprocsym.create('$'+sp);
  511. if assigned(overloaded_operators[optoken]) then
  512. overloaded_operators[optoken].concat_procdefs_to(aktprocsym);
  513. end;
  514. end
  515. else
  516. aktprocsym:=tprocsym.create(orgsp);
  517. symtablestack.insert(aktprocsym);
  518. end;
  519. st:=symtablestack;
  520. aktprocdef:=tprocdef.create;
  521. aktprocdef.symtablelevel:=symtablestack.symtablelevel;
  522. if assigned(procinfo._class) then
  523. aktprocdef._class := procinfo._class;
  524. { set the options from the caller (podestructor or poconstructor) }
  525. aktprocdef.proctypeoption:=options;
  526. { add procsym to the procdef }
  527. aktprocdef.procsym:=aktprocsym;
  528. { save file position }
  529. aktprocdef.fileinfo:=procstartfilepos;
  530. { this must also be inserted in the right symtable !! PM }
  531. { otherwise we get subbtle problems with
  532. definitions of args defs in staticsymtable for
  533. implementation of a global method }
  534. if token=_LKLAMMER then
  535. parameter_dec(aktprocdef);
  536. { calculate the offset of the parameters }
  537. paramoffset:=target_info.first_parm_offset;
  538. { calculate frame pointer offset }
  539. if lexlevel>normal_function_level then
  540. begin
  541. procinfo.framepointer_offset:=paramoffset;
  542. inc(paramoffset,pointer_size);
  543. { this is needed to get correct framepointer push for local
  544. forward functions !! }
  545. aktprocdef.parast.symtablelevel:=lexlevel;
  546. end;
  547. if assigned (procinfo._Class) and
  548. is_object(procinfo._Class) and
  549. (aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) then
  550. inc(paramoffset,pointer_size);
  551. { self pointer offset, must be done after parsing the parameters }
  552. { self isn't pushed in nested procedure of methods }
  553. if assigned(procinfo._class) and (lexlevel=normal_function_level) then
  554. begin
  555. procinfo.selfpointer_offset:=paramoffset;
  556. if assigned(aktprocdef) and
  557. not(po_containsself in aktprocdef.procoptions) then
  558. inc(paramoffset,pointer_size);
  559. end;
  560. { con/-destructor flag ? }
  561. if assigned (procinfo._Class) and
  562. is_class(procinfo._class) and
  563. (aktprocdef.proctypeoption in [potype_destructor,potype_constructor]) then
  564. inc(paramoffset,pointer_size);
  565. procinfo.para_offset:=paramoffset;
  566. { so we only restore the symtable now }
  567. symtablestack:=st;
  568. if (options=potype_operator) then
  569. overloaded_operators[optoken]:=aktprocsym;
  570. end;
  571. procedure parse_proc_dec;
  572. var
  573. hs : string;
  574. isclassmethod : boolean;
  575. begin
  576. inc(lexlevel);
  577. { read class method }
  578. if token=_CLASS then
  579. begin
  580. consume(_CLASS);
  581. isclassmethod:=true;
  582. end
  583. else
  584. isclassmethod:=false;
  585. case token of
  586. _FUNCTION : begin
  587. consume(_FUNCTION);
  588. parse_proc_head(potype_none);
  589. if token<>_COLON then
  590. begin
  591. if assigned(aktprocsym) and
  592. not(is_interface(aktprocdef._class)) and
  593. not(aktprocdef.forwarddef) or
  594. (m_repeat_forward in aktmodeswitches) then
  595. begin
  596. consume(_COLON);
  597. consume_all_until(_SEMICOLON);
  598. end;
  599. end
  600. else
  601. begin
  602. consume(_COLON);
  603. inc(testcurobject);
  604. single_type(aktprocdef.rettype,hs,false);
  605. aktprocdef.test_if_fpu_result;
  606. dec(testcurobject);
  607. end;
  608. end;
  609. _PROCEDURE : begin
  610. consume(_PROCEDURE);
  611. parse_proc_head(potype_none);
  612. if assigned(aktprocsym) then
  613. aktprocdef.rettype:=voidtype;
  614. end;
  615. _CONSTRUCTOR : begin
  616. consume(_CONSTRUCTOR);
  617. parse_proc_head(potype_constructor);
  618. if assigned(procinfo._class) and
  619. is_class(procinfo._class) then
  620. begin
  621. { CLASS constructors return the created instance }
  622. aktprocdef.rettype.setdef(procinfo._class);
  623. end
  624. else
  625. begin
  626. { OBJECT constructors return a boolean }
  627. aktprocdef.rettype:=booltype;
  628. end;
  629. end;
  630. _DESTRUCTOR : begin
  631. consume(_DESTRUCTOR);
  632. parse_proc_head(potype_destructor);
  633. aktprocdef.rettype:=voidtype;
  634. end;
  635. _OPERATOR : begin
  636. if lexlevel>normal_function_level then
  637. Message(parser_e_no_local_operator);
  638. consume(_OPERATOR);
  639. if (token in [first_overloaded..last_overloaded]) then
  640. begin
  641. procinfo.flags:=procinfo.flags or pi_operator;
  642. optoken:=token;
  643. end
  644. else
  645. begin
  646. Message(parser_e_overload_operator_failed);
  647. { Use the dummy NOTOKEN that is also declared
  648. for the overloaded_operator[] }
  649. optoken:=NOTOKEN;
  650. end;
  651. consume(Token);
  652. parse_proc_head(potype_operator);
  653. if token<>_ID then
  654. begin
  655. otsym:=nil;
  656. if not(m_result in aktmodeswitches) then
  657. consume(_ID);
  658. end
  659. else
  660. begin
  661. otsym:=tvarsym.create(pattern,voidtype);
  662. consume(_ID);
  663. end;
  664. if not try_to_consume(_COLON) then
  665. begin
  666. consume(_COLON);
  667. aktprocdef.rettype:=generrortype;
  668. consume_all_until(_SEMICOLON);
  669. end
  670. else
  671. begin
  672. single_type(aktprocdef.rettype,hs,false);
  673. aktprocdef.test_if_fpu_result;
  674. if (optoken in [_EQUAL,_GT,_LT,_GTE,_LTE]) and
  675. ((aktprocdef.rettype.def.deftype<>orddef) or
  676. (torddef(aktprocdef.rettype.def).typ<>bool8bit)) then
  677. Message(parser_e_comparative_operator_return_boolean);
  678. if assigned(otsym) then
  679. otsym.vartype.def:=aktprocdef.rettype.def;
  680. if (optoken=_ASSIGNMENT) and
  681. is_equal(aktprocdef.rettype.def,
  682. tvarsym(aktprocdef.parast.symindex.first).vartype.def) then
  683. message(parser_e_no_such_assignment)
  684. else if not isoperatoracceptable(aktprocdef,optoken) then
  685. Message(parser_e_overload_impossible);
  686. end;
  687. end;
  688. end;
  689. if isclassmethod and
  690. assigned(aktprocsym) then
  691. include(aktprocdef.procoptions,po_classmethod);
  692. { support procedure proc;stdcall export; in Delphi mode only }
  693. if not((m_delphi in aktmodeswitches) and
  694. is_proc_directive(token)) then
  695. consume(_SEMICOLON);
  696. dec(lexlevel);
  697. end;
  698. {****************************************************************************
  699. Procedure directive handlers
  700. ****************************************************************************}
  701. procedure pd_far;
  702. begin
  703. Message(parser_w_proc_far_ignored);
  704. end;
  705. procedure pd_near;
  706. begin
  707. Message(parser_w_proc_near_ignored);
  708. end;
  709. procedure pd_export;
  710. begin
  711. if assigned(procinfo._class) then
  712. Message(parser_e_methods_dont_be_export);
  713. if lexlevel<>normal_function_level then
  714. Message(parser_e_dont_nest_export);
  715. { only os/2 needs this }
  716. if target_info.system=system_i386_os2 then
  717. begin
  718. aktprocdef.aliasnames.insert(aktprocsym.realname);
  719. procinfo.exported:=true;
  720. if cs_link_deffile in aktglobalswitches then
  721. deffile.AddExport(aktprocdef.mangledname);
  722. end;
  723. end;
  724. procedure pd_forward;
  725. begin
  726. aktprocdef.forwarddef:=true;
  727. end;
  728. procedure pd_alias;
  729. begin
  730. consume(_COLON);
  731. aktprocdef.aliasnames.insert(get_stringconst);
  732. end;
  733. procedure pd_asmname;
  734. begin
  735. aktprocdef.setmangledname(target_info.Cprefix+pattern);
  736. aktprocdef.has_mangledname:=true;
  737. if token=_CCHAR then
  738. consume(_CCHAR)
  739. else
  740. consume(_CSTRING);
  741. { we don't need anything else }
  742. aktprocdef.forwarddef:=false;
  743. end;
  744. procedure pd_intern;
  745. begin
  746. consume(_COLON);
  747. aktprocdef.extnumber:=get_intconst;
  748. end;
  749. procedure pd_interrupt;
  750. begin
  751. if lexlevel<>normal_function_level then
  752. Message(parser_e_dont_nest_interrupt);
  753. end;
  754. procedure pd_abstract;
  755. begin
  756. if (po_virtualmethod in aktprocdef.procoptions) then
  757. include(aktprocdef.procoptions,po_abstractmethod)
  758. else
  759. Message(parser_e_only_virtual_methods_abstract);
  760. { the method is defined }
  761. aktprocdef.forwarddef:=false;
  762. end;
  763. procedure pd_virtual;
  764. {$ifdef WITHDMT}
  765. var
  766. pt : tnode;
  767. {$endif WITHDMT}
  768. begin
  769. if (aktprocdef.proctypeoption=potype_constructor) and
  770. is_object(aktprocdef._class) then
  771. Message(parser_e_constructor_cannot_be_not_virtual);
  772. {$ifdef WITHDMT}
  773. if is_object(aktprocdef._class) and
  774. (token<>_SEMICOLON) then
  775. begin
  776. { any type of parameter is allowed here! }
  777. pt:=comp_expr(true);
  778. if is_constintnode(pt) then
  779. begin
  780. include(aktprocdef.procoptions,po_msgint);
  781. aktprocdef.messageinf.i:=pt^.value;
  782. end
  783. else
  784. Message(parser_e_ill_msg_expr);
  785. disposetree(pt);
  786. end;
  787. {$endif WITHDMT}
  788. end;
  789. procedure pd_static;
  790. begin
  791. if (cs_static_keyword in aktmoduleswitches) then
  792. begin
  793. include(aktprocsym.symoptions,sp_static);
  794. include(aktprocdef.procoptions,po_staticmethod);
  795. end;
  796. end;
  797. procedure pd_override;
  798. begin
  799. if not(is_class_or_interface(aktprocdef._class)) then
  800. Message(parser_e_no_object_override);
  801. end;
  802. procedure pd_overload;
  803. begin
  804. include(aktprocsym.symoptions,sp_has_overloaded);
  805. end;
  806. procedure pd_message;
  807. var
  808. pt : tnode;
  809. begin
  810. { check parameter type }
  811. if not(po_containsself in aktprocdef.procoptions) and
  812. ((aktprocdef.minparacount<>1) or
  813. (aktprocdef.maxparacount<>1) or
  814. (TParaItem(aktprocdef.Para.first).paratyp<>vs_var)) then
  815. Message(parser_e_ill_msg_param);
  816. pt:=comp_expr(true);
  817. if pt.nodetype=stringconstn then
  818. begin
  819. include(aktprocdef.procoptions,po_msgstr);
  820. aktprocdef.messageinf.str:=strnew(tstringconstnode(pt).value_str);
  821. end
  822. else
  823. if is_constintnode(pt) then
  824. begin
  825. include(aktprocdef.procoptions,po_msgint);
  826. aktprocdef.messageinf.i:=tordconstnode(pt).value;
  827. end
  828. else
  829. Message(parser_e_ill_msg_expr);
  830. pt.free;
  831. end;
  832. procedure pd_reintroduce;
  833. begin
  834. Message1(parser_w_proc_directive_ignored,'REINTRODUCE');
  835. end;
  836. procedure pd_syscall;
  837. begin
  838. aktprocdef.forwarddef:=false;
  839. aktprocdef.extnumber:=get_intconst;
  840. end;
  841. procedure pd_external;
  842. {
  843. If import_dll=nil the procedure is assumed to be in another
  844. object file. In that object file it should have the name to
  845. which import_name is pointing to. Otherwise, the procedure is
  846. assumed to be in the DLL to which import_dll is pointing to. In
  847. that case either import_nr<>0 or import_name<>nil is true, so
  848. the procedure is either imported by number or by name. (DM)
  849. }
  850. var
  851. import_dll,
  852. import_name : string;
  853. import_nr : word;
  854. begin
  855. aktprocdef.forwarddef:=false;
  856. { forbid local external procedures }
  857. if lexlevel>normal_function_level then
  858. Message(parser_e_no_local_external);
  859. { If the procedure should be imported from a DLL, a constant string follows.
  860. This isn't really correct, an contant string expression follows
  861. so we check if an semicolon follows, else a string constant have to
  862. follow (FK) }
  863. import_nr:=0;
  864. import_name:='';
  865. if not(token=_SEMICOLON) and not(idtoken=_NAME) then
  866. begin
  867. import_dll:=get_stringconst;
  868. if (idtoken=_NAME) then
  869. begin
  870. consume(_NAME);
  871. import_name:=get_stringconst;
  872. end;
  873. if (idtoken=_INDEX) then
  874. begin
  875. {After the word index follows the index number in the DLL.}
  876. consume(_INDEX);
  877. import_nr:=get_intconst;
  878. end;
  879. { default is to used the realname of the procedure }
  880. if (import_nr=0) and (import_name='') then
  881. import_name:=aktprocsym.realname;
  882. { create importlib if not already done }
  883. if not(current_module.uses_imports) then
  884. begin
  885. current_module.uses_imports:=true;
  886. importlib.preparelib(current_module.modulename^);
  887. end;
  888. {$ifdef notused}
  889. if not(m_repeat_forward in aktmodeswitches) and
  890. { if the procedure is declared with the overload option }
  891. { it requires a full declaration in the implementation part }
  892. not(sp_has_overloaded in aktprocsym.symoptions) then
  893. begin
  894. { we can only have one overloaded here ! }
  895. if assigned(aktprocdef.defs.next) then
  896. importlib.importprocedure(aktprocdef.defs.next.mangledname,
  897. import_dll,import_nr,import_name)
  898. else
  899. importlib.importprocedure(aktprocdef.mangledname,import_dll,import_nr,import_name);
  900. end
  901. else
  902. {$endif notused}
  903. importlib.importprocedure(aktprocdef.mangledname,import_dll,import_nr,import_name);
  904. end
  905. else
  906. begin
  907. if (idtoken=_NAME) then
  908. begin
  909. consume(_NAME);
  910. import_name:=get_stringconst;
  911. aktprocdef.setmangledname(import_name);
  912. aktprocdef.has_mangledname:=true;
  913. end;
  914. end;
  915. end;
  916. type
  917. pd_handler=procedure;
  918. proc_dir_rec=record
  919. idtok : ttoken;
  920. pd_flags : longint;
  921. handler : pd_handler;
  922. pocall : tproccalloption;
  923. pooption : tprocoptions;
  924. mutexclpocall : tproccalloptions;
  925. mutexclpotype : tproctypeoptions;
  926. mutexclpo : tprocoptions;
  927. end;
  928. const
  929. {Should contain the number of procedure directives we support.}
  930. num_proc_directives=36;
  931. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  932. (
  933. (
  934. idtok:_ABSTRACT;
  935. pd_flags : pd_interface+pd_object+pd_notobjintf;
  936. handler : {$ifdef FPCPROCVAR}@{$endif}pd_abstract;
  937. pocall : pocall_none;
  938. pooption : [po_abstractmethod];
  939. mutexclpocall : [pocall_internproc,pocall_inline];
  940. mutexclpotype : [potype_constructor,potype_destructor];
  941. mutexclpo : [po_exports,po_interrupt,po_external]
  942. ),(
  943. idtok:_ALIAS;
  944. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  945. handler : {$ifdef FPCPROCVAR}@{$endif}pd_alias;
  946. pocall : pocall_none;
  947. pooption : [];
  948. mutexclpocall : [pocall_inline];
  949. mutexclpotype : [];
  950. mutexclpo : [po_external]
  951. ),(
  952. idtok:_ASMNAME;
  953. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  954. handler : {$ifdef FPCPROCVAR}@{$endif}pd_asmname;
  955. pocall : pocall_cdecl;
  956. pooption : [po_external];
  957. mutexclpocall : [pocall_internproc,pocall_inline];
  958. mutexclpotype : [];
  959. mutexclpo : [po_external]
  960. ),(
  961. idtok:_ASSEMBLER;
  962. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  963. handler : nil;
  964. pocall : pocall_none;
  965. pooption : [po_assembler];
  966. mutexclpocall : [];
  967. mutexclpotype : [];
  968. mutexclpo : [po_external]
  969. ),(
  970. idtok:_CDECL;
  971. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  972. handler : nil;
  973. pocall : pocall_cdecl;
  974. pooption : [];
  975. mutexclpocall : [];
  976. mutexclpotype : [];
  977. mutexclpo : [po_assembler,po_external]
  978. ),(
  979. idtok:_DYNAMIC;
  980. pd_flags : pd_interface+pd_object+pd_notobjintf;
  981. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  982. pocall : pocall_none;
  983. pooption : [po_virtualmethod];
  984. mutexclpocall : [pocall_internproc,pocall_inline];
  985. mutexclpotype : [];
  986. mutexclpo : [po_exports,po_interrupt,po_external]
  987. ),(
  988. idtok:_EXPORT;
  989. pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??}+pd_notobjintf;
  990. handler : {$ifdef FPCPROCVAR}@{$endif}pd_export;
  991. pocall : pocall_none;
  992. pooption : [po_exports];
  993. mutexclpocall : [pocall_internproc,pocall_inline];
  994. mutexclpotype : [];
  995. mutexclpo : [po_external,po_interrupt]
  996. ),(
  997. idtok:_EXTERNAL;
  998. pd_flags : pd_implemen+pd_interface+pd_notobjintf;
  999. handler : {$ifdef FPCPROCVAR}@{$endif}pd_external;
  1000. pocall : pocall_none;
  1001. pooption : [po_external];
  1002. mutexclpocall : [pocall_internproc,pocall_inline,pocall_palmossyscall];
  1003. mutexclpotype : [];
  1004. mutexclpo : [po_exports,po_interrupt,po_assembler]
  1005. ),(
  1006. idtok:_FAR;
  1007. pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar+pd_notobjintf;
  1008. handler : {$ifdef FPCPROCVAR}@{$endif}pd_far;
  1009. pocall : pocall_none;
  1010. pooption : [];
  1011. mutexclpocall : [pocall_internproc,pocall_inline];
  1012. mutexclpotype : [];
  1013. mutexclpo : []
  1014. ),(
  1015. idtok:_FAR16;
  1016. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1017. handler : nil;
  1018. pocall : pocall_far16;
  1019. pooption : [];
  1020. mutexclpocall : [];
  1021. mutexclpotype : [];
  1022. mutexclpo : [po_external,po_leftright]
  1023. ),(
  1024. idtok:_FORWARD;
  1025. pd_flags : pd_implemen+pd_notobjintf;
  1026. handler : {$ifdef FPCPROCVAR}@{$endif}pd_forward;
  1027. pocall : pocall_none;
  1028. pooption : [];
  1029. mutexclpocall : [pocall_internproc,pocall_inline];
  1030. mutexclpotype : [];
  1031. mutexclpo : [po_external]
  1032. ),(
  1033. idtok:_FPCCALL;
  1034. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1035. handler : nil;
  1036. pocall : pocall_fpccall;
  1037. pooption : [];
  1038. mutexclpocall : [];
  1039. mutexclpotype : [];
  1040. mutexclpo : [po_leftright]
  1041. ),(
  1042. idtok:_INLINE;
  1043. pd_flags : pd_interface+pd_implemen+pd_body+pd_notobjintf;
  1044. handler : nil;
  1045. pocall : pocall_inline;
  1046. pooption : [];
  1047. mutexclpocall : [];
  1048. mutexclpotype : [potype_constructor,potype_destructor];
  1049. mutexclpo : [po_exports,po_external,po_interrupt]
  1050. ),(
  1051. idtok:_INTERNCONST;
  1052. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1053. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1054. pocall : pocall_none;
  1055. pooption : [po_internconst];
  1056. mutexclpocall : [];
  1057. mutexclpotype : [potype_operator];
  1058. mutexclpo : []
  1059. ),(
  1060. idtok:_INTERNPROC;
  1061. pd_flags : pd_implemen+pd_notobjintf;
  1062. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1063. pocall : pocall_internproc;
  1064. pooption : [];
  1065. mutexclpocall : [];
  1066. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1067. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_leftright]
  1068. ),(
  1069. idtok:_INTERRUPT;
  1070. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1071. handler : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
  1072. pocall : pocall_none;
  1073. pooption : [po_interrupt];
  1074. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,
  1075. pocall_inline,pocall_pascal,pocall_system,pocall_far16,pocall_fpccall];
  1076. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1077. mutexclpo : [po_external,po_leftright,po_clearstack]
  1078. ),(
  1079. idtok:_IOCHECK;
  1080. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1081. handler : nil;
  1082. pocall : pocall_none;
  1083. pooption : [po_iocheck];
  1084. mutexclpocall : [pocall_internproc];
  1085. mutexclpotype : [];
  1086. mutexclpo : [po_external]
  1087. ),(
  1088. idtok:_MESSAGE;
  1089. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1090. handler : {$ifdef FPCPROCVAR}@{$endif}pd_message;
  1091. pocall : pocall_none;
  1092. pooption : []; { can be po_msgstr or po_msgint }
  1093. mutexclpocall : [pocall_inline,pocall_internproc];
  1094. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1095. mutexclpo : [po_interrupt,po_external]
  1096. ),(
  1097. idtok:_NEAR;
  1098. pd_flags : pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1099. handler : {$ifdef FPCPROCVAR}@{$endif}pd_near;
  1100. pocall : pocall_none;
  1101. pooption : [];
  1102. mutexclpocall : [pocall_internproc];
  1103. mutexclpotype : [];
  1104. mutexclpo : []
  1105. ),(
  1106. idtok:_OVERLOAD;
  1107. pd_flags : pd_implemen+pd_interface+pd_body;
  1108. handler : {$ifdef FPCPROCVAR}@{$endif}pd_overload;
  1109. pocall : pocall_none;
  1110. pooption : [po_overload];
  1111. mutexclpocall : [pocall_internproc];
  1112. mutexclpotype : [];
  1113. mutexclpo : []
  1114. ),(
  1115. idtok:_OVERRIDE;
  1116. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1117. handler : {$ifdef FPCPROCVAR}@{$endif}pd_override;
  1118. pocall : pocall_none;
  1119. pooption : [po_overridingmethod,po_virtualmethod];
  1120. mutexclpocall : [pocall_inline,pocall_internproc];
  1121. mutexclpotype : [];
  1122. mutexclpo : [po_exports,po_external,po_interrupt]
  1123. ),(
  1124. idtok:_PASCAL;
  1125. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1126. handler : nil;
  1127. pocall : pocall_pascal;
  1128. pooption : [];
  1129. mutexclpocall : [];
  1130. mutexclpotype : [];
  1131. mutexclpo : [po_external]
  1132. ),(
  1133. idtok:_POPSTACK;
  1134. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1135. handler : nil;
  1136. pocall : pocall_none;
  1137. pooption : [po_clearstack];
  1138. mutexclpocall : [pocall_inline,pocall_internproc,pocall_stdcall];
  1139. mutexclpotype : [];
  1140. mutexclpo : [po_assembler,po_external]
  1141. ),(
  1142. idtok:_PUBLIC;
  1143. pd_flags : pd_implemen+pd_body+pd_global+pd_notobject+pd_notobjintf;
  1144. handler : nil;
  1145. pocall : pocall_none;
  1146. pooption : [];
  1147. mutexclpocall : [pocall_internproc,pocall_inline];
  1148. mutexclpotype : [];
  1149. mutexclpo : [po_external]
  1150. ),(
  1151. idtok:_REGISTER;
  1152. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1153. handler : nil;
  1154. pocall : pocall_register;
  1155. pooption : [];
  1156. mutexclpocall : [];
  1157. mutexclpotype : [];
  1158. mutexclpo : [po_external]
  1159. ),(
  1160. idtok:_REINTRODUCE;
  1161. pd_flags : pd_interface+pd_object;
  1162. handler : {$ifdef FPCPROCVAR}@{$endif}pd_reintroduce;
  1163. pocall : pocall_none;
  1164. pooption : [];
  1165. mutexclpocall : [];
  1166. mutexclpotype : [];
  1167. mutexclpo : []
  1168. ),(
  1169. idtok:_SAFECALL;
  1170. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1171. handler : nil;
  1172. pocall : pocall_safecall;
  1173. pooption : [];
  1174. mutexclpocall : [];
  1175. mutexclpotype : [];
  1176. mutexclpo : [po_external]
  1177. ),(
  1178. idtok:_SAVEREGISTERS;
  1179. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1180. handler : nil;
  1181. pocall : pocall_none;
  1182. pooption : [po_saveregisters];
  1183. mutexclpocall : [pocall_internproc];
  1184. mutexclpotype : [];
  1185. mutexclpo : [po_external]
  1186. ),(
  1187. idtok:_STATIC;
  1188. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1189. handler : {$ifdef FPCPROCVAR}@{$endif}pd_static;
  1190. pocall : pocall_none;
  1191. pooption : [po_staticmethod];
  1192. mutexclpocall : [pocall_inline,pocall_internproc];
  1193. mutexclpotype : [potype_constructor,potype_destructor];
  1194. mutexclpo : [po_external,po_interrupt,po_exports]
  1195. ),(
  1196. idtok:_STDCALL;
  1197. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1198. handler : nil;
  1199. pocall : pocall_stdcall;
  1200. pooption : [];
  1201. mutexclpocall : [];
  1202. mutexclpotype : [];
  1203. mutexclpo : [po_external]
  1204. ),(
  1205. idtok:_SYSCALL;
  1206. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  1207. handler : {$ifdef FPCPROCVAR}@{$endif}pd_syscall;
  1208. pocall : pocall_palmossyscall;
  1209. pooption : [];
  1210. mutexclpocall : [];
  1211. mutexclpotype : [];
  1212. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  1213. ),(
  1214. idtok:_SYSTEM;
  1215. pd_flags : pd_implemen+pd_notobjintf;
  1216. handler : nil;
  1217. pocall : pocall_system;
  1218. pooption : [];
  1219. mutexclpocall : [];
  1220. mutexclpotype : [];
  1221. mutexclpo : [po_external,po_assembler,po_interrupt]
  1222. ),(
  1223. idtok:_VIRTUAL;
  1224. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1225. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  1226. pocall : pocall_none;
  1227. pooption : [po_virtualmethod];
  1228. mutexclpocall : [pocall_inline,pocall_internproc];
  1229. mutexclpotype : [];
  1230. mutexclpo : [po_external,po_interrupt,po_exports]
  1231. ),(
  1232. idtok:_CPPDECL;
  1233. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1234. handler : nil;
  1235. pocall : pocall_cppdecl;
  1236. pooption : [po_savestdregs];
  1237. mutexclpocall : [];
  1238. mutexclpotype : [];
  1239. mutexclpo : [po_assembler,po_external]
  1240. ),(
  1241. idtok:_VARARGS;
  1242. pd_flags : pd_interface+pd_implemen+pd_procvar;
  1243. handler : nil;
  1244. pocall : pocall_none;
  1245. pooption : [po_varargs];
  1246. mutexclpocall : [pocall_internproc,pocall_stdcall,pocall_register,
  1247. pocall_inline,pocall_far16,pocall_fpccall];
  1248. mutexclpotype : [];
  1249. mutexclpo : [po_assembler,po_interrupt,po_leftright]
  1250. ),(
  1251. idtok:_COMPILERPROC;
  1252. pd_flags : pd_interface+pd_implemen+pd_body+pd_notobjintf;
  1253. handler : nil;
  1254. pocall : pocall_compilerproc;
  1255. pooption : [];
  1256. mutexclpocall : [];
  1257. mutexclpotype : [];
  1258. mutexclpo : [po_interrupt]
  1259. )
  1260. );
  1261. function is_proc_directive(tok:ttoken):boolean;
  1262. var
  1263. i : longint;
  1264. begin
  1265. is_proc_directive:=false;
  1266. for i:=1 to num_proc_directives do
  1267. if proc_direcdata[i].idtok=idtoken then
  1268. begin
  1269. is_proc_directive:=true;
  1270. exit;
  1271. end;
  1272. end;
  1273. function parse_proc_direc(var pdflags:word):boolean;
  1274. {
  1275. Parse the procedure directive, returns true if a correct directive is found
  1276. }
  1277. var
  1278. p : longint;
  1279. found : boolean;
  1280. name : stringid;
  1281. begin
  1282. parse_proc_direc:=false;
  1283. name:=tokeninfo^[idtoken].str;
  1284. found:=false;
  1285. { Hint directive? Then exit immediatly }
  1286. if (m_hintdirective in aktmodeswitches) then
  1287. begin
  1288. case idtoken of
  1289. _LIBRARY,
  1290. _PLATFORM,
  1291. _DEPRECATED :
  1292. exit;
  1293. end;
  1294. end;
  1295. { retrieve data for directive if found }
  1296. for p:=1 to num_proc_directives do
  1297. if proc_direcdata[p].idtok=idtoken then
  1298. begin
  1299. found:=true;
  1300. break;
  1301. end;
  1302. { Check if the procedure directive is known }
  1303. if not found then
  1304. begin
  1305. { parsing a procvar type the name can be any
  1306. next variable !! }
  1307. if (pdflags and (pd_procvar or pd_object))=0 then
  1308. Message1(parser_w_unknown_proc_directive_ignored,name);
  1309. exit;
  1310. end;
  1311. { static needs a special treatment }
  1312. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  1313. exit;
  1314. { Conflicts between directives ? }
  1315. if (aktprocdef.proctypeoption in proc_direcdata[p].mutexclpotype) or
  1316. (aktprocdef.proccalloption in proc_direcdata[p].mutexclpocall) or
  1317. ((aktprocdef.procoptions*proc_direcdata[p].mutexclpo)<>[]) then
  1318. begin
  1319. Message1(parser_e_proc_dir_conflict,name);
  1320. exit;
  1321. end;
  1322. { set calling convention }
  1323. if proc_direcdata[p].pocall<>pocall_none then
  1324. begin
  1325. if aktprocdef.proccalloption<>pocall_none then
  1326. begin
  1327. Message2(parser_w_proc_overriding_calling,
  1328. proccalloptionStr[aktprocdef.proccalloption],
  1329. proccalloptionStr[proc_direcdata[p].pocall]);
  1330. end;
  1331. aktprocdef.proccalloption:=proc_direcdata[p].pocall;
  1332. end;
  1333. { check if method and directive not for object, like public.
  1334. This needs to be checked also for procvars }
  1335. if ((proc_direcdata[p].pd_flags and pd_notobject)<>0) and
  1336. (aktprocdef.owner.symtabletype=objectsymtable) then
  1337. exit;
  1338. if aktprocdef.deftype=procdef then
  1339. begin
  1340. { Check if the directive is only for objects }
  1341. if ((proc_direcdata[p].pd_flags and pd_object)<>0) and
  1342. not assigned(aktprocdef._class) then
  1343. exit;
  1344. { check if method and directive not for interface }
  1345. if ((proc_direcdata[p].pd_flags and pd_notobjintf)<>0) and
  1346. is_interface(aktprocdef._class) then
  1347. exit;
  1348. end;
  1349. { consume directive, and turn flag on }
  1350. consume(token);
  1351. parse_proc_direc:=true;
  1352. { Check the pd_flags if the directive should be allowed }
  1353. if ((pdflags and pd_interface)<>0) and
  1354. ((proc_direcdata[p].pd_flags and pd_interface)=0) then
  1355. begin
  1356. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1357. exit;
  1358. end;
  1359. if ((pdflags and pd_implemen)<>0) and
  1360. ((proc_direcdata[p].pd_flags and pd_implemen)=0) then
  1361. begin
  1362. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1363. exit;
  1364. end;
  1365. if ((pdflags and pd_procvar)<>0) and
  1366. ((proc_direcdata[p].pd_flags and pd_procvar)=0) then
  1367. begin
  1368. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1369. exit;
  1370. end;
  1371. { Return the new pd_flags }
  1372. if (proc_direcdata[p].pd_flags and pd_body)=0 then
  1373. pdflags:=pdflags and (not pd_body);
  1374. if (proc_direcdata[p].pd_flags and pd_global)<>0 then
  1375. pdflags:=pdflags or pd_global;
  1376. { Add the correct flag }
  1377. aktprocdef.procoptions:=aktprocdef.procoptions+proc_direcdata[p].pooption;
  1378. { Call the handler }
  1379. if pointer({$ifndef FPCPROCVAR}@{$endif}proc_direcdata[p].handler)<>nil then
  1380. proc_direcdata[p].handler{$ifdef FPCPROCVAR}(){$endif};
  1381. end;
  1382. procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
  1383. begin
  1384. { set the default calling convention }
  1385. if def.proccalloption=pocall_none then
  1386. def.proccalloption:=aktdefproccall;
  1387. case def.proccalloption of
  1388. pocall_cdecl :
  1389. begin
  1390. { use popstack and save std registers }
  1391. include(def.procoptions,po_clearstack);
  1392. include(def.procoptions,po_savestdregs);
  1393. { set mangledname }
  1394. if (def.deftype=procdef) then
  1395. begin
  1396. if not tprocdef(def).has_mangledname then
  1397. begin
  1398. if assigned(tprocdef(def)._class) then
  1399. tprocdef(def).setmangledname(target_info.Cprefix+tprocdef(def)._class.objrealname^+'_'+sym.realname)
  1400. else
  1401. tprocdef(def).setmangledname(target_info.Cprefix+sym.realname);
  1402. end;
  1403. if not assigned(tprocdef(def).parast) then
  1404. internalerror(200110234);
  1405. { do not copy on local !! }
  1406. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
  1407. { Adjust alignment to match cdecl or stdcall }
  1408. tprocdef(def).parast.dataalignment:=std_param_align;
  1409. end;
  1410. end;
  1411. pocall_cppdecl :
  1412. begin
  1413. if not assigned(sym) then
  1414. internalerror(200110231);
  1415. { use popstack and save std registers }
  1416. include(def.procoptions,po_clearstack);
  1417. include(def.procoptions,po_savestdregs);
  1418. { set mangledname }
  1419. if (def.deftype=procdef) then
  1420. begin
  1421. if not tprocdef(def).has_mangledname then
  1422. tprocdef(def).setmangledname(target_info.Cprefix+tprocdef(def).cplusplusmangledname);
  1423. if not assigned(tprocdef(def).parast) then
  1424. internalerror(200110235);
  1425. { do not copy on local !! }
  1426. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
  1427. { Adjust alignment to match cdecl or stdcall }
  1428. tprocdef(def).parast.dataalignment:=std_param_align;
  1429. end;
  1430. end;
  1431. pocall_stdcall :
  1432. begin
  1433. include(def.procoptions,po_savestdregs);
  1434. if (def.deftype=procdef) then
  1435. begin
  1436. if not assigned(tprocdef(def).parast) then
  1437. internalerror(200110236);
  1438. { Adjust alignment to match cdecl or stdcall }
  1439. tprocdef(def).parast.dataalignment:=std_param_align;
  1440. end;
  1441. end;
  1442. pocall_safecall :
  1443. begin
  1444. include(def.procoptions,po_savestdregs);
  1445. end;
  1446. pocall_compilerproc :
  1447. begin
  1448. if (not assigned(sym)) or
  1449. (def.deftype<>procdef) then
  1450. internalerror(200110232);
  1451. tprocdef(def).setmangledname(lower(sym.name));
  1452. end;
  1453. pocall_pascal :
  1454. begin
  1455. include(def.procoptions,po_leftright);
  1456. end;
  1457. pocall_register :
  1458. begin
  1459. Message1(parser_w_proc_directive_ignored,'REGISTER');
  1460. end;
  1461. pocall_far16 :
  1462. begin
  1463. { Temporary stub, must be rewritten to support OS/2 far16 }
  1464. Message1(parser_w_proc_directive_ignored,'FAR16');
  1465. end;
  1466. pocall_system :
  1467. begin
  1468. include(def.procoptions,po_clearstack);
  1469. if (not assigned(sym)) or
  1470. (def.deftype<>procdef) then
  1471. internalerror(200110233);
  1472. if not tprocdef(def).has_mangledname then
  1473. tprocdef(def).setmangledname(sym.realname);
  1474. end;
  1475. pocall_palmossyscall :
  1476. begin
  1477. { use popstack and save std registers }
  1478. include(def.procoptions,po_clearstack);
  1479. include(def.procoptions,po_savestdregs);
  1480. if (def.deftype=procdef) then
  1481. begin
  1482. if not assigned(tprocdef(def).parast) then
  1483. internalerror(200110236);
  1484. { do not copy on local !! }
  1485. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}resetvaluepara,nil);
  1486. { Adjust positions of args for cdecl or stdcall }
  1487. tprocdef(def).parast.dataalignment:=std_param_align;
  1488. end;
  1489. end;
  1490. pocall_inline :
  1491. begin
  1492. if not(cs_support_inline in aktmoduleswitches) then
  1493. begin
  1494. Message(parser_e_proc_inline_not_supported);
  1495. def.proccalloption:=pocall_fpccall;
  1496. end;
  1497. end;
  1498. end;
  1499. { add mangledname to external list }
  1500. if (def.deftype=procdef) and
  1501. (po_external in def.procoptions) and
  1502. target_info.DllScanSupported then
  1503. current_module.externals.insert(tExternalsItem.create(tprocdef(def).mangledname));
  1504. end;
  1505. procedure calc_parasymtable_addresses(def:tprocdef);
  1506. var
  1507. lastps,
  1508. highps,ps : tsym;
  1509. st : tsymtable;
  1510. begin
  1511. st:=def.parast;
  1512. if po_leftright in def.procoptions then
  1513. begin
  1514. { pushed in reversed order, left to right }
  1515. highps:=nil;
  1516. lastps:=nil;
  1517. while assigned(st.symindex.first) and (lastps<>tsym(st.symindex.first)) do
  1518. begin
  1519. ps:=tsym(st.symindex.first);
  1520. while assigned(ps.indexnext) and (tsym(ps.indexnext)<>lastps) do
  1521. ps:=tsym(ps.indexnext);
  1522. if ps.typ=varsym then
  1523. begin
  1524. { Wait with inserting the high value, it needs to be inserted
  1525. after the corresponding parameter }
  1526. if Copy(ps.name,1,4)='high' then
  1527. highps:=ps
  1528. else
  1529. begin
  1530. st.insertvardata(ps);
  1531. { add also the high tree if it was saved }
  1532. if assigned(highps) then
  1533. begin
  1534. st.insertvardata(highps);
  1535. highps:=nil;
  1536. end;
  1537. end;
  1538. end;
  1539. lastps:=ps;
  1540. end;
  1541. if assigned(highps) then
  1542. internalerror(200208257);
  1543. end
  1544. else
  1545. begin
  1546. { pushed in normal order, right to left }
  1547. ps:=tsym(st.symindex.first);
  1548. while assigned(ps) do
  1549. begin
  1550. if ps.typ=varsym then
  1551. st.insertvardata(ps);
  1552. ps:=tsym(ps.indexnext);
  1553. end;
  1554. end;
  1555. end;
  1556. procedure parse_proc_directives(var pdflags:word);
  1557. {
  1558. Parse the procedure directives. It does not matter if procedure directives
  1559. are written using ;procdir; or ['procdir'] syntax.
  1560. }
  1561. var
  1562. res : boolean;
  1563. begin
  1564. while token in [_ID,_LECKKLAMMER] do
  1565. begin
  1566. if try_to_consume(_LECKKLAMMER) then
  1567. begin
  1568. repeat
  1569. parse_proc_direc(pdflags);
  1570. until not try_to_consume(_COMMA);
  1571. consume(_RECKKLAMMER);
  1572. { we always expect at least '[];' }
  1573. res:=true;
  1574. end
  1575. else
  1576. begin
  1577. res:=parse_proc_direc(pdflags);
  1578. end;
  1579. { A procedure directive normally followed by a semicolon, but in
  1580. a const section we should stop when _EQUAL is found }
  1581. if res then
  1582. begin
  1583. if (block_type=bt_const) and
  1584. (token=_EQUAL) then
  1585. break;
  1586. { support procedure proc;stdcall export; in Delphi mode only }
  1587. if not((m_delphi in aktmodeswitches) and
  1588. is_proc_directive(token)) then
  1589. consume(_SEMICOLON);
  1590. end
  1591. else
  1592. break;
  1593. end;
  1594. handle_calling_convention(aktprocsym,aktprocdef);
  1595. { calculate addresses in parasymtable }
  1596. if aktprocdef.deftype=procdef then
  1597. calc_parasymtable_addresses(aktprocdef);
  1598. end;
  1599. procedure parse_var_proc_directives(var sym : tsym);
  1600. var
  1601. pdflags : word;
  1602. oldsym : tprocsym;
  1603. olddef : tprocdef;
  1604. pd : tabstractprocdef;
  1605. begin
  1606. oldsym:=aktprocsym;
  1607. olddef:=aktprocdef;
  1608. pdflags:=pd_procvar;
  1609. { we create a temporary aktprocsym to read the directives }
  1610. aktprocsym:=tprocsym.create(sym.name);
  1611. case sym.typ of
  1612. varsym :
  1613. pd:=tabstractprocdef(tvarsym(sym).vartype.def);
  1614. typedconstsym :
  1615. pd:=tabstractprocdef(ttypedconstsym(sym).typedconsttype.def);
  1616. typesym :
  1617. pd:=tabstractprocdef(ttypesym(sym).restype.def);
  1618. else
  1619. internalerror(994932432);
  1620. end;
  1621. if pd.deftype<>procvardef then
  1622. internalerror(994932433);
  1623. tabstractprocdef(aktprocdef):=pd;
  1624. { names should never be used anyway }
  1625. inc(lexlevel);
  1626. parse_proc_directives(pdflags);
  1627. dec(lexlevel);
  1628. aktprocsym.free;
  1629. aktprocsym:=oldsym;
  1630. aktprocdef:=olddef;
  1631. end;
  1632. procedure parse_object_proc_directives(var sym : tprocsym);
  1633. var
  1634. pdflags : word;
  1635. begin
  1636. pdflags:=pd_object;
  1637. inc(lexlevel);
  1638. parse_proc_directives(pdflags);
  1639. dec(lexlevel);
  1640. if (po_containsself in aktprocdef.procoptions) and
  1641. (([po_msgstr,po_msgint]*aktprocdef.procoptions)=[]) then
  1642. Message(parser_e_self_in_non_message_handler);
  1643. end;
  1644. function proc_add_definition(aprocsym:tprocsym;var aprocdef : tprocdef) : boolean;
  1645. {
  1646. Add definition aprocdef to the overloaded definitions of aprocsym. If a
  1647. forwarddef is found and reused it returns true
  1648. }
  1649. var
  1650. hd : tprocdef;
  1651. ad,fd : tsym;
  1652. forwardfound : boolean;
  1653. i : cardinal;
  1654. begin
  1655. forwardfound:=false;
  1656. { check overloaded functions if the same function already exists }
  1657. for i:=1 to aprocsym.procdef_count do
  1658. begin
  1659. hd:=aprocsym.procdef[i];
  1660. { check the parameters, for delphi/tp it is possible to
  1661. leave the parameters away in the implementation (forwarddef=false).
  1662. But for an overload declared function this is not allowed }
  1663. if { check if empty implementation arguments match is allowed }
  1664. (
  1665. not(m_repeat_forward in aktmodeswitches) and
  1666. not(aprocdef.forwarddef) and
  1667. (aprocdef.maxparacount=0) and
  1668. not(po_overload in hd.procoptions)
  1669. ) or
  1670. { check arguments }
  1671. (
  1672. equal_paras(aprocdef.para,hd.para,cp_none) and
  1673. { for operators equal_paras is not enough !! }
  1674. ((aprocdef.proctypeoption<>potype_operator) or (optoken<>_ASSIGNMENT) or
  1675. is_equal(hd.rettype.def,aprocdef.rettype.def))
  1676. ) then
  1677. begin
  1678. { Check if we've found the forwarddef, if found then
  1679. we need to update the forward def with the current
  1680. implementation settings }
  1681. if hd.forwarddef then
  1682. begin
  1683. forwardfound:=true;
  1684. { Check if the procedure type and return type are correct,
  1685. also the parameters must match also with the type }
  1686. if (hd.proctypeoption<>aprocdef.proctypeoption) or
  1687. (
  1688. (m_repeat_forward in aktmodeswitches) and
  1689. (not((aprocdef.maxparacount=0) or
  1690. equal_paras(aprocdef.para,hd.para,cp_all)))
  1691. ) or
  1692. (
  1693. ((m_repeat_forward in aktmodeswitches) or
  1694. not(is_void(aprocdef.rettype.def))) and
  1695. (not is_equal(hd.rettype.def,aprocdef.rettype.def))) then
  1696. begin
  1697. MessagePos1(aprocdef.fileinfo,parser_e_header_dont_match_forward,
  1698. aprocdef.fullprocname);
  1699. break;
  1700. end;
  1701. { Check if both are declared forward }
  1702. if hd.forwarddef and aprocdef.forwarddef then
  1703. begin
  1704. MessagePos1(aprocdef.fileinfo,parser_e_function_already_declared_public_forward,
  1705. aprocdef.fullprocname);
  1706. end;
  1707. { internconst or internproc only need to be defined once }
  1708. if (hd.proccalloption=pocall_internproc) then
  1709. aprocdef.proccalloption:=hd.proccalloption
  1710. else
  1711. if (aprocdef.proccalloption=pocall_internproc) then
  1712. hd.proccalloption:=aprocdef.proccalloption;
  1713. if (po_internconst in hd.procoptions) then
  1714. include(aprocdef.procoptions,po_internconst)
  1715. else if (po_internconst in aprocdef.procoptions) then
  1716. include(hd.procoptions,po_internconst);
  1717. { Check calling convention }
  1718. if (hd.proccalloption<>aprocdef.proccalloption) then
  1719. begin
  1720. { For delphi check if the current implementation has no proccalloption, then
  1721. take the options from the interface }
  1722. if not(m_delphi in aktmodeswitches) or
  1723. (aprocdef.proccalloption<>pocall_none) then
  1724. MessagePos(aprocdef.fileinfo,parser_e_call_convention_dont_match_forward);
  1725. { restore interface settings }
  1726. aprocdef.proccalloption:=hd.proccalloption;
  1727. aprocdef.has_mangledname:=hd.has_mangledname;
  1728. if hd.has_mangledname then
  1729. aprocdef.setmangledname(hd.mangledname);
  1730. end;
  1731. { Check manglednames }
  1732. if (m_repeat_forward in aktmodeswitches) or
  1733. aprocdef.haspara then
  1734. begin
  1735. { If mangled names are equal then they have the same amount of arguments }
  1736. { We can check the names of the arguments }
  1737. { both symtables are in the same order from left to right }
  1738. ad:=tsym(hd.parast.symindex.first);
  1739. fd:=tsym(aprocdef.parast.symindex.first);
  1740. repeat
  1741. { skip default parameter constsyms }
  1742. while assigned(ad) and (ad.typ<>varsym) do
  1743. ad:=tsym(ad.indexnext);
  1744. while assigned(fd) and (fd.typ<>varsym) do
  1745. fd:=tsym(fd.indexnext);
  1746. { stop when one of the two lists is at the end }
  1747. if not assigned(ad) or not assigned(fd) then
  1748. break;
  1749. if (ad.name<>fd.name) then
  1750. begin
  1751. MessagePos3(aprocdef.fileinfo,parser_e_header_different_var_names,
  1752. aprocsym.name,ad.name,fd.name);
  1753. break;
  1754. end;
  1755. ad:=tsym(ad.indexnext);
  1756. fd:=tsym(fd.indexnext);
  1757. until false;
  1758. if assigned(ad) or assigned(fd) then
  1759. internalerror(200204178);
  1760. end;
  1761. { Everything is checked, now we can update the forward declaration
  1762. with the new data from the implementation }
  1763. hd.forwarddef:=aprocdef.forwarddef;
  1764. hd.hasforward:=true;
  1765. hd.parast.address_fixup:=aprocdef.parast.address_fixup;
  1766. hd.procoptions:=hd.procoptions+aprocdef.procoptions;
  1767. if hd.extnumber=65535 then
  1768. hd.extnumber:=aprocdef.extnumber;
  1769. while not aprocdef.aliasnames.empty do
  1770. hd.aliasnames.insert(aprocdef.aliasnames.getfirst);
  1771. { update mangledname if the implementation has a fixed mangledname set }
  1772. if aprocdef.has_mangledname then
  1773. begin
  1774. { rename also asmsymbol first, because the name can already be used }
  1775. objectlibrary.renameasmsymbol(hd.mangledname,aprocdef.mangledname);
  1776. { update the mangledname }
  1777. hd.has_mangledname:=true;
  1778. hd.setmangledname(aprocdef.mangledname);
  1779. end;
  1780. { for compilerproc defines we need to rename and update the
  1781. symbolname to lowercase }
  1782. if (aprocdef.proccalloption=pocall_compilerproc) then
  1783. begin
  1784. { rename to lowercase so users can't access it }
  1785. aprocsym.owner.rename(aprocsym.name,lower(aprocsym.name));
  1786. { also update the realname that is stored in the ppu }
  1787. stringdispose(aprocsym._realname);
  1788. aprocsym._realname:=stringdup('$'+aprocsym.name);
  1789. { the mangeled name is already changed by the pd_compilerproc }
  1790. { handler. It must be done immediately because if we have a }
  1791. { call to a compilerproc before it's implementation is }
  1792. { encountered, it must already use the new mangled name (JM) }
  1793. end;
  1794. { return the forwarddef }
  1795. aprocdef:=hd;
  1796. end
  1797. else
  1798. begin
  1799. { abstract methods aren't forward defined, but this }
  1800. { needs another error message }
  1801. if (po_abstractmethod in hd.procoptions) then
  1802. MessagePos(aprocdef.fileinfo,parser_e_abstract_no_definition)
  1803. else
  1804. MessagePos(aprocdef.fileinfo,parser_e_overloaded_have_same_parameters);
  1805. end;
  1806. { we found one proc with the same arguments, there are no others
  1807. so we can stop }
  1808. break;
  1809. end;
  1810. { check for allowing overload directive }
  1811. if not(m_fpc in aktmodeswitches) then
  1812. begin
  1813. { overload directive turns on overloading }
  1814. if ((po_overload in aprocdef.procoptions) or
  1815. (po_overload in hd.procoptions)) then
  1816. begin
  1817. { check if all procs have overloading, but not if the proc was
  1818. already declared forward, then the check is already done }
  1819. if not(hd.hasforward or
  1820. (aprocdef.forwarddef<>hd.forwarddef) or
  1821. ((po_overload in aprocdef.procoptions) and
  1822. (po_overload in hd.procoptions))) then
  1823. begin
  1824. MessagePos1(aprocdef.fileinfo,parser_e_no_overload_for_all_procs,aprocsym.realname);
  1825. break;
  1826. end;
  1827. end
  1828. else
  1829. begin
  1830. if not(hd.forwarddef) then
  1831. begin
  1832. MessagePos(aprocdef.fileinfo,parser_e_procedure_overloading_is_off);
  1833. break;
  1834. end;
  1835. end;
  1836. end; { equal arguments }
  1837. end;
  1838. { if we didn't reuse a forwarddef then we add the procdef to the overloaded
  1839. list }
  1840. if not forwardfound then
  1841. begin
  1842. aprocsym.addprocdef(aprocdef);
  1843. { add overloadnumber for unique naming, the overloadcount is
  1844. counted per module and 0 for the first procedure }
  1845. aprocdef.overloadnumber:=aprocsym.overloadcount;
  1846. inc(aprocsym.overloadcount);
  1847. end;
  1848. { insert otsym only in the right symtable }
  1849. if ((procinfo.flags and pi_operator)<>0) and
  1850. assigned(otsym) then
  1851. begin
  1852. if not parse_only then
  1853. begin
  1854. if paramanager.ret_in_param(aprocdef.rettype.def) then
  1855. begin
  1856. aprocdef.parast.insert(otsym);
  1857. { this allows to read the funcretoffset }
  1858. otsym.address:=-4;
  1859. otsym.varspez:=vs_var;
  1860. end
  1861. else
  1862. begin
  1863. aprocdef.localst.insert(otsym);
  1864. aprocdef.localst.insertvardata(otsym);
  1865. end;
  1866. end
  1867. else
  1868. begin
  1869. { this is not required anymore }
  1870. otsym.free;
  1871. otsym:=nil;
  1872. end;
  1873. end;
  1874. paramanager.create_param_loc_info(aprocdef);
  1875. proc_add_definition:=forwardfound;
  1876. end;
  1877. end.
  1878. {
  1879. $Log$
  1880. Revision 1.73 2002-09-09 19:39:07 peter
  1881. * check return type for forwarddefs also not delphi mode when
  1882. the type is not void
  1883. Revision 1.72 2002/09/09 17:34:15 peter
  1884. * tdicationary.replace added to replace and item in a dictionary. This
  1885. is only allowed for the same name
  1886. * varsyms are inserted in symtable before the types are parsed. This
  1887. fixes the long standing "var longint : longint" bug
  1888. - consume_idlist and idstringlist removed. The loops are inserted
  1889. at the callers place and uses the symtable for duplicate id checking
  1890. Revision 1.71 2002/09/07 15:25:06 peter
  1891. * old logs removed and tabs fixed
  1892. Revision 1.70 2002/09/03 16:26:27 daniel
  1893. * Make Tprocdef.defs protected
  1894. Revision 1.69 2002/09/01 12:11:33 peter
  1895. * calc param_offset after parameters are read, because the calculation
  1896. depends on po_containself
  1897. Revision 1.68 2002/08/25 19:25:20 peter
  1898. * sym.insert_in_data removed
  1899. * symtable.insertvardata/insertconstdata added
  1900. * removed insert_in_data call from symtable.insert, it needs to be
  1901. called separatly. This allows to deref the address calculation
  1902. * procedures now calculate the parast addresses after the procedure
  1903. directives are parsed. This fixes the cdecl parast problem
  1904. * push_addr_param has an extra argument that specifies if cdecl is used
  1905. or not
  1906. Revision 1.67 2002/08/25 11:33:06 peter
  1907. * also check the paratypes when a forward was found
  1908. Revision 1.66 2002/08/19 19:36:44 peter
  1909. * More fixes for cross unit inlining, all tnodes are now implemented
  1910. * Moved pocall_internconst to po_internconst because it is not a
  1911. calling type at all and it conflicted when inlining of these small
  1912. functions was requested
  1913. Revision 1.65 2002/08/18 20:06:24 peter
  1914. * inlining is now also allowed in interface
  1915. * renamed write/load to ppuwrite/ppuload
  1916. * tnode storing in ppu
  1917. * nld,ncon,nbas are already updated for storing in ppu
  1918. Revision 1.64 2002/08/17 09:23:39 florian
  1919. * first part of procinfo rewrite
  1920. Revision 1.63 2002/08/11 14:32:27 peter
  1921. * renamed current_library to objectlibrary
  1922. Revision 1.62 2002/08/11 13:24:12 peter
  1923. * saving of asmsymbols in ppu supported
  1924. * asmsymbollist global is removed and moved into a new class
  1925. tasmlibrarydata that will hold the info of a .a file which
  1926. corresponds with a single module. Added librarydata to tmodule
  1927. to keep the library info stored for the module. In the future the
  1928. objectfiles will also be stored to the tasmlibrarydata class
  1929. * all getlabel/newasmsymbol and friends are moved to the new class
  1930. Revision 1.61 2002/07/26 21:15:40 florian
  1931. * rewrote the system handling
  1932. Revision 1.60 2002/07/20 11:57:55 florian
  1933. * types.pas renamed to defbase.pas because D6 contains a types
  1934. unit so this would conflicts if D6 programms are compiled
  1935. + Willamette/SSE2 instructions to assembler added
  1936. Revision 1.59 2002/07/11 14:41:28 florian
  1937. * start of the new generic parameter handling
  1938. Revision 1.58 2002/07/01 18:46:25 peter
  1939. * internal linker
  1940. * reorganized aasm layer
  1941. Revision 1.57 2002/05/18 13:34:12 peter
  1942. * readded missing revisions
  1943. Revision 1.56 2002/05/16 19:46:42 carl
  1944. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1945. + try to fix temp allocation (still in ifdef)
  1946. + generic constructor calls
  1947. + start of tassembler / tmodulebase class cleanup
  1948. Revision 1.54 2002/05/12 16:53:08 peter
  1949. * moved entry and exitcode to ncgutil and cgobj
  1950. * foreach gets extra argument for passing local data to the
  1951. iterator function
  1952. * -CR checks also class typecasts at runtime by changing them
  1953. into as
  1954. * fixed compiler to cycle with the -CR option
  1955. * fixed stabs with elf writer, finally the global variables can
  1956. be watched
  1957. * removed a lot of routines from cga unit and replaced them by
  1958. calls to cgobj
  1959. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1960. u32bit then the other is typecasted also to u32bit without giving
  1961. a rangecheck warning/error.
  1962. * fixed pascal calling method with reversing also the high tree in
  1963. the parast, detected by tcalcst3 test
  1964. Revision 1.53 2002/04/21 19:02:04 peter
  1965. * removed newn and disposen nodes, the code is now directly
  1966. inlined from pexpr
  1967. * -an option that will write the secondpass nodes to the .s file, this
  1968. requires EXTDEBUG define to actually write the info
  1969. * fixed various internal errors and crashes due recent code changes
  1970. Revision 1.52 2002/04/20 21:32:24 carl
  1971. + generic FPC_CHECKPOINTER
  1972. + first parameter offset in stack now portable
  1973. * rename some constants
  1974. + move some cpu stuff to other units
  1975. - remove unused constents
  1976. * fix stacksize for some targets
  1977. * fix generic size problems which depend now on EXTEND_SIZE constant
  1978. Revision 1.51 2002/04/20 15:27:05 carl
  1979. - remove ifdef i386 define
  1980. Revision 1.50 2002/04/19 15:46:02 peter
  1981. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  1982. in most cases and not written to the ppu
  1983. * add mangeledname_prefix() routine to generate the prefix of
  1984. manglednames depending on the current procedure, object and module
  1985. * removed static procprefix since the mangledname is now build only
  1986. on demand from tprocdef.mangledname
  1987. }