pdecsub.pas 79 KB

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