pdecsub.pas 69 KB

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