pdecsub.pas 70 KB

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