pdecsub.pas 64 KB

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