pdecsub.pas 74 KB

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