pdecsub.pas 75 KB

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