pdecsub.pas 77 KB

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