pdecsub.pas 77 KB

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