pdecsub.pas 78 KB

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