pdecsub.pas 77 KB

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