pdecsub.pas 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.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 insert_hidden_para(pd:tabstractprocdef);
  34. procedure check_self_para(aktprocdef:tabstractprocdef);
  35. procedure parameter_dec(aktprocdef:tabstractprocdef);
  36. procedure parse_proc_directives(var pdflags:word);
  37. procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
  38. procedure calc_parasymtable_addresses(pd:tprocdef);
  39. procedure parse_proc_head(options:tproctypeoption);
  40. procedure parse_proc_dec;
  41. procedure parse_var_proc_directives(var sym : tsym);
  42. procedure parse_object_proc_directives(var sym : tprocsym);
  43. function proc_add_definition(aprocsym:tprocsym;var aprocdef : tprocdef) : boolean;
  44. implementation
  45. uses
  46. {$ifdef delphi}
  47. sysutils,
  48. {$else delphi}
  49. strings,
  50. {$endif delphi}
  51. { common }
  52. cutils,cclasses,
  53. { global }
  54. globtype,globals,verbose,
  55. systems,cpubase,
  56. { aasm }
  57. aasmbase,aasmtai,aasmcpu,
  58. { symtable }
  59. symbase,symtable,defutil,defcmp,paramgr,
  60. { pass 1 }
  61. node,htypechk,
  62. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  63. { parser }
  64. fmodule,scanner,
  65. pbase,pexpr,ptype,pdecl,
  66. { linking }
  67. import,gendef,
  68. { codegen }
  69. cpuinfo,cgbase
  70. ;
  71. procedure insert_hidden_para(pd:tabstractprocdef);
  72. var
  73. currpara : tparaitem;
  74. hvs : tvarsym;
  75. begin
  76. { walk from right to left, so we can insert the
  77. high parameters after the current parameter }
  78. currpara:=tparaitem(pd.para.last);
  79. while assigned(currpara) do
  80. begin
  81. { need high parameter ? }
  82. if paramanager.push_high_param(currpara.paratype.def,pd.proccalloption) then
  83. begin
  84. if assigned(currpara.parasym) then
  85. begin
  86. hvs:=tvarsym.create('$high'+tvarsym(currpara.parasym).name,s32bittype);
  87. hvs.varspez:=vs_const;
  88. include(hvs.varoptions,vo_is_high_value);
  89. tvarsym(currpara.parasym).owner.insert(hvs);
  90. tvarsym(currpara.parasym).highvarsym:=hvs;
  91. end
  92. else
  93. hvs:=nil;
  94. pd.concatpara(currpara,s32bittype,hvs,vs_hidden,nil);
  95. end
  96. else
  97. begin
  98. { Give a warning that cdecl routines does not include high()
  99. support }
  100. if (pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  101. paramanager.push_high_param(currpara.paratype.def,pocall_fpccall) then
  102. begin
  103. if is_open_string(currpara.paratype.def) then
  104. Message(parser_w_cdecl_no_openstring);
  105. if not (po_external in pd.procoptions) then
  106. Message(parser_w_cdecl_has_no_high);
  107. end;
  108. end;
  109. currpara:=tparaitem(currpara.previous);
  110. end;
  111. end;
  112. procedure checkvaluepara(p:tnamedindexitem;arg:pointer);
  113. begin
  114. if tsym(p).typ<>varsym then
  115. exit;
  116. with tvarsym(p) do
  117. begin
  118. { do we need a local copy? Then rename the varsym, do this after the
  119. insert so the dup id checking is done correctly.
  120. array of const and open array do not need this, the local copy routine
  121. will patch the pushed value to point to the local copy }
  122. if (varspez=vs_value) and
  123. paramanager.push_addr_param(vartype.def,aktprocdef.proccalloption) and
  124. not(is_array_of_const(vartype.def) or
  125. is_open_array(vartype.def)) then
  126. aktprocdef.parast.symsearch.rename(name,'val'+name);
  127. end;
  128. end;
  129. procedure check_c_para(p:tnamedindexitem;arg:pointer);
  130. begin
  131. if (tsym(p).typ<>varsym) then
  132. exit;
  133. with tvarsym(p) do
  134. begin
  135. case vartype.def.deftype of
  136. arraydef :
  137. begin
  138. if not is_variant_array(vartype.def) and
  139. not is_array_of_const(vartype.def) then
  140. begin
  141. if (varspez<>vs_var) then
  142. Message(parser_h_c_arrays_are_references);
  143. end;
  144. if is_array_of_const(vartype.def) and
  145. assigned(indexnext) and
  146. (tsym(indexnext).typ=varsym) and
  147. not(vo_is_high_value in tvarsym(indexnext).varoptions) then
  148. Message(parser_e_C_array_of_const_must_be_last);
  149. end;
  150. end;
  151. end;
  152. end;
  153. procedure check_self_para(aktprocdef:tabstractprocdef);
  154. var
  155. hpara : tparaitem;
  156. begin
  157. hpara:=aktprocdef.selfpara;
  158. if assigned(hpara) and
  159. (
  160. ((aktprocdef.deftype=procvardef) and
  161. (po_methodpointer in aktprocdef.procoptions)) or
  162. ((aktprocdef.deftype=procdef) and
  163. assigned(tprocdef(aktprocdef)._class))
  164. ) then
  165. begin
  166. include(aktprocdef.procoptions,po_containsself);
  167. if hpara.paratyp <> vs_value then
  168. CGMessage(parser_e_self_call_by_value);
  169. if (aktprocdef.deftype=procdef) then
  170. begin
  171. inc(procinfo.selfpointer_offset,tvarsym(hpara.parasym).address);
  172. if compare_defs(hpara.paratype.def,tprocdef(aktprocdef)._class,nothingn)=te_incompatible then
  173. CGMessage2(type_e_incompatible_types,hpara.paratype.def.typename,tprocdef(aktprocdef)._class.typename);
  174. end;
  175. end;
  176. end;
  177. procedure parameter_dec(aktprocdef:tabstractprocdef);
  178. {
  179. handle_procvar needs the same changes
  180. }
  181. var
  182. is_procvar : boolean;
  183. sc : tsinglelist;
  184. tt : ttype;
  185. arrayelementtype : ttype;
  186. vs : tvarsym;
  187. srsym : tsym;
  188. hs1 : string;
  189. varspez : Tvarspez;
  190. hpara : tparaitem;
  191. tdefaultvalue : tconstsym;
  192. defaultrequired : boolean;
  193. old_object_option : tsymoptions;
  194. dummyst : tparasymtable;
  195. currparast : tparasymtable;
  196. begin
  197. consume(_LKLAMMER);
  198. { Delphi/Kylix supports nonsense like }
  199. { procedure p(); }
  200. if try_to_consume(_RKLAMMER) and
  201. not(m_tp7 in aktmodeswitches) then
  202. exit;
  203. { parsing a proc or procvar ? }
  204. is_procvar:=(aktprocdef.deftype=procvardef);
  205. { create dummy symtable for procvars }
  206. if is_procvar then
  207. begin
  208. dummyst:=tparasymtable.create;
  209. currparast:=dummyst;
  210. end
  211. else
  212. begin
  213. currparast:=tparasymtable(tprocdef(aktprocdef).parast);
  214. end;
  215. { reset }
  216. sc:=tsinglelist.create;
  217. defaultrequired:=false;
  218. { the variables are always public }
  219. old_object_option:=current_object_option;
  220. current_object_option:=[sp_public];
  221. inc(testcurobject);
  222. repeat
  223. if try_to_consume(_VAR) then
  224. varspez:=vs_var
  225. else
  226. if try_to_consume(_CONST) then
  227. varspez:=vs_const
  228. else
  229. if (idtoken=_OUT) and (m_out in aktmodeswitches) then
  230. begin
  231. consume(_OUT);
  232. varspez:=vs_out
  233. end
  234. else
  235. varspez:=vs_value;
  236. tdefaultvalue:=nil;
  237. tt.reset;
  238. { read identifiers and insert with error type }
  239. sc.reset;
  240. repeat
  241. vs:=tvarsym.create(orgpattern,generrortype);
  242. currparast.insert(vs);
  243. if assigned(vs.owner) then
  244. sc.insert(vs)
  245. else
  246. vs.free;
  247. consume(_ID);
  248. until not try_to_consume(_COMMA);
  249. { read type declaration, force reading for value and const paras }
  250. if (token=_COLON) or (varspez=vs_value) then
  251. begin
  252. consume(_COLON);
  253. { check for an open array }
  254. if token=_ARRAY then
  255. begin
  256. consume(_ARRAY);
  257. consume(_OF);
  258. { define range and type of range }
  259. tt.setdef(tarraydef.create(0,-1,s32bittype));
  260. { array of const ? }
  261. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  262. begin
  263. consume(_CONST);
  264. srsym:=searchsymonlyin(systemunit,'TVARREC');
  265. if not assigned(srsym) then
  266. InternalError(1234124);
  267. tarraydef(tt.def).setelementtype(ttypesym(srsym).restype);
  268. tarraydef(tt.def).IsArrayOfConst:=true;
  269. end
  270. else
  271. begin
  272. { define field type }
  273. single_type(arrayelementtype,hs1,false);
  274. tarraydef(tt.def).setelementtype(arrayelementtype);
  275. end;
  276. end
  277. else
  278. begin
  279. { open string ? }
  280. if (varspez=vs_var) and
  281. (
  282. (
  283. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  284. (cs_openstring in aktmoduleswitches) and
  285. not(cs_ansistrings in aktlocalswitches)
  286. ) or
  287. (idtoken=_OPENSTRING)) then
  288. begin
  289. consume(token);
  290. tt:=openshortstringtype;
  291. hs1:='openstring';
  292. end
  293. else
  294. begin
  295. { everything else }
  296. single_type(tt,hs1,false);
  297. end;
  298. { default parameter }
  299. if (m_default_para in aktmodeswitches) then
  300. begin
  301. if try_to_consume(_EQUAL) then
  302. begin
  303. vs:=tvarsym(sc.first);
  304. if assigned(vs.listnext) then
  305. Message(parser_e_default_value_only_one_para);
  306. { prefix 'def' to the parameter name }
  307. tdefaultvalue:=ReadConstant('$def'+vs.name,vs.fileinfo);
  308. if assigned(tdefaultvalue) then
  309. tprocdef(aktprocdef).parast.insert(tdefaultvalue);
  310. defaultrequired:=true;
  311. end
  312. else
  313. begin
  314. if defaultrequired then
  315. Message1(parser_e_default_value_expected_for_para,vs.name);
  316. end;
  317. end;
  318. end;
  319. end
  320. else
  321. begin
  322. {$ifndef UseNiceNames}
  323. hs1:='$$$';
  324. {$else UseNiceNames}
  325. hs1:='var';
  326. {$endif UseNiceNames}
  327. tt:=cformaltype;
  328. end;
  329. vs:=tvarsym(sc.first);
  330. while assigned(vs) do
  331. begin
  332. { update varsym }
  333. vs.vartype:=tt;
  334. vs.varspez:=varspez;
  335. { For proc vars we only need the definitions }
  336. if not is_procvar then
  337. begin
  338. if (varspez in [vs_var,vs_const,vs_out]) and
  339. paramanager.push_addr_param(tt.def,aktprocdef.proccalloption) then
  340. include(vs.varoptions,vo_regable);
  341. hpara:=aktprocdef.concatpara(nil,tt,vs,varspez,tdefaultvalue);
  342. end
  343. else
  344. hpara:=aktprocdef.concatpara(nil,tt,nil,varspez,tdefaultvalue);
  345. { save position of self parameter }
  346. if vs.name='SELF' then
  347. aktprocdef.selfpara:=hpara;
  348. vs:=tvarsym(vs.listnext);
  349. end;
  350. until not try_to_consume(_SEMICOLON);
  351. { remove parasymtable from stack }
  352. if is_procvar then
  353. dummyst.free;
  354. sc.free;
  355. { check for a self parameter, only for normal procedures. For
  356. procvars we need to wait until the 'of object' is parsed }
  357. if not is_procvar then
  358. check_self_para(aktprocdef);
  359. { reset object options }
  360. dec(testcurobject);
  361. current_object_option:=old_object_option;
  362. consume(_RKLAMMER);
  363. end;
  364. procedure parse_proc_head(options:tproctypeoption);
  365. var
  366. orgsp,sp:stringid;
  367. paramoffset:longint;
  368. sym:tsym;
  369. st : tsymtable;
  370. srsymtable : tsymtable;
  371. storepos,procstartfilepos : tfileposinfo;
  372. searchagain : boolean;
  373. i: longint;
  374. begin
  375. { Save the position where this procedure really starts }
  376. procstartfilepos:=akttokenpos;
  377. aktprocdef:=nil;
  378. if (options=potype_operator) then
  379. begin
  380. sp:=overloaded_names[optoken];
  381. orgsp:=sp;
  382. end
  383. else
  384. begin
  385. sp:=pattern;
  386. orgsp:=orgpattern;
  387. consume(_ID);
  388. end;
  389. { examine interface map: function/procedure iname.functionname=locfuncname }
  390. if parse_only and
  391. assigned(procinfo._class) and
  392. assigned(procinfo._class.implementedinterfaces) and
  393. (procinfo._class.implementedinterfaces.count>0) and
  394. try_to_consume(_POINT) then
  395. begin
  396. storepos:=akttokenpos;
  397. akttokenpos:=procstartfilepos;
  398. { get interface syms}
  399. searchsym(sp,sym,srsymtable);
  400. if not assigned(sym) then
  401. begin
  402. identifier_not_found(orgsp);
  403. sym:=generrorsym;
  404. end;
  405. akttokenpos:=storepos;
  406. { load proc name }
  407. if sym.typ=typesym then
  408. i:=procinfo._class.implementedinterfaces.searchintf(ttypesym(sym).restype.def);
  409. { qualifier is interface name? }
  410. if (sym.typ<>typesym) or (ttypesym(sym).restype.def.deftype<>objectdef) or
  411. (i=-1) then
  412. begin
  413. Message(parser_e_interface_id_expected);
  414. aktprocsym:=nil;
  415. end
  416. else
  417. begin
  418. aktprocsym:=tprocsym(procinfo._class.implementedinterfaces.interfaces(i).symtable.search(sp));
  419. { the method can be declared after the mapping FK
  420. if not(assigned(aktprocsym)) then
  421. Message(parser_e_methode_id_expected);
  422. }
  423. end;
  424. consume(_ID);
  425. consume(_EQUAL);
  426. if (token=_ID) { and assigned(aktprocsym) } then
  427. procinfo._class.implementedinterfaces.addmappings(i,sp,pattern);
  428. consume(_ID);
  429. exit;
  430. end;
  431. { method ? }
  432. if not(parse_only) and
  433. (lexlevel=normal_function_level) and
  434. try_to_consume(_POINT) then
  435. begin
  436. { search for object name }
  437. storepos:=akttokenpos;
  438. akttokenpos:=procstartfilepos;
  439. searchsym(sp,sym,srsymtable);
  440. if not assigned(sym) then
  441. begin
  442. identifier_not_found(orgsp);
  443. sym:=generrorsym;
  444. end;
  445. akttokenpos:=storepos;
  446. { consume proc name }
  447. sp:=pattern;
  448. orgsp:=orgpattern;
  449. procstartfilepos:=akttokenpos;
  450. consume(_ID);
  451. { qualifier is class name ? }
  452. if (sym.typ<>typesym) or
  453. (ttypesym(sym).restype.def.deftype<>objectdef) then
  454. begin
  455. Message(parser_e_class_id_expected);
  456. aktprocsym:=nil;
  457. aktprocdef:=nil;
  458. end
  459. else
  460. begin
  461. { used to allow private syms to be seen }
  462. aktobjectdef:=tobjectdef(ttypesym(sym).restype.def);
  463. procinfo._class:=tobjectdef(ttypesym(sym).restype.def);
  464. aktprocsym:=tprocsym(procinfo._class.symtable.search(sp));
  465. {The procedure has been found. So it is
  466. a global one. Set the flags to mark this.}
  467. procinfo.flags:=procinfo.flags or pi_is_global;
  468. aktobjectdef:=nil;
  469. { we solve this below }
  470. if assigned(aktprocsym) then
  471. begin
  472. if aktprocsym.typ<>procsym then
  473. begin
  474. { we use a different error message for tp7 so it looks more compatible }
  475. if (m_fpc in aktmodeswitches) then
  476. Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
  477. else
  478. Message(parser_e_methode_id_expected);
  479. { rename the name to an unique name to avoid an
  480. error when inserting the symbol in the symtable }
  481. orgsp:=orgsp+'$'+tostr(aktfilepos.line);
  482. aktprocsym:=nil;
  483. end;
  484. end
  485. else
  486. Message(parser_e_methode_id_expected);
  487. end;
  488. end
  489. else
  490. begin
  491. { check for constructor/destructor which is not allowed here }
  492. if (not parse_only) and
  493. (options in [potype_constructor,potype_destructor]) then
  494. Message(parser_e_constructors_always_objects);
  495. repeat
  496. searchagain:=false;
  497. akttokenpos:=procstartfilepos;
  498. aktprocsym:=tprocsym(symtablestack.search(sp));
  499. if not(parse_only) and
  500. not assigned(aktprocsym) and
  501. (symtablestack.symtabletype=staticsymtable) and
  502. assigned(symtablestack.next) and
  503. (symtablestack.next.unitid=0) then
  504. begin
  505. {The procedure we prepare for is in the implementation
  506. part of the unit we compile. It is also possible that we
  507. are compiling a program, which is also some kind of
  508. implementaion part.
  509. We need to find out if the procedure is global. If it is
  510. global, it is in the global symtable.}
  511. aktprocsym:=tprocsym(symtablestack.next.search(sp));
  512. end;
  513. { Check if overloaded is a procsym }
  514. if assigned(aktprocsym) and
  515. (aktprocsym.typ<>procsym) then
  516. begin
  517. { when the other symbol is a unit symbol then hide the unit
  518. symbol. Only in tp mode because it's bad programming }
  519. if (m_duplicate_names in aktmodeswitches) and
  520. (aktprocsym.typ=unitsym) then
  521. begin
  522. aktprocsym.owner.rename(aktprocsym.name,'hidden'+aktprocsym.name);
  523. searchagain:=true;
  524. end
  525. else
  526. begin
  527. { we use a different error message for tp7 so it looks more compatible }
  528. if (m_fpc in aktmodeswitches) then
  529. Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
  530. else
  531. DuplicateSym(aktprocsym);
  532. { rename the name to an unique name to avoid an
  533. error when inserting the symbol in the symtable }
  534. orgsp:=orgsp+'$'+tostr(aktfilepos.line);
  535. { generate a new aktprocsym }
  536. aktprocsym:=nil;
  537. end;
  538. end;
  539. until not searchagain;
  540. end;
  541. { test again if assigned, it can be reset to recover }
  542. if not assigned(aktprocsym) then
  543. begin
  544. { create a new procsym and set the real filepos }
  545. akttokenpos:=procstartfilepos;
  546. { for operator we have only one procsym for each overloaded
  547. operation }
  548. if (options=potype_operator) then
  549. begin
  550. { is the current overload sym already in the current unit }
  551. if assigned(overloaded_operators[optoken]) and
  552. (overloaded_operators[optoken].owner=symtablestack) then
  553. aktprocsym:=overloaded_operators[optoken]
  554. else
  555. begin
  556. { create the procsym with saving the original case }
  557. aktprocsym:=tprocsym.create('$'+sp);
  558. if assigned(overloaded_operators[optoken]) then
  559. overloaded_operators[optoken].concat_procdefs_to(aktprocsym);
  560. end;
  561. end
  562. else
  563. aktprocsym:=tprocsym.create(orgsp);
  564. symtablestack.insert(aktprocsym);
  565. end
  566. else
  567. begin
  568. { Set global flag when found in globalsytmable }
  569. if (not parse_only) and
  570. (aktprocsym.owner.symtabletype=globalsymtable) then
  571. procinfo.flags:=procinfo.flags or pi_is_global;
  572. end;
  573. st:=symtablestack;
  574. aktprocdef:=tprocdef.create;
  575. aktprocdef.symtablelevel:=symtablestack.symtablelevel;
  576. if assigned(procinfo._class) then
  577. aktprocdef._class := procinfo._class;
  578. { set the options from the caller (podestructor or poconstructor) }
  579. aktprocdef.proctypeoption:=options;
  580. { add procsym to the procdef }
  581. aktprocdef.procsym:=aktprocsym;
  582. { save file position and symbol options }
  583. aktprocdef.fileinfo:=procstartfilepos;
  584. aktprocdef.symoptions:=current_object_option;
  585. { this must also be inserted in the right symtable !! PM }
  586. { otherwise we get subbtle problems with
  587. definitions of args defs in staticsymtable for
  588. implementation of a global method }
  589. if token=_LKLAMMER then
  590. parameter_dec(aktprocdef);
  591. { calculate the offset of the parameters }
  592. paramoffset:=target_info.first_parm_offset;
  593. { calculate frame pointer offset }
  594. if lexlevel>normal_function_level then
  595. begin
  596. procinfo.framepointer_offset:=paramoffset;
  597. inc(paramoffset,pointer_size);
  598. { this is needed to get correct framepointer push for local
  599. forward functions !! }
  600. aktprocdef.parast.symtablelevel:=lexlevel;
  601. end;
  602. { Get self, vmt offsets }
  603. if assigned (procinfo._Class) then
  604. begin
  605. { self pointer offset, must be done after parsing the parameters }
  606. { self isn't pushed in nested procedure of methods }
  607. if (lexlevel=normal_function_level) then
  608. begin
  609. if assigned(aktprocdef) and
  610. not(po_containsself in aktprocdef.procoptions) then
  611. begin
  612. procinfo.selfpointer_offset:=paramoffset;
  613. inc(paramoffset,POINTER_SIZE);
  614. end;
  615. end;
  616. { Special parameters for de-/constructors }
  617. case aktprocdef.proctypeoption of
  618. potype_constructor :
  619. begin
  620. procinfo.vmtpointer_offset:=paramoffset;
  621. inc(paramoffset,POINTER_SIZE);
  622. end;
  623. potype_destructor :
  624. begin
  625. if is_object(procinfo._class) then
  626. begin
  627. procinfo.vmtpointer_offset:=paramoffset;
  628. inc(paramoffset,POINTER_SIZE);
  629. end
  630. else
  631. if is_class(procinfo._class) then
  632. begin
  633. procinfo.inheritedflag_offset:=paramoffset;
  634. inc(paramoffset,POINTER_SIZE);
  635. end
  636. else
  637. internalerror(200303261);
  638. end;
  639. end;
  640. end;
  641. procinfo.para_offset:=paramoffset;
  642. { so we only restore the symtable now }
  643. symtablestack:=st;
  644. if (options=potype_operator) then
  645. overloaded_operators[optoken]:=aktprocsym;
  646. end;
  647. procedure parse_proc_dec;
  648. var
  649. hs : string;
  650. isclassmethod : boolean;
  651. begin
  652. inc(lexlevel);
  653. { read class method }
  654. if try_to_consume(_CLASS) then
  655. begin
  656. { class method only allowed for procedures and functions }
  657. if not(token in [_FUNCTION,_PROCEDURE]) then
  658. Message(parser_e_procedure_or_function_expected);
  659. isclassmethod:=true;
  660. end
  661. else
  662. isclassmethod:=false;
  663. case token of
  664. _FUNCTION : begin
  665. consume(_FUNCTION);
  666. parse_proc_head(potype_none);
  667. if token<>_COLON then
  668. begin
  669. if assigned(aktprocsym) and
  670. not(is_interface(aktprocdef._class)) and
  671. not(aktprocdef.forwarddef) or
  672. (m_repeat_forward in aktmodeswitches) then
  673. begin
  674. consume(_COLON);
  675. consume_all_until(_SEMICOLON);
  676. end;
  677. end
  678. else
  679. begin
  680. consume(_COLON);
  681. inc(testcurobject);
  682. single_type(aktprocdef.rettype,hs,false);
  683. aktprocdef.test_if_fpu_result;
  684. if (aktprocdef.rettype.def.deftype=stringdef) and
  685. (tstringdef(aktprocdef.rettype.def).string_typ<>st_shortstring) then
  686. procinfo.no_fast_exit:=true;
  687. dec(testcurobject);
  688. end;
  689. end;
  690. _PROCEDURE : begin
  691. consume(_PROCEDURE);
  692. parse_proc_head(potype_none);
  693. if assigned(aktprocsym) then
  694. aktprocdef.rettype:=voidtype;
  695. end;
  696. _CONSTRUCTOR : begin
  697. consume(_CONSTRUCTOR);
  698. parse_proc_head(potype_constructor);
  699. if assigned(procinfo._class) and
  700. is_class(procinfo._class) then
  701. begin
  702. { CLASS constructors return the created instance }
  703. aktprocdef.rettype.setdef(procinfo._class);
  704. end
  705. else
  706. begin
  707. { OBJECT constructors return a boolean }
  708. aktprocdef.rettype:=booltype;
  709. end;
  710. end;
  711. _DESTRUCTOR : begin
  712. consume(_DESTRUCTOR);
  713. parse_proc_head(potype_destructor);
  714. aktprocdef.rettype:=voidtype;
  715. end;
  716. _OPERATOR : begin
  717. if lexlevel>normal_function_level then
  718. Message(parser_e_no_local_operator);
  719. consume(_OPERATOR);
  720. if (token in [first_overloaded..last_overloaded]) then
  721. begin
  722. procinfo.flags:=procinfo.flags or pi_operator;
  723. optoken:=token;
  724. end
  725. else
  726. begin
  727. Message(parser_e_overload_operator_failed);
  728. { Use the dummy NOTOKEN that is also declared
  729. for the overloaded_operator[] }
  730. optoken:=NOTOKEN;
  731. end;
  732. consume(Token);
  733. parse_proc_head(potype_operator);
  734. if token<>_ID then
  735. begin
  736. otsym:=nil;
  737. if not(m_result in aktmodeswitches) then
  738. consume(_ID);
  739. end
  740. else
  741. begin
  742. otsym:=tvarsym.create(pattern,voidtype);
  743. consume(_ID);
  744. end;
  745. if not try_to_consume(_COLON) then
  746. begin
  747. consume(_COLON);
  748. aktprocdef.rettype:=generrortype;
  749. consume_all_until(_SEMICOLON);
  750. end
  751. else
  752. begin
  753. single_type(aktprocdef.rettype,hs,false);
  754. aktprocdef.test_if_fpu_result;
  755. if (optoken in [_EQUAL,_GT,_LT,_GTE,_LTE]) and
  756. ((aktprocdef.rettype.def.deftype<>orddef) or
  757. (torddef(aktprocdef.rettype.def).typ<>bool8bit)) then
  758. Message(parser_e_comparative_operator_return_boolean);
  759. if assigned(otsym) then
  760. otsym.vartype.def:=aktprocdef.rettype.def;
  761. if (optoken=_ASSIGNMENT) and
  762. equal_defs(aktprocdef.rettype.def,
  763. tvarsym(aktprocdef.parast.symindex.first).vartype.def) then
  764. message(parser_e_no_such_assignment)
  765. else if not isoperatoracceptable(aktprocdef,optoken) then
  766. Message(parser_e_overload_impossible);
  767. end;
  768. end;
  769. end;
  770. if isclassmethod and
  771. assigned(aktprocsym) then
  772. include(aktprocdef.procoptions,po_classmethod);
  773. { support procedure proc;stdcall export; in Delphi mode only }
  774. if not((m_delphi in aktmodeswitches) and
  775. is_proc_directive(token)) then
  776. consume(_SEMICOLON);
  777. dec(lexlevel);
  778. end;
  779. {****************************************************************************
  780. Procedure directive handlers
  781. ****************************************************************************}
  782. procedure pd_far;
  783. begin
  784. Message1(parser_w_proc_directive_ignored,'FAR');
  785. end;
  786. procedure pd_near;
  787. begin
  788. Message1(parser_w_proc_directive_ignored,'NEAR');
  789. end;
  790. procedure pd_export;
  791. begin
  792. if assigned(procinfo._class) then
  793. Message(parser_e_methods_dont_be_export);
  794. if lexlevel<>normal_function_level then
  795. Message(parser_e_dont_nest_export);
  796. { only os/2 and emx need this }
  797. if target_info.system in [system_i386_os2,system_i386_emx] then
  798. begin
  799. aktprocdef.aliasnames.insert(aktprocsym.realname);
  800. procinfo.exported:=true;
  801. if cs_link_deffile in aktglobalswitches then
  802. deffile.AddExport(aktprocdef.mangledname);
  803. end;
  804. end;
  805. procedure pd_forward;
  806. begin
  807. aktprocdef.forwarddef:=true;
  808. end;
  809. procedure pd_alias;
  810. begin
  811. consume(_COLON);
  812. aktprocdef.aliasnames.insert(get_stringconst);
  813. end;
  814. procedure pd_asmname;
  815. begin
  816. aktprocdef.setmangledname(target_info.Cprefix+pattern);
  817. if token=_CCHAR then
  818. consume(_CCHAR)
  819. else
  820. consume(_CSTRING);
  821. { we don't need anything else }
  822. aktprocdef.forwarddef:=false;
  823. end;
  824. procedure pd_inline;
  825. var
  826. hp : tparaitem;
  827. begin
  828. { check if there is an array of const }
  829. hp:=tparaitem(aktprocdef.para.first);
  830. while assigned(hp) do
  831. begin
  832. if assigned(hp.paratype.def) and
  833. (hp.paratype.def.deftype=arraydef) then
  834. begin
  835. with tarraydef(hp.paratype.def) do
  836. if IsVariant or IsConstructor {or IsArrayOfConst} then
  837. begin
  838. Message1(parser_w_not_supported_for_inline,'array of const');
  839. Message(parser_w_inlining_disabled);
  840. aktprocdef.proccalloption:=pocall_fpccall;
  841. end;
  842. end;
  843. hp:=tparaitem(hp.next);
  844. end;
  845. end;
  846. procedure pd_intern;
  847. begin
  848. consume(_COLON);
  849. aktprocdef.extnumber:=get_intconst;
  850. end;
  851. procedure pd_interrupt;
  852. begin
  853. if lexlevel<>normal_function_level then
  854. Message(parser_e_dont_nest_interrupt);
  855. end;
  856. procedure pd_abstract;
  857. begin
  858. if (po_virtualmethod in aktprocdef.procoptions) then
  859. include(aktprocdef.procoptions,po_abstractmethod)
  860. else
  861. Message(parser_e_only_virtual_methods_abstract);
  862. { the method is defined }
  863. aktprocdef.forwarddef:=false;
  864. end;
  865. procedure pd_virtual;
  866. {$ifdef WITHDMT}
  867. var
  868. pt : tnode;
  869. {$endif WITHDMT}
  870. begin
  871. if (aktprocdef.proctypeoption=potype_constructor) and
  872. is_object(aktprocdef._class) then
  873. Message(parser_e_constructor_cannot_be_not_virtual);
  874. {$ifdef WITHDMT}
  875. if is_object(aktprocdef._class) and
  876. (token<>_SEMICOLON) then
  877. begin
  878. { any type of parameter is allowed here! }
  879. pt:=comp_expr(true);
  880. if is_constintnode(pt) then
  881. begin
  882. include(aktprocdef.procoptions,po_msgint);
  883. aktprocdef.messageinf.i:=pt^.value;
  884. end
  885. else
  886. Message(parser_e_ill_msg_expr);
  887. disposetree(pt);
  888. end;
  889. {$endif WITHDMT}
  890. end;
  891. procedure pd_static;
  892. begin
  893. if (cs_static_keyword in aktmoduleswitches) then
  894. begin
  895. include(aktprocsym.symoptions,sp_static);
  896. include(aktprocdef.procoptions,po_staticmethod);
  897. end;
  898. end;
  899. procedure pd_override;
  900. begin
  901. if not(is_class_or_interface(aktprocdef._class)) then
  902. Message(parser_e_no_object_override);
  903. end;
  904. procedure pd_overload;
  905. begin
  906. include(aktprocsym.symoptions,sp_has_overloaded);
  907. end;
  908. procedure pd_message;
  909. var
  910. pt : tnode;
  911. begin
  912. if not is_class(aktprocdef._class) then
  913. Message(parser_e_msg_only_for_classes);
  914. { check parameter type }
  915. if not(po_containsself in aktprocdef.procoptions) and
  916. ((aktprocdef.minparacount<>1) or
  917. (aktprocdef.maxparacount<>1) or
  918. (TParaItem(aktprocdef.Para.first).paratyp<>vs_var)) then
  919. Message(parser_e_ill_msg_param);
  920. pt:=comp_expr(true);
  921. if pt.nodetype=stringconstn then
  922. begin
  923. include(aktprocdef.procoptions,po_msgstr);
  924. aktprocdef.messageinf.str:=strnew(tstringconstnode(pt).value_str);
  925. end
  926. else
  927. if is_constintnode(pt) then
  928. begin
  929. include(aktprocdef.procoptions,po_msgint);
  930. aktprocdef.messageinf.i:=tordconstnode(pt).value;
  931. end
  932. else
  933. Message(parser_e_ill_msg_expr);
  934. pt.free;
  935. end;
  936. procedure pd_reintroduce;
  937. begin
  938. Message1(parser_w_proc_directive_ignored,'REINTRODUCE');
  939. end;
  940. procedure pd_syscall;
  941. begin
  942. aktprocdef.forwarddef:=false;
  943. aktprocdef.extnumber:=get_intconst;
  944. end;
  945. procedure pd_external;
  946. {
  947. If import_dll=nil the procedure is assumed to be in another
  948. object file. In that object file it should have the name to
  949. which import_name is pointing to. Otherwise, the procedure is
  950. assumed to be in the DLL to which import_dll is pointing to. In
  951. that case either import_nr<>0 or import_name<>nil is true, so
  952. the procedure is either imported by number or by name. (DM)
  953. }
  954. var
  955. pd : tprocdef;
  956. import_dll,
  957. import_name : string;
  958. import_nr : word;
  959. begin
  960. aktprocdef.forwarddef:=false;
  961. { forbid local external procedures }
  962. if lexlevel>normal_function_level then
  963. Message(parser_e_no_local_external);
  964. { If the procedure should be imported from a DLL, a constant string follows.
  965. This isn't really correct, an contant string expression follows
  966. so we check if an semicolon follows, else a string constant have to
  967. follow (FK) }
  968. import_nr:=0;
  969. import_name:='';
  970. if not(token=_SEMICOLON) and not(idtoken=_NAME) then
  971. begin
  972. import_dll:=get_stringconst;
  973. if (idtoken=_NAME) then
  974. begin
  975. consume(_NAME);
  976. import_name:=get_stringconst;
  977. end;
  978. if (idtoken=_INDEX) then
  979. begin
  980. {After the word index follows the index number in the DLL.}
  981. consume(_INDEX);
  982. import_nr:=get_intconst;
  983. end;
  984. { default is to used the realname of the procedure }
  985. if (import_nr=0) and (import_name='') then
  986. import_name:=aktprocsym.realname;
  987. { create importlib if not already done }
  988. if not(current_module.uses_imports) then
  989. begin
  990. current_module.uses_imports:=true;
  991. importlib.preparelib(current_module.modulename^);
  992. end;
  993. if not(m_repeat_forward in aktmodeswitches) then
  994. begin
  995. { we can only have one overloaded here ! }
  996. if aktprocsym.procdef_count>1 then
  997. pd:=aktprocsym.procdef[2]
  998. else
  999. pd:=aktprocdef;
  1000. end
  1001. else
  1002. pd:=aktprocdef;
  1003. importlib.importproceduredef(pd,import_dll,import_nr,import_name);
  1004. end
  1005. else
  1006. begin
  1007. if (idtoken=_NAME) then
  1008. begin
  1009. consume(_NAME);
  1010. import_name:=get_stringconst;
  1011. aktprocdef.setmangledname(import_name);
  1012. end;
  1013. end;
  1014. end;
  1015. type
  1016. pd_handler=procedure;
  1017. proc_dir_rec=record
  1018. idtok : ttoken;
  1019. pd_flags : longint;
  1020. handler : pd_handler;
  1021. pocall : tproccalloption;
  1022. pooption : tprocoptions;
  1023. mutexclpocall : tproccalloptions;
  1024. mutexclpotype : tproctypeoptions;
  1025. mutexclpo : tprocoptions;
  1026. end;
  1027. const
  1028. {Should contain the number of procedure directives we support.}
  1029. num_proc_directives=36;
  1030. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  1031. (
  1032. (
  1033. idtok:_ABSTRACT;
  1034. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1035. handler : {$ifdef FPCPROCVAR}@{$endif}pd_abstract;
  1036. pocall : pocall_none;
  1037. pooption : [po_abstractmethod];
  1038. mutexclpocall : [pocall_internproc,pocall_inline];
  1039. mutexclpotype : [potype_constructor,potype_destructor];
  1040. mutexclpo : [po_exports,po_interrupt,po_external]
  1041. ),(
  1042. idtok:_ALIAS;
  1043. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1044. handler : {$ifdef FPCPROCVAR}@{$endif}pd_alias;
  1045. pocall : pocall_none;
  1046. pooption : [];
  1047. mutexclpocall : [pocall_inline];
  1048. mutexclpotype : [];
  1049. mutexclpo : [po_external]
  1050. ),(
  1051. idtok:_ASMNAME;
  1052. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  1053. handler : {$ifdef FPCPROCVAR}@{$endif}pd_asmname;
  1054. pocall : pocall_cdecl;
  1055. pooption : [po_external];
  1056. mutexclpocall : [pocall_internproc,pocall_inline];
  1057. mutexclpotype : [];
  1058. mutexclpo : [po_external]
  1059. ),(
  1060. idtok:_ASSEMBLER;
  1061. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1062. handler : nil;
  1063. pocall : pocall_none;
  1064. pooption : [po_assembler];
  1065. mutexclpocall : [];
  1066. mutexclpotype : [];
  1067. mutexclpo : [po_external]
  1068. ),(
  1069. idtok:_CDECL;
  1070. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1071. handler : nil;
  1072. pocall : pocall_cdecl;
  1073. pooption : [];
  1074. mutexclpocall : [];
  1075. mutexclpotype : [potype_constructor,potype_destructor];
  1076. mutexclpo : [po_assembler,po_external]
  1077. ),(
  1078. idtok:_DYNAMIC;
  1079. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1080. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  1081. pocall : pocall_none;
  1082. pooption : [po_virtualmethod];
  1083. mutexclpocall : [pocall_internproc,pocall_inline];
  1084. mutexclpotype : [];
  1085. mutexclpo : [po_exports,po_interrupt,po_external]
  1086. ),(
  1087. idtok:_EXPORT;
  1088. pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??}+pd_notobjintf;
  1089. handler : {$ifdef FPCPROCVAR}@{$endif}pd_export;
  1090. pocall : pocall_none;
  1091. pooption : [po_exports];
  1092. mutexclpocall : [pocall_internproc,pocall_inline];
  1093. mutexclpotype : [potype_constructor,potype_destructor];
  1094. mutexclpo : [po_external,po_interrupt]
  1095. ),(
  1096. idtok:_EXTERNAL;
  1097. pd_flags : pd_implemen+pd_interface+pd_notobject+pd_notobjintf;
  1098. handler : {$ifdef FPCPROCVAR}@{$endif}pd_external;
  1099. pocall : pocall_none;
  1100. pooption : [po_external];
  1101. mutexclpocall : [pocall_internproc,pocall_inline,pocall_palmossyscall];
  1102. mutexclpotype : [potype_constructor,potype_destructor];
  1103. mutexclpo : [po_exports,po_interrupt,po_assembler]
  1104. ),(
  1105. idtok:_FAR;
  1106. pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar+pd_notobject+pd_notobjintf;
  1107. handler : {$ifdef FPCPROCVAR}@{$endif}pd_far;
  1108. pocall : pocall_none;
  1109. pooption : [];
  1110. mutexclpocall : [pocall_internproc,pocall_inline];
  1111. mutexclpotype : [];
  1112. mutexclpo : []
  1113. ),(
  1114. idtok:_FAR16;
  1115. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar+pd_notobject;
  1116. handler : nil;
  1117. pocall : pocall_far16;
  1118. pooption : [];
  1119. mutexclpocall : [];
  1120. mutexclpotype : [];
  1121. mutexclpo : [po_external,po_leftright]
  1122. ),(
  1123. idtok:_FORWARD;
  1124. pd_flags : pd_implemen+pd_notobject+pd_notobjintf;
  1125. handler : {$ifdef FPCPROCVAR}@{$endif}pd_forward;
  1126. pocall : pocall_none;
  1127. pooption : [];
  1128. mutexclpocall : [pocall_internproc,pocall_inline];
  1129. mutexclpotype : [];
  1130. mutexclpo : [po_external]
  1131. ),(
  1132. idtok:_FPCCALL;
  1133. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1134. handler : nil;
  1135. pocall : pocall_fpccall;
  1136. pooption : [];
  1137. mutexclpocall : [];
  1138. mutexclpotype : [];
  1139. mutexclpo : [po_leftright]
  1140. ),(
  1141. idtok:_INLINE;
  1142. pd_flags : pd_interface+pd_implemen+pd_body+pd_notobjintf;
  1143. handler : {$ifdef FPCPROCVAR}@{$endif}pd_inline;
  1144. pocall : pocall_inline;
  1145. pooption : [];
  1146. mutexclpocall : [];
  1147. mutexclpotype : [potype_constructor,potype_destructor];
  1148. mutexclpo : [po_exports,po_external,po_interrupt]
  1149. ),(
  1150. idtok:_INTERNCONST;
  1151. pd_flags : pd_implemen+pd_body+pd_notobject+pd_notobjintf;
  1152. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1153. pocall : pocall_none;
  1154. pooption : [po_internconst];
  1155. mutexclpocall : [];
  1156. mutexclpotype : [potype_operator];
  1157. mutexclpo : []
  1158. ),(
  1159. idtok:_INTERNPROC;
  1160. pd_flags : pd_implemen+pd_notobject+pd_notobjintf;
  1161. handler : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
  1162. pocall : pocall_internproc;
  1163. pooption : [];
  1164. mutexclpocall : [];
  1165. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1166. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_leftright]
  1167. ),(
  1168. idtok:_INTERRUPT;
  1169. pd_flags : pd_implemen+pd_body+pd_notobject+pd_notobjintf;
  1170. handler : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
  1171. pocall : pocall_none;
  1172. pooption : [po_interrupt];
  1173. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,
  1174. pocall_inline,pocall_pascal,pocall_system,pocall_far16,pocall_fpccall];
  1175. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1176. mutexclpo : [po_external,po_leftright,po_clearstack]
  1177. ),(
  1178. idtok:_IOCHECK;
  1179. pd_flags : pd_implemen+pd_body+pd_notobjintf;
  1180. handler : nil;
  1181. pocall : pocall_none;
  1182. pooption : [po_iocheck];
  1183. mutexclpocall : [pocall_internproc];
  1184. mutexclpotype : [];
  1185. mutexclpo : [po_external]
  1186. ),(
  1187. idtok:_MESSAGE;
  1188. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1189. handler : {$ifdef FPCPROCVAR}@{$endif}pd_message;
  1190. pocall : pocall_none;
  1191. pooption : []; { can be po_msgstr or po_msgint }
  1192. mutexclpocall : [pocall_inline,pocall_internproc];
  1193. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1194. mutexclpo : [po_interrupt,po_external]
  1195. ),(
  1196. idtok:_NEAR;
  1197. pd_flags : pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1198. handler : {$ifdef FPCPROCVAR}@{$endif}pd_near;
  1199. pocall : pocall_none;
  1200. pooption : [];
  1201. mutexclpocall : [pocall_internproc];
  1202. mutexclpotype : [];
  1203. mutexclpo : []
  1204. ),(
  1205. idtok:_OVERLOAD;
  1206. pd_flags : pd_implemen+pd_interface+pd_body;
  1207. handler : {$ifdef FPCPROCVAR}@{$endif}pd_overload;
  1208. pocall : pocall_none;
  1209. pooption : [po_overload];
  1210. mutexclpocall : [pocall_internproc];
  1211. mutexclpotype : [];
  1212. mutexclpo : []
  1213. ),(
  1214. idtok:_OVERRIDE;
  1215. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1216. handler : {$ifdef FPCPROCVAR}@{$endif}pd_override;
  1217. pocall : pocall_none;
  1218. pooption : [po_overridingmethod,po_virtualmethod];
  1219. mutexclpocall : [pocall_inline,pocall_internproc];
  1220. mutexclpotype : [];
  1221. mutexclpo : [po_exports,po_external,po_interrupt]
  1222. ),(
  1223. idtok:_PASCAL;
  1224. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1225. handler : nil;
  1226. pocall : pocall_pascal;
  1227. pooption : [];
  1228. mutexclpocall : [];
  1229. mutexclpotype : [potype_constructor,potype_destructor];
  1230. mutexclpo : [po_external]
  1231. ),(
  1232. idtok:_POPSTACK;
  1233. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1234. handler : nil;
  1235. pocall : pocall_none;
  1236. pooption : [po_clearstack];
  1237. mutexclpocall : [pocall_inline,pocall_internproc,pocall_stdcall];
  1238. mutexclpotype : [potype_constructor,potype_destructor];
  1239. mutexclpo : [po_assembler,po_external]
  1240. ),(
  1241. idtok:_PUBLIC;
  1242. pd_flags : pd_implemen+pd_body+pd_global+pd_notobject+pd_notobjintf;
  1243. handler : nil;
  1244. pocall : pocall_none;
  1245. pooption : [];
  1246. mutexclpocall : [pocall_internproc,pocall_inline];
  1247. mutexclpotype : [];
  1248. mutexclpo : [po_external]
  1249. ),(
  1250. idtok:_REGISTER;
  1251. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1252. handler : nil;
  1253. pocall : pocall_register;
  1254. pooption : [];
  1255. mutexclpocall : [];
  1256. mutexclpotype : [potype_constructor,potype_destructor];
  1257. mutexclpo : [po_external]
  1258. ),(
  1259. idtok:_REINTRODUCE;
  1260. pd_flags : pd_interface+pd_object;
  1261. handler : {$ifdef FPCPROCVAR}@{$endif}pd_reintroduce;
  1262. pocall : pocall_none;
  1263. pooption : [];
  1264. mutexclpocall : [];
  1265. mutexclpotype : [];
  1266. mutexclpo : []
  1267. ),(
  1268. idtok:_SAFECALL;
  1269. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1270. handler : nil;
  1271. pocall : pocall_safecall;
  1272. pooption : [];
  1273. mutexclpocall : [];
  1274. mutexclpotype : [potype_constructor,potype_destructor];
  1275. mutexclpo : [po_external]
  1276. ),(
  1277. idtok:_SAVEREGISTERS;
  1278. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar+pd_notobjintf;
  1279. handler : nil;
  1280. pocall : pocall_none;
  1281. pooption : [po_saveregisters];
  1282. mutexclpocall : [pocall_internproc];
  1283. mutexclpotype : [potype_constructor,potype_destructor];
  1284. mutexclpo : [po_external]
  1285. ),(
  1286. idtok:_STATIC;
  1287. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1288. handler : {$ifdef FPCPROCVAR}@{$endif}pd_static;
  1289. pocall : pocall_none;
  1290. pooption : [po_staticmethod];
  1291. mutexclpocall : [pocall_inline,pocall_internproc];
  1292. mutexclpotype : [potype_constructor,potype_destructor];
  1293. mutexclpo : [po_external,po_interrupt,po_exports]
  1294. ),(
  1295. idtok:_STDCALL;
  1296. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1297. handler : nil;
  1298. pocall : pocall_stdcall;
  1299. pooption : [];
  1300. mutexclpocall : [];
  1301. mutexclpotype : [potype_constructor,potype_destructor];
  1302. mutexclpo : [po_external]
  1303. ),(
  1304. idtok:_SYSCALL;
  1305. pd_flags : pd_interface+pd_implemen+pd_notobjintf;
  1306. handler : {$ifdef FPCPROCVAR}@{$endif}pd_syscall;
  1307. pocall : pocall_palmossyscall;
  1308. pooption : [];
  1309. mutexclpocall : [];
  1310. mutexclpotype : [potype_constructor,potype_destructor];
  1311. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  1312. ),(
  1313. idtok:_SYSTEM;
  1314. pd_flags : pd_implemen+pd_notobject+pd_notobjintf;
  1315. handler : nil;
  1316. pocall : pocall_system;
  1317. pooption : [];
  1318. mutexclpocall : [];
  1319. mutexclpotype : [potype_constructor,potype_destructor];
  1320. mutexclpo : [po_external,po_assembler,po_interrupt]
  1321. ),(
  1322. idtok:_VIRTUAL;
  1323. pd_flags : pd_interface+pd_object+pd_notobjintf;
  1324. handler : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
  1325. pocall : pocall_none;
  1326. pooption : [po_virtualmethod];
  1327. mutexclpocall : [pocall_inline,pocall_internproc];
  1328. mutexclpotype : [];
  1329. mutexclpo : [po_external,po_interrupt,po_exports]
  1330. ),(
  1331. idtok:_CPPDECL;
  1332. pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
  1333. handler : nil;
  1334. pocall : pocall_cppdecl;
  1335. pooption : [po_savestdregs];
  1336. mutexclpocall : [];
  1337. mutexclpotype : [potype_constructor,potype_destructor];
  1338. mutexclpo : [po_assembler,po_external,po_virtualmethod]
  1339. ),(
  1340. idtok:_VARARGS;
  1341. pd_flags : pd_interface+pd_implemen+pd_procvar;
  1342. handler : nil;
  1343. pocall : pocall_none;
  1344. pooption : [po_varargs];
  1345. mutexclpocall : [pocall_internproc,pocall_stdcall,pocall_register,
  1346. pocall_inline,pocall_far16,pocall_fpccall];
  1347. mutexclpotype : [];
  1348. mutexclpo : [po_assembler,po_interrupt,po_leftright]
  1349. ),(
  1350. idtok:_COMPILERPROC;
  1351. pd_flags : pd_interface+pd_implemen+pd_body+pd_notobjintf;
  1352. handler : nil;
  1353. pocall : pocall_compilerproc;
  1354. pooption : [];
  1355. mutexclpocall : [];
  1356. mutexclpotype : [potype_constructor,potype_destructor];
  1357. mutexclpo : [po_interrupt]
  1358. )
  1359. );
  1360. function is_proc_directive(tok:ttoken):boolean;
  1361. var
  1362. i : longint;
  1363. begin
  1364. is_proc_directive:=false;
  1365. for i:=1 to num_proc_directives do
  1366. if proc_direcdata[i].idtok=idtoken then
  1367. begin
  1368. is_proc_directive:=true;
  1369. exit;
  1370. end;
  1371. end;
  1372. function parse_proc_direc(var pdflags:word):boolean;
  1373. {
  1374. Parse the procedure directive, returns true if a correct directive is found
  1375. }
  1376. var
  1377. p : longint;
  1378. found : boolean;
  1379. name : stringid;
  1380. begin
  1381. parse_proc_direc:=false;
  1382. name:=tokeninfo^[idtoken].str;
  1383. found:=false;
  1384. { Hint directive? Then exit immediatly }
  1385. if (m_hintdirective in aktmodeswitches) then
  1386. begin
  1387. case idtoken of
  1388. _LIBRARY,
  1389. _PLATFORM,
  1390. _UNIMPLEMENTED,
  1391. _DEPRECATED :
  1392. exit;
  1393. end;
  1394. end;
  1395. { retrieve data for directive if found }
  1396. for p:=1 to num_proc_directives do
  1397. if proc_direcdata[p].idtok=idtoken then
  1398. begin
  1399. found:=true;
  1400. break;
  1401. end;
  1402. { Check if the procedure directive is known }
  1403. if not found then
  1404. begin
  1405. { parsing a procvar type the name can be any
  1406. next variable !! }
  1407. if (pdflags and (pd_procvar or pd_object))=0 then
  1408. Message1(parser_w_unknown_proc_directive_ignored,name);
  1409. exit;
  1410. end;
  1411. { static needs a special treatment }
  1412. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  1413. exit;
  1414. { Conflicts between directives ? }
  1415. if (aktprocdef.proctypeoption in proc_direcdata[p].mutexclpotype) or
  1416. (aktprocdef.proccalloption in proc_direcdata[p].mutexclpocall) or
  1417. ((aktprocdef.procoptions*proc_direcdata[p].mutexclpo)<>[]) then
  1418. begin
  1419. Message1(parser_e_proc_dir_conflict,name);
  1420. exit;
  1421. end;
  1422. { set calling convention }
  1423. if proc_direcdata[p].pocall<>pocall_none then
  1424. begin
  1425. if aktprocdef.proccalloption<>pocall_none then
  1426. begin
  1427. Message2(parser_w_proc_overriding_calling,
  1428. proccalloptionStr[aktprocdef.proccalloption],
  1429. proccalloptionStr[proc_direcdata[p].pocall]);
  1430. end;
  1431. aktprocdef.proccalloption:=proc_direcdata[p].pocall;
  1432. end;
  1433. { check if method and directive not for object, like public.
  1434. This needs to be checked also for procvars }
  1435. if ((proc_direcdata[p].pd_flags and pd_notobject)<>0) and
  1436. (aktprocdef.owner.symtabletype=objectsymtable) then
  1437. exit;
  1438. if aktprocdef.deftype=procdef then
  1439. begin
  1440. { Check if the directive is only for objects }
  1441. if ((proc_direcdata[p].pd_flags and pd_object)<>0) and
  1442. not assigned(aktprocdef._class) then
  1443. exit;
  1444. { check if method and directive not for interface }
  1445. if ((proc_direcdata[p].pd_flags and pd_notobjintf)<>0) and
  1446. is_interface(aktprocdef._class) then
  1447. exit;
  1448. end;
  1449. { consume directive, and turn flag on }
  1450. consume(token);
  1451. parse_proc_direc:=true;
  1452. { Check the pd_flags if the directive should be allowed }
  1453. if ((pdflags and pd_interface)<>0) and
  1454. ((proc_direcdata[p].pd_flags and pd_interface)=0) then
  1455. begin
  1456. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1457. exit;
  1458. end;
  1459. if ((pdflags and pd_implemen)<>0) and
  1460. ((proc_direcdata[p].pd_flags and pd_implemen)=0) then
  1461. begin
  1462. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1463. exit;
  1464. end;
  1465. if ((pdflags and pd_procvar)<>0) and
  1466. ((proc_direcdata[p].pd_flags and pd_procvar)=0) then
  1467. begin
  1468. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1469. exit;
  1470. end;
  1471. { Return the new pd_flags }
  1472. if (proc_direcdata[p].pd_flags and pd_body)=0 then
  1473. pdflags:=pdflags and (not pd_body);
  1474. if (proc_direcdata[p].pd_flags and pd_global)<>0 then
  1475. pdflags:=pdflags or pd_global;
  1476. { Add the correct flag }
  1477. aktprocdef.procoptions:=aktprocdef.procoptions+proc_direcdata[p].pooption;
  1478. { Call the handler }
  1479. if pointer({$ifndef FPCPROCVAR}@{$endif}proc_direcdata[p].handler)<>nil then
  1480. proc_direcdata[p].handler{$ifdef FPCPROCVAR}(){$endif};
  1481. end;
  1482. procedure handle_calling_convention(sym:tprocsym;def:tabstractprocdef);
  1483. begin
  1484. { set the default calling convention }
  1485. if def.proccalloption=pocall_none then
  1486. def.proccalloption:=aktdefproccall;
  1487. { handle proccall specific settings }
  1488. case def.proccalloption of
  1489. pocall_cdecl :
  1490. begin
  1491. { use popstack and save std registers }
  1492. include(def.procoptions,po_clearstack);
  1493. include(def.procoptions,po_savestdregs);
  1494. { set mangledname }
  1495. if (def.deftype=procdef) then
  1496. begin
  1497. if not tprocdef(def).has_mangledname then
  1498. begin
  1499. if assigned(tprocdef(def)._class) then
  1500. tprocdef(def).setmangledname(target_info.Cprefix+tprocdef(def)._class.objrealname^+'_'+sym.realname)
  1501. else
  1502. tprocdef(def).setmangledname(target_info.Cprefix+sym.realname);
  1503. end;
  1504. if not assigned(tprocdef(def).parast) then
  1505. internalerror(200110234);
  1506. { check C cdecl para types }
  1507. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_c_para,nil);
  1508. { Adjust alignment to match cdecl or stdcall }
  1509. tprocdef(def).parast.dataalignment:=std_param_align;
  1510. end;
  1511. end;
  1512. pocall_cppdecl :
  1513. begin
  1514. if not assigned(sym) then
  1515. internalerror(200110231);
  1516. { use popstack and save std registers }
  1517. include(def.procoptions,po_clearstack);
  1518. include(def.procoptions,po_savestdregs);
  1519. { set mangledname }
  1520. if (def.deftype=procdef) then
  1521. begin
  1522. if not tprocdef(def).has_mangledname then
  1523. tprocdef(def).setmangledname(target_info.Cprefix+tprocdef(def).cplusplusmangledname);
  1524. if not assigned(tprocdef(def).parast) then
  1525. internalerror(200110235);
  1526. { check C cdecl para types }
  1527. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}check_c_para,nil);
  1528. { Adjust alignment to match cdecl or stdcall }
  1529. tprocdef(def).parast.dataalignment:=std_param_align;
  1530. end;
  1531. end;
  1532. pocall_stdcall :
  1533. begin
  1534. include(def.procoptions,po_savestdregs);
  1535. if (def.deftype=procdef) then
  1536. begin
  1537. if not assigned(tprocdef(def).parast) then
  1538. internalerror(200110236);
  1539. { Adjust alignment to match cdecl or stdcall }
  1540. tprocdef(def).parast.dataalignment:=std_param_align;
  1541. end;
  1542. end;
  1543. pocall_safecall :
  1544. begin
  1545. include(def.procoptions,po_savestdregs);
  1546. end;
  1547. pocall_compilerproc :
  1548. begin
  1549. if (not assigned(sym)) or
  1550. (def.deftype<>procdef) then
  1551. internalerror(200110232);
  1552. tprocdef(def).setmangledname(lower(sym.name));
  1553. end;
  1554. pocall_pascal :
  1555. begin
  1556. include(def.procoptions,po_leftright);
  1557. end;
  1558. pocall_register :
  1559. begin
  1560. Message1(parser_w_proc_directive_ignored,'REGISTER');
  1561. end;
  1562. pocall_far16 :
  1563. begin
  1564. { Temporary stub, must be rewritten to support OS/2 far16 }
  1565. Message1(parser_w_proc_directive_ignored,'FAR16');
  1566. end;
  1567. pocall_system :
  1568. begin
  1569. include(def.procoptions,po_clearstack);
  1570. if (not assigned(sym)) or
  1571. (def.deftype<>procdef) then
  1572. internalerror(200110233);
  1573. if not tprocdef(def).has_mangledname then
  1574. tprocdef(def).setmangledname(sym.realname);
  1575. end;
  1576. pocall_palmossyscall :
  1577. begin
  1578. { use popstack and save std registers }
  1579. include(def.procoptions,po_clearstack);
  1580. include(def.procoptions,po_savestdregs);
  1581. if (def.deftype=procdef) then
  1582. begin
  1583. if not assigned(tprocdef(def).parast) then
  1584. internalerror(200110236);
  1585. { Adjust positions of args for cdecl or stdcall }
  1586. tprocdef(def).parast.dataalignment:=std_param_align;
  1587. end;
  1588. end;
  1589. pocall_inline :
  1590. begin
  1591. if not(cs_support_inline in aktmoduleswitches) then
  1592. begin
  1593. Message(parser_e_proc_inline_not_supported);
  1594. def.proccalloption:=pocall_fpccall;
  1595. end;
  1596. end;
  1597. end;
  1598. { insert hidden high parameters }
  1599. insert_hidden_para(def);
  1600. { insert local valXXX value parameters }
  1601. if (def.deftype=procdef) then
  1602. tprocdef(def).parast.foreach_static({$ifdef FPCPROCVAR}@{$endif}checkvaluepara,nil);
  1603. { add mangledname to external list }
  1604. if (def.deftype=procdef) and
  1605. (po_external in def.procoptions) and
  1606. target_info.DllScanSupported then
  1607. current_module.externals.insert(tExternalsItem.create(tprocdef(def).mangledname));
  1608. end;
  1609. procedure calc_parasymtable_addresses(pd:tprocdef);
  1610. var
  1611. currpara : tparaitem;
  1612. st : tsymtable;
  1613. begin
  1614. st:=pd.parast;
  1615. if po_leftright in pd.procoptions then
  1616. begin
  1617. { pushed from left to right, so the in reverse order
  1618. on the stack }
  1619. currpara:=tparaitem(pd.para.last);
  1620. while assigned(currpara) do
  1621. begin
  1622. if not(assigned(currpara.parasym) and (currpara.parasym.typ=varsym)) then
  1623. internalerror(200304231);
  1624. st.insertvardata(currpara.parasym);
  1625. currpara:=tparaitem(currpara.previous);
  1626. end;
  1627. end
  1628. else
  1629. begin
  1630. { pushed from right to left }
  1631. currpara:=tparaitem(pd.para.first);
  1632. while assigned(currpara) do
  1633. begin
  1634. if not(assigned(currpara.parasym) and (currpara.parasym.typ=varsym)) then
  1635. internalerror(200304232);
  1636. st.insertvardata(currpara.parasym);
  1637. currpara:=tparaitem(currpara.next);
  1638. end;
  1639. end;
  1640. end;
  1641. procedure parse_proc_directives(var pdflags:word);
  1642. {
  1643. Parse the procedure directives. It does not matter if procedure directives
  1644. are written using ;procdir; or ['procdir'] syntax.
  1645. }
  1646. var
  1647. res : boolean;
  1648. begin
  1649. while token in [_ID,_LECKKLAMMER] do
  1650. begin
  1651. if try_to_consume(_LECKKLAMMER) then
  1652. begin
  1653. repeat
  1654. parse_proc_direc(pdflags);
  1655. until not try_to_consume(_COMMA);
  1656. consume(_RECKKLAMMER);
  1657. { we always expect at least '[];' }
  1658. res:=true;
  1659. end
  1660. else
  1661. begin
  1662. res:=parse_proc_direc(pdflags);
  1663. end;
  1664. { A procedure directive normally followed by a semicolon, but in
  1665. a const section we should stop when _EQUAL is found }
  1666. if res then
  1667. begin
  1668. if (block_type=bt_const) and
  1669. (token=_EQUAL) then
  1670. break;
  1671. { support procedure proc;stdcall export; in Delphi mode only }
  1672. if not((m_delphi in aktmodeswitches) and
  1673. is_proc_directive(token)) then
  1674. consume(_SEMICOLON);
  1675. end
  1676. else
  1677. break;
  1678. end;
  1679. handle_calling_convention(aktprocsym,aktprocdef);
  1680. { calculate addresses in parasymtable }
  1681. if aktprocdef.deftype=procdef then
  1682. calc_parasymtable_addresses(aktprocdef);
  1683. end;
  1684. procedure parse_var_proc_directives(var sym : tsym);
  1685. var
  1686. pdflags : word;
  1687. oldsym : tprocsym;
  1688. olddef : tprocdef;
  1689. pd : tabstractprocdef;
  1690. begin
  1691. oldsym:=aktprocsym;
  1692. olddef:=aktprocdef;
  1693. pdflags:=pd_procvar;
  1694. { we create a temporary aktprocsym to read the directives }
  1695. aktprocsym:=tprocsym.create(sym.name);
  1696. case sym.typ of
  1697. varsym :
  1698. pd:=tabstractprocdef(tvarsym(sym).vartype.def);
  1699. typedconstsym :
  1700. pd:=tabstractprocdef(ttypedconstsym(sym).typedconsttype.def);
  1701. typesym :
  1702. pd:=tabstractprocdef(ttypesym(sym).restype.def);
  1703. else
  1704. internalerror(994932432);
  1705. end;
  1706. if pd.deftype<>procvardef then
  1707. internalerror(994932433);
  1708. tabstractprocdef(aktprocdef):=pd;
  1709. { names should never be used anyway }
  1710. inc(lexlevel);
  1711. parse_proc_directives(pdflags);
  1712. dec(lexlevel);
  1713. aktprocsym.free;
  1714. aktprocsym:=oldsym;
  1715. aktprocdef:=olddef;
  1716. end;
  1717. procedure parse_object_proc_directives(var sym : tprocsym);
  1718. var
  1719. pdflags : word;
  1720. begin
  1721. pdflags:=pd_object;
  1722. inc(lexlevel);
  1723. parse_proc_directives(pdflags);
  1724. dec(lexlevel);
  1725. if (po_containsself in aktprocdef.procoptions) and
  1726. (([po_msgstr,po_msgint]*aktprocdef.procoptions)=[]) then
  1727. Message(parser_e_self_in_non_message_handler);
  1728. end;
  1729. function proc_add_definition(aprocsym:tprocsym;var aprocdef : tprocdef) : boolean;
  1730. {
  1731. Add definition aprocdef to the overloaded definitions of aprocsym. If a
  1732. forwarddef is found and reused it returns true
  1733. }
  1734. var
  1735. hd : tprocdef;
  1736. ad,fd : tsym;
  1737. i : cardinal;
  1738. forwardfound : boolean;
  1739. po_comp : tprocoptions;
  1740. begin
  1741. forwardfound:=false;
  1742. { check overloaded functions if the same function already exists }
  1743. for i:=1 to aprocsym.procdef_count do
  1744. begin
  1745. hd:=aprocsym.procdef[i];
  1746. { Skip overloaded definitions that are declared in other
  1747. units }
  1748. if hd.procsym<>aprocsym then
  1749. continue;
  1750. { check the parameters, for delphi/tp it is possible to
  1751. leave the parameters away in the implementation (forwarddef=false).
  1752. But for an overload declared function this is not allowed }
  1753. if { check if empty implementation arguments match is allowed }
  1754. (
  1755. not(m_repeat_forward in aktmodeswitches) and
  1756. not(aprocdef.forwarddef) and
  1757. (aprocdef.maxparacount=0) and
  1758. not(po_overload in hd.procoptions)
  1759. ) or
  1760. { check arguments }
  1761. (
  1762. (compare_paras(aprocdef.para,hd.para,cp_none,false)>=te_equal) and
  1763. { for operators equal_paras is not enough !! }
  1764. ((aprocdef.proctypeoption<>potype_operator) or (optoken<>_ASSIGNMENT) or
  1765. equal_defs(hd.rettype.def,aprocdef.rettype.def))
  1766. ) then
  1767. begin
  1768. { Check if we've found the forwarddef, if found then
  1769. we need to update the forward def with the current
  1770. implementation settings }
  1771. if hd.forwarddef then
  1772. begin
  1773. forwardfound:=true;
  1774. { Check if the procedure type and return type are correct,
  1775. also the parameters must match also with the type }
  1776. if (hd.proctypeoption<>aprocdef.proctypeoption) or
  1777. (
  1778. (m_repeat_forward in aktmodeswitches) and
  1779. (not((aprocdef.maxparacount=0) or
  1780. (compare_paras(aprocdef.para,hd.para,cp_all,false)>=te_equal)))
  1781. ) or
  1782. (
  1783. ((m_repeat_forward in aktmodeswitches) or
  1784. not(is_void(aprocdef.rettype.def))) and
  1785. (not equal_defs(hd.rettype.def,aprocdef.rettype.def))) then
  1786. begin
  1787. MessagePos1(aprocdef.fileinfo,parser_e_header_dont_match_forward,
  1788. aprocdef.fullprocname);
  1789. aprocsym.write_parameter_lists(aprocdef);
  1790. break;
  1791. end;
  1792. { Check if both are declared forward }
  1793. if hd.forwarddef and aprocdef.forwarddef then
  1794. begin
  1795. MessagePos1(aprocdef.fileinfo,parser_e_function_already_declared_public_forward,
  1796. aprocdef.fullprocname);
  1797. end;
  1798. { internconst or internproc only need to be defined once }
  1799. if (hd.proccalloption=pocall_internproc) then
  1800. aprocdef.proccalloption:=hd.proccalloption
  1801. else
  1802. if (aprocdef.proccalloption=pocall_internproc) then
  1803. hd.proccalloption:=aprocdef.proccalloption;
  1804. if (po_internconst in hd.procoptions) then
  1805. include(aprocdef.procoptions,po_internconst)
  1806. else if (po_internconst in aprocdef.procoptions) then
  1807. include(hd.procoptions,po_internconst);
  1808. { Check calling convention }
  1809. if (hd.proccalloption<>aprocdef.proccalloption) then
  1810. begin
  1811. { In delphi it is possible to specify the calling
  1812. convention in the interface or implementation if
  1813. there was no convention specified in the other
  1814. part }
  1815. if (m_delphi in aktmodeswitches) then
  1816. begin
  1817. if (aprocdef.proccalloption=pocall_none) then
  1818. aprocdef.proccalloption:=hd.proccalloption
  1819. else
  1820. if (hd.proccalloption=pocall_none) then
  1821. hd.proccalloption:=aprocdef.proccalloption
  1822. else
  1823. begin
  1824. MessagePos(aprocdef.fileinfo,parser_e_call_convention_dont_match_forward);
  1825. aprocsym.write_parameter_lists(aprocdef);
  1826. { restore interface settings }
  1827. aprocdef.proccalloption:=hd.proccalloption;
  1828. end;
  1829. end
  1830. else
  1831. begin
  1832. MessagePos(aprocdef.fileinfo,parser_e_call_convention_dont_match_forward);
  1833. aprocsym.write_parameter_lists(aprocdef);
  1834. { restore interface settings }
  1835. aprocdef.proccalloption:=hd.proccalloption;
  1836. end;
  1837. end;
  1838. { Check procedure options, Delphi requires that class is
  1839. repeated in the implementation for class methods }
  1840. po_comp:=[];
  1841. if (m_fpc in aktmodeswitches) then
  1842. po_comp:=[po_varargs,po_methodpointer,po_containsself,po_interrupt]
  1843. else if (m_delphi in aktmodeswitches) then
  1844. po_comp:=[po_classmethod,po_methodpointer,po_containsself];
  1845. if ((po_comp * hd.procoptions)<>(po_comp * aprocdef.procoptions)) then
  1846. begin
  1847. MessagePos1(aprocdef.fileinfo,parser_e_header_dont_match_forward,
  1848. aprocdef.fullprocname);
  1849. aprocsym.write_parameter_lists(aprocdef);
  1850. { This error is non-fatal, we can recover }
  1851. end;
  1852. { Check manglednames }
  1853. if (m_repeat_forward in aktmodeswitches) or
  1854. aprocdef.haspara then
  1855. begin
  1856. { If mangled names are equal then they have the same amount of arguments }
  1857. { We can check the names of the arguments }
  1858. { both symtables are in the same order from left to right }
  1859. ad:=tsym(hd.parast.symindex.first);
  1860. fd:=tsym(aprocdef.parast.symindex.first);
  1861. repeat
  1862. { skip default parameter constsyms }
  1863. while assigned(ad) and (ad.typ<>varsym) do
  1864. ad:=tsym(ad.indexnext);
  1865. while assigned(fd) and (fd.typ<>varsym) do
  1866. fd:=tsym(fd.indexnext);
  1867. { stop when one of the two lists is at the end }
  1868. if not assigned(ad) or not assigned(fd) then
  1869. break;
  1870. if (ad.name<>fd.name) then
  1871. begin
  1872. MessagePos3(aprocdef.fileinfo,parser_e_header_different_var_names,
  1873. aprocsym.name,ad.name,fd.name);
  1874. break;
  1875. end;
  1876. ad:=tsym(ad.indexnext);
  1877. fd:=tsym(fd.indexnext);
  1878. until false;
  1879. if assigned(ad) xor assigned(fd) then
  1880. internalerror(200204178);
  1881. end;
  1882. { Everything is checked, now we can update the forward declaration
  1883. with the new data from the implementation }
  1884. hd.forwarddef:=aprocdef.forwarddef;
  1885. hd.hasforward:=true;
  1886. hd.parast.address_fixup:=aprocdef.parast.address_fixup;
  1887. hd.procoptions:=hd.procoptions+aprocdef.procoptions;
  1888. if hd.extnumber=65535 then
  1889. hd.extnumber:=aprocdef.extnumber;
  1890. while not aprocdef.aliasnames.empty do
  1891. hd.aliasnames.insert(aprocdef.aliasnames.getfirst);
  1892. { update mangledname if the implementation has a fixed mangledname set }
  1893. if aprocdef.has_mangledname then
  1894. begin
  1895. { rename also asmsymbol first, because the name can already be used }
  1896. objectlibrary.renameasmsymbol(hd.mangledname,aprocdef.mangledname);
  1897. hd.setmangledname(aprocdef.mangledname);
  1898. end;
  1899. { for compilerproc defines we need to rename and update the
  1900. symbolname to lowercase }
  1901. if (aprocdef.proccalloption=pocall_compilerproc) then
  1902. begin
  1903. { rename to lowercase so users can't access it }
  1904. aprocsym.owner.rename(aprocsym.name,lower(aprocsym.name));
  1905. { also update the realname that is stored in the ppu }
  1906. stringdispose(aprocsym._realname);
  1907. aprocsym._realname:=stringdup('$'+aprocsym.name);
  1908. { the mangeled name is already changed by the pd_compilerproc }
  1909. { handler. It must be done immediately because if we have a }
  1910. { call to a compilerproc before it's implementation is }
  1911. { encountered, it must already use the new mangled name (JM) }
  1912. end;
  1913. { return the forwarddef }
  1914. aprocdef:=hd;
  1915. end
  1916. else
  1917. begin
  1918. { abstract methods aren't forward defined, but this }
  1919. { needs another error message }
  1920. if (po_abstractmethod in hd.procoptions) then
  1921. MessagePos(aprocdef.fileinfo,parser_e_abstract_no_definition)
  1922. else
  1923. MessagePos(aprocdef.fileinfo,parser_e_overloaded_have_same_parameters);
  1924. end;
  1925. { we found one proc with the same arguments, there are no others
  1926. so we can stop }
  1927. break;
  1928. end;
  1929. { check for allowing overload directive }
  1930. if not(m_fpc in aktmodeswitches) then
  1931. begin
  1932. { overload directive turns on overloading }
  1933. if ((po_overload in aprocdef.procoptions) or
  1934. (po_overload in hd.procoptions)) then
  1935. begin
  1936. { check if all procs have overloading, but not if the proc was
  1937. already declared forward, then the check is already done }
  1938. if not(hd.hasforward or
  1939. (aprocdef.forwarddef<>hd.forwarddef) or
  1940. ((po_overload in aprocdef.procoptions) and
  1941. (po_overload in hd.procoptions))) then
  1942. begin
  1943. MessagePos1(aprocdef.fileinfo,parser_e_no_overload_for_all_procs,aprocsym.realname);
  1944. break;
  1945. end;
  1946. end
  1947. else
  1948. begin
  1949. if not(hd.forwarddef) then
  1950. begin
  1951. MessagePos(aprocdef.fileinfo,parser_e_procedure_overloading_is_off);
  1952. break;
  1953. end;
  1954. end;
  1955. end; { equal arguments }
  1956. end;
  1957. { if we didn't reuse a forwarddef then we add the procdef to the overloaded
  1958. list }
  1959. if not forwardfound then
  1960. begin
  1961. aprocsym.addprocdef(aprocdef);
  1962. { add overloadnumber for unique naming, the overloadcount is
  1963. counted per module and 0 for the first procedure }
  1964. aprocdef.overloadnumber:=aprocsym.overloadcount;
  1965. inc(aprocsym.overloadcount);
  1966. end;
  1967. { insert otsym only in the right symtable }
  1968. if ((procinfo.flags and pi_operator)<>0) and
  1969. assigned(otsym) then
  1970. begin
  1971. if not parse_only then
  1972. begin
  1973. if paramanager.ret_in_param(aprocdef.rettype.def,aprocdef.proccalloption) then
  1974. begin
  1975. aprocdef.parast.insert(otsym);
  1976. { this allows to read the funcretoffset }
  1977. otsym.address:=-4;
  1978. otsym.varspez:=vs_var;
  1979. end
  1980. else
  1981. begin
  1982. if not assigned(aprocdef.localst) then
  1983. aprocdef.insert_localst;
  1984. aprocdef.localst.insert(otsym);
  1985. aprocdef.localst.insertvardata(otsym);
  1986. end;
  1987. end
  1988. else
  1989. begin
  1990. { this is not required anymore }
  1991. otsym.free;
  1992. otsym:=nil;
  1993. end;
  1994. end;
  1995. paramanager.create_param_loc_info(aprocdef);
  1996. proc_add_definition:=forwardfound;
  1997. end;
  1998. end.
  1999. {
  2000. $Log$
  2001. Revision 1.113 2003-04-23 10:12:51 peter
  2002. * don't check po_varargs for delphi
  2003. Revision 1.112 2003/04/22 13:47:08 peter
  2004. * fixed C style array of const
  2005. * fixed C array passing
  2006. * fixed left to right with high parameters
  2007. Revision 1.111 2003/04/10 17:57:53 peter
  2008. * vs_hidden released
  2009. Revision 1.110 2003/03/28 19:16:56 peter
  2010. * generic constructor working for i386
  2011. * remove fixed self register
  2012. * esi added as address register for i386
  2013. Revision 1.109 2003/03/23 23:21:42 hajny
  2014. + emx target added
  2015. Revision 1.108 2003/03/19 17:34:04 peter
  2016. * only allow class [procedure|function]
  2017. Revision 1.107 2003/03/17 18:56:02 peter
  2018. * fix crash with duplicate id
  2019. Revision 1.106 2003/03/17 15:54:22 peter
  2020. * store symoptions also for procdef
  2021. * check symoptions (private,public) when calculating possible
  2022. overload candidates
  2023. Revision 1.105 2003/01/15 20:02:28 carl
  2024. * fix highname problem
  2025. Revision 1.104 2003/01/12 15:42:23 peter
  2026. * m68k pathexist update from 1.0.x
  2027. * palmos res update from 1.0.x
  2028. Revision 1.103 2003/01/07 19:16:38 peter
  2029. * removed some duplicate code when creating aktprocsym
  2030. Revision 1.102 2003/01/05 18:17:45 peter
  2031. * more conflicts for constructor/destructor types
  2032. Revision 1.100 2003/01/02 19:49:00 peter
  2033. * update self parameter only for methodpointer and methods
  2034. Revision 1.99 2003/01/01 22:51:03 peter
  2035. * high value insertion changed so it works also when 2 parameters
  2036. are passed
  2037. Revision 1.98 2003/01/01 14:35:33 peter
  2038. * don't check for export directive repeat
  2039. Revision 1.97 2002/12/29 18:16:06 peter
  2040. * delphi allows setting calling convention in interface or
  2041. implementation
  2042. Revision 1.96 2002/12/29 14:55:44 peter
  2043. * fix static method check
  2044. * don't require class for class methods in the implementation for
  2045. non delphi modes
  2046. Revision 1.95 2002/12/27 15:25:14 peter
  2047. * check procoptions when a forward is found
  2048. * exclude some call directives for constructor/destructor
  2049. Revision 1.94 2002/12/25 01:26:56 peter
  2050. * duplicate procsym-unitsym fix
  2051. Revision 1.93 2002/12/24 21:21:06 peter
  2052. * remove code that skipped the _ prefix for win32 imports
  2053. Revision 1.92 2002/12/23 21:24:22 peter
  2054. * fix wrong internalerror when var names were different
  2055. Revision 1.91 2002/12/23 20:58:52 peter
  2056. * cdecl array fix, hack to change it to vs_var is not needed
  2057. Revision 1.90 2002/12/17 22:19:33 peter
  2058. * fixed pushing of records>8 bytes with stdcall
  2059. * simplified hightree loading
  2060. Revision 1.89 2002/12/15 21:07:30 peter
  2061. * don't allow external in object declarations
  2062. Revision 1.88 2002/12/15 19:34:31 florian
  2063. + some front end stuff for vs_hidden added
  2064. Revision 1.87 2002/12/07 14:27:07 carl
  2065. * 3% memory optimization
  2066. * changed some types
  2067. + added type checking with different size for call node and for
  2068. parameters
  2069. Revision 1.86 2002/12/06 17:51:10 peter
  2070. * merged cdecl and array fixes
  2071. Revision 1.85 2002/12/01 22:06:14 carl
  2072. * cleanup of error messages
  2073. Revision 1.84 2002/11/29 22:31:19 carl
  2074. + unimplemented hint directive added
  2075. * hint directive parsing implemented
  2076. * warning on these directives
  2077. Revision 1.83 2002/11/27 02:35:28 peter
  2078. * fixed typo in method comparing
  2079. Revision 1.82 2002/11/25 17:43:21 peter
  2080. * splitted defbase in defutil,symutil,defcmp
  2081. * merged isconvertable and is_equal into compare_defs(_ext)
  2082. * made operator search faster by walking the list only once
  2083. Revision 1.81 2002/11/18 17:31:58 peter
  2084. * pass proccalloption to ret_in_xxx and push_xxx functions
  2085. Revision 1.80 2002/11/17 16:31:56 carl
  2086. * memory optimization (3-4%) : cleanup of tai fields,
  2087. cleanup of tdef and tsym fields.
  2088. * make it work for m68k
  2089. Revision 1.79 2002/11/16 14:20:50 peter
  2090. * fix infinite loop in pd_inline
  2091. Revision 1.78 2002/11/15 01:58:53 peter
  2092. * merged changes from 1.0.7 up to 04-11
  2093. - -V option for generating bug report tracing
  2094. - more tracing for option parsing
  2095. - errors for cdecl and high()
  2096. - win32 import stabs
  2097. - win32 records<=8 are returned in eax:edx (turned off by default)
  2098. - heaptrc update
  2099. - more info for temp management in .s file with EXTDEBUG
  2100. Revision 1.77 2002/10/06 15:09:12 peter
  2101. * variant:=nil supported
  2102. Revision 1.76 2002/09/27 21:13:29 carl
  2103. * low-highval always checked if limit ober 2GB is reached (to avoid overflow)
  2104. Revision 1.75 2002/09/16 14:11:13 peter
  2105. * add argument to equal_paras() to support default values or not
  2106. Revision 1.74 2002/09/10 16:27:28 peter
  2107. * don't insert parast in symtablestack, because typesyms should not be
  2108. searched in the the parast
  2109. Revision 1.73 2002/09/09 19:39:07 peter
  2110. * check return type for forwarddefs also not delphi mode when
  2111. the type is not void
  2112. Revision 1.72 2002/09/09 17:34:15 peter
  2113. * tdicationary.replace added to replace and item in a dictionary. This
  2114. is only allowed for the same name
  2115. * varsyms are inserted in symtable before the types are parsed. This
  2116. fixes the long standing "var longint : longint" bug
  2117. - consume_idlist and idstringlist removed. The loops are inserted
  2118. at the callers place and uses the symtable for duplicate id checking
  2119. Revision 1.71 2002/09/07 15:25:06 peter
  2120. * old logs removed and tabs fixed
  2121. Revision 1.70 2002/09/03 16:26:27 daniel
  2122. * Make Tprocdef.defs protected
  2123. Revision 1.69 2002/09/01 12:11:33 peter
  2124. * calc param_offset after parameters are read, because the calculation
  2125. depends on po_containself
  2126. Revision 1.68 2002/08/25 19:25:20 peter
  2127. * sym.insert_in_data removed
  2128. * symtable.insertvardata/insertconstdata added
  2129. * removed insert_in_data call from symtable.insert, it needs to be
  2130. called separatly. This allows to deref the address calculation
  2131. * procedures now calculate the parast addresses after the procedure
  2132. directives are parsed. This fixes the cdecl parast problem
  2133. * push_addr_param has an extra argument that specifies if cdecl is used
  2134. or not
  2135. Revision 1.67 2002/08/25 11:33:06 peter
  2136. * also check the paratypes when a forward was found
  2137. Revision 1.66 2002/08/19 19:36:44 peter
  2138. * More fixes for cross unit inlining, all tnodes are now implemented
  2139. * Moved pocall_internconst to po_internconst because it is not a
  2140. calling type at all and it conflicted when inlining of these small
  2141. functions was requested
  2142. Revision 1.65 2002/08/18 20:06:24 peter
  2143. * inlining is now also allowed in interface
  2144. * renamed write/load to ppuwrite/ppuload
  2145. * tnode storing in ppu
  2146. * nld,ncon,nbas are already updated for storing in ppu
  2147. Revision 1.64 2002/08/17 09:23:39 florian
  2148. * first part of procinfo rewrite
  2149. Revision 1.63 2002/08/11 14:32:27 peter
  2150. * renamed current_library to objectlibrary
  2151. Revision 1.62 2002/08/11 13:24:12 peter
  2152. * saving of asmsymbols in ppu supported
  2153. * asmsymbollist global is removed and moved into a new class
  2154. tasmlibrarydata that will hold the info of a .a file which
  2155. corresponds with a single module. Added librarydata to tmodule
  2156. to keep the library info stored for the module. In the future the
  2157. objectfiles will also be stored to the tasmlibrarydata class
  2158. * all getlabel/newasmsymbol and friends are moved to the new class
  2159. Revision 1.61 2002/07/26 21:15:40 florian
  2160. * rewrote the system handling
  2161. Revision 1.60 2002/07/20 11:57:55 florian
  2162. * types.pas renamed to defbase.pas because D6 contains a types
  2163. unit so this would conflicts if D6 programms are compiled
  2164. + Willamette/SSE2 instructions to assembler added
  2165. Revision 1.59 2002/07/11 14:41:28 florian
  2166. * start of the new generic parameter handling
  2167. Revision 1.58 2002/07/01 18:46:25 peter
  2168. * internal linker
  2169. * reorganized aasm layer
  2170. Revision 1.57 2002/05/18 13:34:12 peter
  2171. * readded missing revisions
  2172. Revision 1.56 2002/05/16 19:46:42 carl
  2173. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2174. + try to fix temp allocation (still in ifdef)
  2175. + generic constructor calls
  2176. + start of tassembler / tmodulebase class cleanup
  2177. Revision 1.54 2002/05/12 16:53:08 peter
  2178. * moved entry and exitcode to ncgutil and cgobj
  2179. * foreach gets extra argument for passing local data to the
  2180. iterator function
  2181. * -CR checks also class typecasts at runtime by changing them
  2182. into as
  2183. * fixed compiler to cycle with the -CR option
  2184. * fixed stabs with elf writer, finally the global variables can
  2185. be watched
  2186. * removed a lot of routines from cga unit and replaced them by
  2187. calls to cgobj
  2188. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2189. u32bit then the other is typecasted also to u32bit without giving
  2190. a rangecheck warning/error.
  2191. * fixed pascal calling method with reversing also the high tree in
  2192. the parast, detected by tcalcst3 test
  2193. Revision 1.53 2002/04/21 19:02:04 peter
  2194. * removed newn and disposen nodes, the code is now directly
  2195. inlined from pexpr
  2196. * -an option that will write the secondpass nodes to the .s file, this
  2197. requires EXTDEBUG define to actually write the info
  2198. * fixed various internal errors and crashes due recent code changes
  2199. Revision 1.52 2002/04/20 21:32:24 carl
  2200. + generic FPC_CHECKPOINTER
  2201. + first parameter offset in stack now portable
  2202. * rename some constants
  2203. + move some cpu stuff to other units
  2204. - remove unused constents
  2205. * fix stacksize for some targets
  2206. * fix generic size problems which depend now on EXTEND_SIZE constant
  2207. Revision 1.51 2002/04/20 15:27:05 carl
  2208. - remove ifdef i386 define
  2209. Revision 1.50 2002/04/19 15:46:02 peter
  2210. * mangledname rewrite, tprocdef.mangledname is now created dynamicly
  2211. in most cases and not written to the ppu
  2212. * add mangeledname_prefix() routine to generate the prefix of
  2213. manglednames depending on the current procedure, object and module
  2214. * removed static procprefix since the mangledname is now build only
  2215. on demand from tprocdef.mangledname
  2216. }