pdecsub.pas 81 KB

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