pdecsub.pas 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494
  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. type
  24. tpdflag=(
  25. pd_body, { directive needs a body }
  26. pd_implemen, { directive can be used implementation section }
  27. pd_interface, { directive can be used interface section }
  28. pd_object, { directive can be used object declaration }
  29. pd_procvar, { directive can be used procvar declaration }
  30. pd_notobject, { directive can not be used object declaration }
  31. pd_notobjintf, { directive can not be used interface declaration }
  32. pd_notprocvar { directive can not be used procvar declaration }
  33. );
  34. tpdflags=set of tpdflag;
  35. function check_proc_directive(isprocvar:boolean):boolean;
  36. procedure insert_funcret_local(pd:tprocdef);
  37. function proc_add_definition(var pd:tprocdef):boolean;
  38. procedure proc_set_mangledname(pd:tprocdef);
  39. procedure handle_calling_convention(pd:tabstractprocdef);
  40. procedure parse_parameter_dec(pd:tabstractprocdef);
  41. procedure parse_proc_directives(pd:tabstractprocdef;var pdflags:tpdflags);
  42. procedure parse_var_proc_directives(sym:tsym);
  43. procedure parse_object_proc_directives(pd:tabstractprocdef);
  44. function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean;
  45. function parse_proc_dec(aclass:tobjectdef):tprocdef;
  46. implementation
  47. uses
  48. strings,
  49. { common }
  50. cutils,cclasses,
  51. { global }
  52. globtype,globals,verbose,
  53. systems,
  54. cpuinfo,
  55. { symtable }
  56. symbase,symtable,defutil,defcmp,paramgr,cpupara,
  57. { pass 1 }
  58. node,htypechk,
  59. nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,
  60. { parser }
  61. scanner,
  62. pbase,pexpr,ptype,pdecl
  63. ;
  64. const
  65. { Please leave this here, this module should NOT use
  66. these variables.
  67. Declaring it as string here results in an error when compiling (PFV) }
  68. current_procinfo = 'error';
  69. procedure insert_funcret_para(pd:tabstractprocdef);
  70. var
  71. storepos : tfileposinfo;
  72. vs : tparavarsym;
  73. paranr : word;
  74. begin
  75. if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and
  76. not is_void(pd.rettype.def) and
  77. paramanager.ret_in_param(pd.rettype.def,pd.proccalloption) then
  78. begin
  79. storepos:=akttokenpos;
  80. if pd.deftype=procdef then
  81. akttokenpos:=tprocdef(pd).fileinfo;
  82. { For left to right add it at the end to be delphi compatible }
  83. if pd.proccalloption in pushleftright_pocalls then
  84. paranr:=paranr_result_leftright
  85. else
  86. paranr:=paranr_result;
  87. { Generate result variable accessing function result }
  88. vs:=tparavarsym.create('$result',paranr,vs_var,pd.rettype,[vo_is_funcret,vo_is_hidden_para]);
  89. pd.parast.insert(vs);
  90. { Store the this symbol as funcretsym for procedures }
  91. if pd.deftype=procdef then
  92. tprocdef(pd).funcretsym:=vs;
  93. akttokenpos:=storepos;
  94. end;
  95. end;
  96. procedure insert_parentfp_para(pd:tabstractprocdef);
  97. var
  98. storepos : tfileposinfo;
  99. vs : tparavarsym;
  100. begin
  101. if pd.parast.symtablelevel>normal_function_level then
  102. begin
  103. storepos:=akttokenpos;
  104. if pd.deftype=procdef then
  105. akttokenpos:=tprocdef(pd).fileinfo;
  106. { Generate result variable accessing function result, it
  107. can't be put in a register since it must be accessable
  108. from the framepointer }
  109. vs:=tparavarsym.create('$parentfp',paranr_parentfp,vs_var,voidpointertype,[vo_is_parentfp,vo_is_hidden_para]);
  110. vs.varregable:=vr_none;
  111. pd.parast.insert(vs);
  112. akttokenpos:=storepos;
  113. end;
  114. end;
  115. procedure insert_self_and_vmt_para(pd:tabstractprocdef);
  116. var
  117. storepos : tfileposinfo;
  118. vs : tparavarsym;
  119. tt : ttype;
  120. vsp : tvarspez;
  121. begin
  122. if (pd.deftype=procvardef) and
  123. pd.is_methodpointer then
  124. begin
  125. { Generate self variable }
  126. tt:=voidpointertype;
  127. vs:=tparavarsym.create('$self',paranr_self,vs_value,tt,[vo_is_self,vo_is_hidden_para]);
  128. pd.parast.insert(vs);
  129. end
  130. else
  131. begin
  132. if (pd.deftype=procdef) and
  133. assigned(tprocdef(pd)._class) and
  134. (pd.parast.symtablelevel=normal_function_level) then
  135. begin
  136. storepos:=akttokenpos;
  137. akttokenpos:=tprocdef(pd).fileinfo;
  138. { Generate VMT variable for constructor/destructor }
  139. if pd.proctypeoption in [potype_constructor,potype_destructor] then
  140. begin
  141. { can't use classrefdef as type because inheriting
  142. will then always file because of a type mismatch }
  143. tt:=voidpointertype;
  144. vs:=tparavarsym.create('$vmt',paranr_vmt,vs_value,tt,[vo_is_vmt,vo_is_hidden_para]);
  145. pd.parast.insert(vs);
  146. end;
  147. { Generate self variable, for classes we need
  148. to use the generic voidpointer to be compatible with
  149. methodpointers }
  150. vsp:=vs_value;
  151. if (po_staticmethod in pd.procoptions) or
  152. (po_classmethod in pd.procoptions) then
  153. begin
  154. tt.setdef(tprocdef(pd)._class);
  155. tt.setdef(tclassrefdef.create(tt));
  156. end
  157. else
  158. begin
  159. if is_object(tprocdef(pd)._class) then
  160. vsp:=vs_var;
  161. tt.setdef(tprocdef(pd)._class);
  162. end;
  163. vs:=tparavarsym.create('$self',paranr_self,vsp,tt,[vo_is_self,vo_is_hidden_para]);
  164. pd.parast.insert(vs);
  165. akttokenpos:=storepos;
  166. end;
  167. end;
  168. end;
  169. procedure insert_funcret_local(pd:tprocdef);
  170. var
  171. storepos : tfileposinfo;
  172. vs : tlocalvarsym;
  173. aliasvs : tabsolutevarsym;
  174. sl : tsymlist;
  175. begin
  176. { The result from constructors and destructors can't be accessed directly }
  177. if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and
  178. not is_void(pd.rettype.def) then
  179. begin
  180. storepos:=akttokenpos;
  181. akttokenpos:=pd.fileinfo;
  182. { We always need a localsymtable }
  183. if not assigned(pd.localst) then
  184. pd.insert_localst;
  185. { We need to insert a varsym for the result in the localst
  186. when it is returning in a register }
  187. if not paramanager.ret_in_param(pd.rettype.def,pd.proccalloption) then
  188. begin
  189. vs:=tlocalvarsym.create('$result',vs_value,pd.rettype,[vo_is_funcret]);
  190. pd.localst.insert(vs);
  191. pd.funcretsym:=vs;
  192. end;
  193. { insert the name of the procedure as alias for the function result,
  194. we can't use realname because that will not work for compilerprocs
  195. as the name is lowercase and unreachable from the code }
  196. if pd.resultname='' then
  197. pd.resultname:=pd.procsym.name;
  198. sl:=tsymlist.create;
  199. sl.addsym(sl_load,pd.funcretsym);
  200. aliasvs:=tabsolutevarsym.create_ref(pd.resultname,pd.rettype,sl);
  201. include(aliasvs.varoptions,vo_is_funcret);
  202. pd.localst.insert(aliasvs);
  203. { insert result also if support is on }
  204. if (m_result in aktmodeswitches) then
  205. begin
  206. sl:=tsymlist.create;
  207. sl.addsym(sl_load,pd.funcretsym);
  208. aliasvs:=tabsolutevarsym.create_ref('RESULT',pd.rettype,sl);
  209. include(aliasvs.varoptions,vo_is_funcret);
  210. include(aliasvs.varoptions,vo_is_result);
  211. pd.localst.insert(aliasvs);
  212. end;
  213. akttokenpos:=storepos;
  214. end;
  215. end;
  216. procedure insert_hidden_para(p:tnamedindexitem;arg:pointer);
  217. var
  218. hvs : tparavarsym;
  219. pd : tabstractprocdef absolute arg;
  220. begin
  221. if (tsym(p).typ<>paravarsym) then
  222. exit;
  223. with tparavarsym(p) do
  224. begin
  225. { We need a local copy for a value parameter when only the
  226. address is pushed. Open arrays and Array of Const are
  227. an exception because they are allocated at runtime and the
  228. address that is pushed is patched }
  229. if (varspez=vs_value) and
  230. paramanager.push_addr_param(varspez,vartype.def,pd.proccalloption) and
  231. not(is_open_array(vartype.def) or
  232. is_array_of_const(vartype.def)) then
  233. include(varoptions,vo_has_local_copy);
  234. { needs high parameter ? }
  235. if paramanager.push_high_param(varspez,vartype.def,pd.proccalloption) then
  236. begin
  237. hvs:=tparavarsym.create('$high'+name,paranr+1,vs_const,sinttype,[vo_is_high_para,vo_is_hidden_para]);
  238. owner.insert(hvs);
  239. end
  240. else
  241. begin
  242. { Give a warning that cdecl routines does not include high()
  243. support }
  244. if (pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
  245. paramanager.push_high_param(varspez,vartype.def,pocall_default) then
  246. begin
  247. if is_open_string(vartype.def) then
  248. Message(parser_w_cdecl_no_openstring);
  249. if not (po_external in pd.procoptions) then
  250. Message(parser_w_cdecl_has_no_high);
  251. end;
  252. end;
  253. end;
  254. end;
  255. procedure check_c_para(p:tnamedindexitem;arg:pointer);
  256. begin
  257. if (tsym(p).typ<>paravarsym) then
  258. exit;
  259. with tparavarsym(p) do
  260. begin
  261. case vartype.def.deftype of
  262. arraydef :
  263. begin
  264. if not is_variant_array(vartype.def) and
  265. not is_array_of_const(vartype.def) then
  266. begin
  267. if (varspez<>vs_var) then
  268. Message(parser_h_c_arrays_are_references);
  269. end;
  270. if is_array_of_const(vartype.def) and
  271. assigned(indexnext) and
  272. (tsym(indexnext).typ=paravarsym) and
  273. not(vo_is_high_para in tparavarsym(indexnext).varoptions) then
  274. Message(parser_e_C_array_of_const_must_be_last);
  275. end;
  276. end;
  277. end;
  278. end;
  279. procedure check_msg_para(p:tnamedindexitem;arg:pointer);
  280. begin
  281. if (tsym(p).typ<>paravarsym) then
  282. exit;
  283. with tparavarsym(p) do
  284. begin
  285. { Count parameters }
  286. if (paranr>=10) then
  287. inc(plongint(arg)^);
  288. { First parameter must be var }
  289. if (paranr=10) and
  290. (varspez<>vs_var) then
  291. Message(parser_e_ill_msg_param);
  292. end;
  293. end;
  294. procedure check_inline_para(p:tnamedindexitem;arg:pointer);
  295. var
  296. pd : tabstractprocdef absolute arg;
  297. begin
  298. if (pd.proccalloption<>pocall_inline) or
  299. (tsym(p).typ<>paravarsym) then
  300. exit;
  301. with tparavarsym(p) do
  302. begin
  303. case vartype.def.deftype of
  304. arraydef :
  305. begin
  306. with tarraydef(vartype.def) do
  307. if IsVariant or IsConstructor then
  308. begin
  309. Message1(parser_w_not_supported_for_inline,'array of const');
  310. Message(parser_w_inlining_disabled);
  311. pd.proccalloption:=pocall_default;
  312. end;
  313. end;
  314. end;
  315. end;
  316. end;
  317. procedure set_addr_param_regable(p:tnamedindexitem;arg:pointer);
  318. begin
  319. if (tsym(p).typ<>paravarsym) then
  320. exit;
  321. with tparavarsym(p) do
  322. begin
  323. if not vartype.def.needs_inittable and
  324. paramanager.push_addr_param(varspez,vartype.def,tprocdef(arg).proccalloption) then
  325. varregable:=vr_intreg;
  326. end;
  327. end;
  328. procedure parse_parameter_dec(pd:tabstractprocdef);
  329. {
  330. handle_procvar needs the same changes
  331. }
  332. var
  333. sc : tsinglelist;
  334. tt : ttype;
  335. arrayelementtype : ttype;
  336. vs : tparavarsym;
  337. srsym : tsym;
  338. hs1 : string;
  339. varspez : Tvarspez;
  340. defaultvalue : tconstsym;
  341. defaultrequired : boolean;
  342. old_object_option : tsymoptions;
  343. currparast : tparasymtable;
  344. explicit_paraloc : boolean;
  345. locationstr : string;
  346. paranr : integer;
  347. begin
  348. explicit_paraloc:=false;
  349. consume(_LKLAMMER);
  350. { Delphi/Kylix supports nonsense like }
  351. { procedure p(); }
  352. if try_to_consume(_RKLAMMER) and
  353. not(m_tp7 in aktmodeswitches) then
  354. exit;
  355. { parsing a proc or procvar ? }
  356. currparast:=tparasymtable(pd.parast);
  357. { reset }
  358. sc:=tsinglelist.create;
  359. defaultrequired:=false;
  360. paranr:=0;
  361. { the variables are always public }
  362. old_object_option:=current_object_option;
  363. current_object_option:=[sp_public];
  364. inc(testcurobject);
  365. repeat
  366. if try_to_consume(_VAR) then
  367. varspez:=vs_var
  368. else
  369. if try_to_consume(_CONST) then
  370. varspez:=vs_const
  371. else
  372. if (idtoken=_OUT) and (m_out in aktmodeswitches) then
  373. begin
  374. consume(_OUT);
  375. varspez:=vs_out
  376. end
  377. else
  378. if (token=_POINTPOINTPOINT) and (m_mac in aktmodeswitches) then
  379. begin
  380. consume(_POINTPOINTPOINT);
  381. include(pd.procoptions,po_varargs);
  382. break;
  383. end
  384. else
  385. varspez:=vs_value;
  386. defaultvalue:=nil;
  387. tt.reset;
  388. { read identifiers and insert with error type }
  389. sc.reset;
  390. repeat
  391. inc(paranr);
  392. vs:=tparavarsym.create(orgpattern,paranr*10,varspez,generrortype,[]);
  393. currparast.insert(vs);
  394. if assigned(vs.owner) then
  395. sc.insert(vs)
  396. else
  397. vs.free;
  398. consume(_ID);
  399. until not try_to_consume(_COMMA);
  400. locationstr:='';
  401. { read type declaration, force reading for value and const paras }
  402. if (token=_COLON) or (varspez=vs_value) then
  403. begin
  404. consume(_COLON);
  405. { check for an open array }
  406. if token=_ARRAY then
  407. begin
  408. consume(_ARRAY);
  409. consume(_OF);
  410. { define range and type of range }
  411. tt.setdef(tarraydef.create(0,-1,s32inttype));
  412. { array of const ? }
  413. if (token=_CONST) and (m_objpas in aktmodeswitches) then
  414. begin
  415. consume(_CONST);
  416. srsym:=searchsymonlyin(systemunit,'TVARREC');
  417. if not assigned(srsym) then
  418. InternalError(200404181);
  419. tarraydef(tt.def).setelementtype(ttypesym(srsym).restype);
  420. tarraydef(tt.def).IsArrayOfConst:=true;
  421. end
  422. else
  423. begin
  424. { define field type }
  425. single_type(arrayelementtype,hs1,false);
  426. tarraydef(tt.def).setelementtype(arrayelementtype);
  427. end;
  428. end
  429. else
  430. begin
  431. { open string ? }
  432. if (varspez=vs_var) and
  433. (
  434. (
  435. ((token=_STRING) or (idtoken=_SHORTSTRING)) and
  436. (cs_openstring in aktmoduleswitches) and
  437. not(cs_ansistrings in aktlocalswitches)
  438. ) or
  439. (idtoken=_OPENSTRING)) then
  440. begin
  441. consume(token);
  442. tt:=openshortstringtype;
  443. hs1:='openstring';
  444. end
  445. else
  446. begin
  447. { everything else }
  448. if (m_mac in aktmodeswitches) then
  449. try_to_consume(_UNIV); {currently does nothing}
  450. single_type(tt,hs1,false);
  451. end;
  452. if (target_info.system in [system_powerpc_morphos,system_m68k_amiga]) then
  453. begin
  454. if (idtoken=_LOCATION) then
  455. begin
  456. consume(_LOCATION);
  457. locationstr:=pattern;
  458. consume(_CSTRING);
  459. end
  460. else
  461. begin
  462. if explicit_paraloc then
  463. Message(parser_e_paraloc_all_paras);
  464. locationstr:='';
  465. end;
  466. end
  467. else
  468. locationstr:='';
  469. { default parameter }
  470. if (m_default_para in aktmodeswitches) then
  471. begin
  472. if try_to_consume(_EQUAL) then
  473. begin
  474. vs:=tparavarsym(sc.first);
  475. if assigned(vs.listnext) then
  476. Message(parser_e_default_value_only_one_para);
  477. { prefix 'def' to the parameter name }
  478. defaultvalue:=ReadConstant('$def'+vs.name,vs.fileinfo);
  479. if assigned(defaultvalue) then
  480. begin
  481. include(defaultvalue.symoptions,sp_internal);
  482. pd.parast.insert(defaultvalue);
  483. end;
  484. defaultrequired:=true;
  485. end
  486. else
  487. begin
  488. if defaultrequired then
  489. Message1(parser_e_default_value_expected_for_para,vs.name);
  490. end;
  491. end;
  492. end;
  493. end
  494. else
  495. begin
  496. {$ifndef UseNiceNames}
  497. hs1:='$$$';
  498. {$else UseNiceNames}
  499. hs1:='var';
  500. {$endif UseNiceNames}
  501. tt:=cformaltype;
  502. end;
  503. { File types are only allowed for var parameters }
  504. if (tt.def.deftype=filedef) and
  505. (varspez<>vs_var) then
  506. CGMessage(cg_e_file_must_call_by_reference);
  507. vs:=tparavarsym(sc.first);
  508. while assigned(vs) do
  509. begin
  510. { update varsym }
  511. vs.vartype:=tt;
  512. vs.defaultconstsym:=defaultvalue;
  513. if (target_info.system in [system_powerpc_morphos,system_m68k_amiga]) then
  514. begin
  515. if locationstr<>'' then
  516. begin
  517. if assigned(sc.first.listnext) then
  518. Message(parser_e_paraloc_only_one_para);
  519. if (paranr>1) and not(explicit_paraloc) then
  520. Message(parser_e_paraloc_all_paras);
  521. explicit_paraloc:=true;
  522. include(vs.varoptions,vo_has_explicit_paraloc);
  523. if not(paramanager.parseparaloc(vs,upper(locationstr))) then
  524. message(parser_e_illegal_explicit_paraloc);
  525. end
  526. else
  527. if explicit_paraloc then
  528. Message(parser_e_paraloc_all_paras);
  529. end;
  530. vs:=tparavarsym(vs.listnext);
  531. end;
  532. until not try_to_consume(_SEMICOLON);
  533. if explicit_paraloc then
  534. begin
  535. pd.has_paraloc_info:=true;
  536. include(pd.procoptions,po_explicitparaloc);
  537. end;
  538. { remove parasymtable from stack }
  539. sc.free;
  540. { reset object options }
  541. dec(testcurobject);
  542. current_object_option:=old_object_option;
  543. consume(_RKLAMMER);
  544. end;
  545. function parse_proc_head(aclass:tobjectdef;potype:tproctypeoption;var pd:tprocdef):boolean;
  546. var
  547. orgsp,sp : stringid;
  548. sym : tsym;
  549. srsym : tsym;
  550. srsymtable : tsymtable;
  551. storepos,
  552. procstartfilepos : tfileposinfo;
  553. searchagain : boolean;
  554. i : longint;
  555. st : tsymtable;
  556. aprocsym : tprocsym;
  557. begin
  558. { Save the position where this procedure really starts }
  559. procstartfilepos:=akttokenpos;
  560. result:=false;
  561. pd:=nil;
  562. aprocsym:=nil;
  563. if (potype=potype_operator) then
  564. begin
  565. sp:=overloaded_names[optoken];
  566. orgsp:=sp;
  567. end
  568. else
  569. begin
  570. sp:=pattern;
  571. orgsp:=orgpattern;
  572. consume(_ID);
  573. end;
  574. { examine interface map: function/procedure iname.functionname=locfuncname }
  575. if assigned(aclass) and
  576. assigned(aclass.implementedinterfaces) and
  577. (aclass.implementedinterfaces.count>0) and
  578. try_to_consume(_POINT) then
  579. begin
  580. storepos:=akttokenpos;
  581. akttokenpos:=procstartfilepos;
  582. { get interface syms}
  583. searchsym(sp,sym,srsymtable);
  584. if not assigned(sym) then
  585. begin
  586. identifier_not_found(orgsp);
  587. sym:=generrorsym;
  588. end;
  589. akttokenpos:=storepos;
  590. { qualifier is interface? }
  591. if (sym.typ=typesym) and
  592. (ttypesym(sym).restype.def.deftype=objectdef) then
  593. i:=aclass.implementedinterfaces.searchintf(ttypesym(sym).restype.def)
  594. else
  595. i:=-1;
  596. if (i=-1) then
  597. Message(parser_e_interface_id_expected);
  598. consume(_ID);
  599. consume(_EQUAL);
  600. if (token=_ID) then
  601. aclass.implementedinterfaces.addmappings(i,sp,pattern);
  602. consume(_ID);
  603. result:=true;
  604. exit;
  605. end;
  606. { method ? }
  607. if not assigned(aclass) and
  608. (potype<>potype_operator) and
  609. (symtablestack.symtablelevel=main_program_level) and
  610. try_to_consume(_POINT) then
  611. begin
  612. { search for object name }
  613. storepos:=akttokenpos;
  614. akttokenpos:=procstartfilepos;
  615. searchsym(sp,sym,srsymtable);
  616. if not assigned(sym) then
  617. begin
  618. identifier_not_found(orgsp);
  619. sym:=generrorsym;
  620. end;
  621. akttokenpos:=storepos;
  622. { consume proc name }
  623. sp:=pattern;
  624. orgsp:=orgpattern;
  625. procstartfilepos:=akttokenpos;
  626. consume(_ID);
  627. { qualifier is class name ? }
  628. if (sym.typ=typesym) and
  629. (ttypesym(sym).restype.def.deftype=objectdef) then
  630. begin
  631. aclass:=tobjectdef(ttypesym(sym).restype.def);
  632. aprocsym:=tprocsym(aclass.symtable.search(sp));
  633. { we solve this below }
  634. if assigned(aprocsym) then
  635. begin
  636. if aprocsym.typ<>procsym then
  637. begin
  638. { we use a different error message for tp7 so it looks more compatible }
  639. if (m_fpc in aktmodeswitches) then
  640. Message1(parser_e_overloaded_no_procedure,aprocsym.realname)
  641. else
  642. Message(parser_e_methode_id_expected);
  643. { rename the name to an unique name to avoid an
  644. error when inserting the symbol in the symtable }
  645. orgsp:=orgsp+'$'+tostr(aktfilepos.line);
  646. aprocsym:=nil;
  647. end;
  648. end
  649. else
  650. begin
  651. Message(parser_e_methode_id_expected);
  652. { recover by making it a normal procedure instead of method }
  653. aclass:=nil;
  654. end;
  655. end
  656. else
  657. Message(parser_e_class_id_expected);
  658. end
  659. else
  660. begin
  661. { check for constructor/destructor which is not allowed here }
  662. if (not parse_only) and
  663. (potype in [potype_constructor,potype_destructor]) then
  664. Message(parser_e_constructors_always_objects);
  665. repeat
  666. searchagain:=false;
  667. akttokenpos:=procstartfilepos;
  668. srsym:=tsym(symtablestack.search(sp));
  669. if not(parse_only) and
  670. not assigned(srsym) and
  671. (symtablestack.symtabletype=staticsymtable) and
  672. assigned(symtablestack.next) and
  673. (symtablestack.next.unitid=0) then
  674. begin
  675. { The procedure we prepare for is in the implementation
  676. part of the unit we compile. It is also possible that we
  677. are compiling a program, which is also some kind of
  678. implementaion part.
  679. We need to find out if the procedure is global. If it is
  680. global, it is in the global symtable.}
  681. srsym:=tsym(symtablestack.next.search(sp));
  682. end;
  683. { Check if overloaded is a procsym }
  684. if assigned(srsym) then
  685. begin
  686. if srsym.typ=procsym then
  687. aprocsym:=tprocsym(srsym)
  688. else
  689. begin
  690. { when the other symbol is a unit symbol then hide the unit
  691. symbol }
  692. if (srsym.typ=unitsym) then
  693. begin
  694. srsym.owner.rename(srsym.name,'hidden'+srsym.name);
  695. searchagain:=true;
  696. end
  697. else
  698. begin
  699. { we use a different error message for tp7 so it looks more compatible }
  700. if (m_fpc in aktmodeswitches) then
  701. Message1(parser_e_overloaded_no_procedure,srsym.realname)
  702. else
  703. tstoredsymtable(symtablestack).DuplicateSym(nil,srsym);
  704. { rename the name to an unique name to avoid an
  705. error when inserting the symbol in the symtable }
  706. orgsp:=orgsp+'$'+tostr(aktfilepos.line);
  707. end;
  708. end;
  709. end;
  710. until not searchagain;
  711. end;
  712. { test again if assigned, it can be reset to recover }
  713. if not assigned(aprocsym) then
  714. begin
  715. { create a new procsym and set the real filepos }
  716. akttokenpos:=procstartfilepos;
  717. { for operator we have only one procsym for each overloaded
  718. operation }
  719. if (potype=potype_operator) then
  720. begin
  721. Aprocsym:=Tprocsym(symtablestack.search(sp));
  722. if Aprocsym=nil then
  723. Aprocsym:=tprocsym.create('$'+sp);
  724. end
  725. else
  726. aprocsym:=tprocsym.create(orgsp);
  727. symtablestack.insert(aprocsym);
  728. end;
  729. { to get the correct symtablelevel we must ignore objectsymtables }
  730. st:=symtablestack;
  731. while not(st.symtabletype in [staticsymtable,globalsymtable,localsymtable]) do
  732. st:=st.next;
  733. pd:=tprocdef.create(st.symtablelevel+1);
  734. pd._class:=aclass;
  735. pd.procsym:=aprocsym;
  736. pd.proctypeoption:=potype;
  737. { methods need to be exported }
  738. if assigned(aclass) and
  739. (
  740. (symtablestack.symtabletype=objectsymtable) or
  741. (symtablestack.symtablelevel=main_program_level)
  742. ) then
  743. include(pd.procoptions,po_global);
  744. { symbol options that need to be kept per procdef }
  745. pd.fileinfo:=procstartfilepos;
  746. pd.symoptions:=current_object_option;
  747. { parse parameters }
  748. if token=_LKLAMMER then
  749. parse_parameter_dec(pd);
  750. result:=true;
  751. end;
  752. function parse_proc_dec(aclass:tobjectdef):tprocdef;
  753. var
  754. pd : tprocdef;
  755. hs : string;
  756. isclassmethod : boolean;
  757. begin
  758. pd:=nil;
  759. { read class method }
  760. if try_to_consume(_CLASS) then
  761. begin
  762. { class method only allowed for procedures and functions }
  763. if not(token in [_FUNCTION,_PROCEDURE]) then
  764. Message(parser_e_procedure_or_function_expected);
  765. isclassmethod:=true;
  766. end
  767. else
  768. isclassmethod:=false;
  769. case token of
  770. _FUNCTION :
  771. begin
  772. consume(_FUNCTION);
  773. if parse_proc_head(aclass,potype_none,pd) then
  774. begin
  775. { pd=nil when it is a interface mapping }
  776. if assigned(pd) then
  777. begin
  778. if try_to_consume(_COLON) then
  779. begin
  780. inc(testcurobject);
  781. single_type(pd.rettype,hs,false);
  782. pd.test_if_fpu_result;
  783. dec(testcurobject);
  784. end
  785. else
  786. begin
  787. if (
  788. parse_only and
  789. not(is_interface(pd._class))
  790. ) or
  791. (m_repeat_forward in aktmodeswitches) then
  792. begin
  793. consume(_COLON);
  794. consume_all_until(_SEMICOLON);
  795. end;
  796. end;
  797. if isclassmethod then
  798. include(pd.procoptions,po_classmethod);
  799. end;
  800. end
  801. else
  802. begin
  803. { recover }
  804. consume(_COLON);
  805. consume_all_until(_SEMICOLON);
  806. end;
  807. end;
  808. _PROCEDURE :
  809. begin
  810. consume(_PROCEDURE);
  811. if parse_proc_head(aclass,potype_none,pd) then
  812. begin
  813. { pd=nil when it is a interface mapping }
  814. if assigned(pd) then
  815. begin
  816. pd.rettype:=voidtype;
  817. if isclassmethod then
  818. include(pd.procoptions,po_classmethod);
  819. end;
  820. end;
  821. end;
  822. _CONSTRUCTOR :
  823. begin
  824. consume(_CONSTRUCTOR);
  825. parse_proc_head(aclass,potype_constructor,pd);
  826. if assigned(pd) and
  827. assigned(pd._class) then
  828. begin
  829. { Set return type, class constructors return the
  830. created instance, object constructors return boolean }
  831. if is_class(pd._class) then
  832. pd.rettype.setdef(pd._class)
  833. else
  834. pd.rettype:=booltype;
  835. end;
  836. end;
  837. _DESTRUCTOR :
  838. begin
  839. consume(_DESTRUCTOR);
  840. parse_proc_head(aclass,potype_destructor,pd);
  841. if assigned(pd) then
  842. pd.rettype:=voidtype;
  843. end;
  844. _OPERATOR :
  845. begin
  846. consume(_OPERATOR);
  847. if (token in [first_overloaded..last_overloaded]) then
  848. begin
  849. optoken:=token;
  850. end
  851. else
  852. begin
  853. Message(parser_e_overload_operator_failed);
  854. { Use the dummy NOTOKEN that is also declared
  855. for the overloaded_operator[] }
  856. optoken:=NOTOKEN;
  857. end;
  858. consume(token);
  859. parse_proc_head(aclass,potype_operator,pd);
  860. if assigned(pd) then
  861. begin
  862. if pd.parast.symtablelevel>normal_function_level then
  863. Message(parser_e_no_local_operator);
  864. if token<>_ID then
  865. begin
  866. if not(m_result in aktmodeswitches) then
  867. consume(_ID);
  868. end
  869. else
  870. begin
  871. pd.resultname:=orgpattern;
  872. consume(_ID);
  873. end;
  874. if not try_to_consume(_COLON) then
  875. begin
  876. consume(_COLON);
  877. pd.rettype:=generrortype;
  878. consume_all_until(_SEMICOLON);
  879. end
  880. else
  881. begin
  882. single_type(pd.rettype,hs,false);
  883. pd.test_if_fpu_result;
  884. if (optoken in [_EQUAL,_GT,_LT,_GTE,_LTE]) and
  885. ((pd.rettype.def.deftype<>orddef) or
  886. (torddef(pd.rettype.def).typ<>bool8bit)) then
  887. Message(parser_e_comparative_operator_return_boolean);
  888. if (optoken=_ASSIGNMENT) and
  889. equal_defs(pd.rettype.def,
  890. tparavarsym(pd.parast.symindex.first).vartype.def) then
  891. message(parser_e_no_such_assignment)
  892. else if not isoperatoracceptable(pd,optoken) then
  893. Message(parser_e_overload_impossible);
  894. end;
  895. end
  896. else
  897. begin
  898. { recover }
  899. try_to_consume(_ID);
  900. consume(_COLON);
  901. consume_all_until(_SEMICOLON);
  902. end;
  903. end;
  904. end;
  905. { support procedure proc stdcall export; }
  906. if not(check_proc_directive(false)) then
  907. consume(_SEMICOLON);
  908. result:=pd;
  909. end;
  910. {****************************************************************************
  911. Procedure directive handlers
  912. ****************************************************************************}
  913. procedure pd_far(pd:tabstractprocdef);
  914. begin
  915. Message1(parser_w_proc_directive_ignored,'FAR');
  916. end;
  917. procedure pd_near(pd:tabstractprocdef);
  918. begin
  919. Message1(parser_w_proc_directive_ignored,'NEAR');
  920. end;
  921. procedure pd_export(pd:tabstractprocdef);
  922. begin
  923. if pd.deftype<>procdef then
  924. internalerror(200304264);
  925. if assigned(tprocdef(pd)._class) then
  926. Message(parser_e_methods_dont_be_export);
  927. if pd.parast.symtablelevel>normal_function_level then
  928. Message(parser_e_dont_nest_export);
  929. end;
  930. procedure pd_forward(pd:tabstractprocdef);
  931. begin
  932. if pd.deftype<>procdef then
  933. internalerror(200304265);
  934. tprocdef(pd).forwarddef:=true;
  935. end;
  936. procedure pd_alias(pd:tabstractprocdef);
  937. begin
  938. if pd.deftype<>procdef then
  939. internalerror(200304266);
  940. consume(_COLON);
  941. tprocdef(pd).aliasnames.insert(get_stringconst);
  942. include(pd.procoptions,po_has_public_name);
  943. end;
  944. procedure pd_public(pd:tabstractprocdef);
  945. begin
  946. if pd.deftype<>procdef then
  947. internalerror(200304266);
  948. if try_to_consume(_NAME) then
  949. begin
  950. tprocdef(pd).aliasnames.insert(get_stringconst);
  951. include(pd.procoptions,po_has_public_name);
  952. end;
  953. end;
  954. procedure pd_asmname(pd:tabstractprocdef);
  955. begin
  956. if pd.deftype<>procdef then
  957. internalerror(200304267);
  958. tprocdef(pd).aliasnames.insert(target_info.Cprefix+pattern);
  959. if token=_CCHAR then
  960. consume(_CCHAR)
  961. else
  962. consume(_CSTRING);
  963. { we don't need anything else }
  964. tprocdef(pd).forwarddef:=false;
  965. end;
  966. procedure pd_inline(pd:tabstractprocdef);
  967. begin
  968. { Check if there are parameters that can't be inlined }
  969. pd.parast.foreach_static(@check_inline_para,pd);
  970. end;
  971. procedure pd_internconst(pd:tabstractprocdef);
  972. begin
  973. if pd.deftype<>procdef then
  974. internalerror(200304268);
  975. consume(_COLON);
  976. tprocdef(pd).extnumber:=get_intconst;
  977. end;
  978. procedure pd_internproc(pd:tabstractprocdef);
  979. begin
  980. if pd.deftype<>procdef then
  981. internalerror(200304268);
  982. consume(_COLON);
  983. tprocdef(pd).extnumber:=get_intconst;
  984. { the proc is defined }
  985. tprocdef(pd).forwarddef:=false;
  986. end;
  987. procedure pd_interrupt(pd:tabstractprocdef);
  988. begin
  989. if pd.parast.symtablelevel>normal_function_level then
  990. Message(parser_e_dont_nest_interrupt);
  991. end;
  992. procedure pd_abstract(pd:tabstractprocdef);
  993. begin
  994. if pd.deftype<>procdef then
  995. internalerror(200304269);
  996. if (po_virtualmethod in pd.procoptions) then
  997. include(pd.procoptions,po_abstractmethod)
  998. else
  999. Message(parser_e_only_virtual_methods_abstract);
  1000. { the method is defined }
  1001. tprocdef(pd).forwarddef:=false;
  1002. end;
  1003. procedure pd_virtual(pd:tabstractprocdef);
  1004. {$ifdef WITHDMT}
  1005. var
  1006. pt : tnode;
  1007. {$endif WITHDMT}
  1008. begin
  1009. if pd.deftype<>procdef then
  1010. internalerror(2003042610);
  1011. if (pd.proctypeoption=potype_constructor) and
  1012. is_object(tprocdef(pd)._class) then
  1013. Message(parser_e_constructor_cannot_be_not_virtual);
  1014. {$ifdef WITHDMT}
  1015. if is_object(tprocdef(pd)._class) and
  1016. (token<>_SEMICOLON) then
  1017. begin
  1018. { any type of parameter is allowed here! }
  1019. pt:=comp_expr(true);
  1020. if is_constintnode(pt) then
  1021. begin
  1022. include(pd.procoptions,po_msgint);
  1023. pd.messageinf.i:=pt^.value;
  1024. end
  1025. else
  1026. Message(parser_e_ill_msg_expr);
  1027. disposetree(pt);
  1028. end;
  1029. {$endif WITHDMT}
  1030. end;
  1031. procedure pd_static(pd:tabstractprocdef);
  1032. begin
  1033. if (cs_static_keyword in aktmoduleswitches) then
  1034. begin
  1035. if pd.deftype=procdef then
  1036. include(tprocdef(pd).procsym.symoptions,sp_static);
  1037. include(pd.procoptions,po_staticmethod);
  1038. end;
  1039. end;
  1040. procedure pd_override(pd:tabstractprocdef);
  1041. begin
  1042. if pd.deftype<>procdef then
  1043. internalerror(2003042611);
  1044. if not(is_class_or_interface(tprocdef(pd)._class)) then
  1045. Message(parser_e_no_object_override);
  1046. end;
  1047. procedure pd_overload(pd:tabstractprocdef);
  1048. begin
  1049. if pd.deftype<>procdef then
  1050. internalerror(2003042612);
  1051. include(tprocdef(pd).procsym.symoptions,sp_has_overloaded);
  1052. end;
  1053. procedure pd_message(pd:tabstractprocdef);
  1054. var
  1055. pt : tnode;
  1056. paracnt : longint;
  1057. begin
  1058. if pd.deftype<>procdef then
  1059. internalerror(2003042613);
  1060. if not is_class(tprocdef(pd)._class) then
  1061. Message(parser_e_msg_only_for_classes);
  1062. { check parameter type }
  1063. paracnt:=0;
  1064. pd.parast.foreach_static(@check_msg_para,@paracnt);
  1065. if paracnt<>1 then
  1066. Message(parser_e_ill_msg_param);
  1067. pt:=comp_expr(true);
  1068. if pt.nodetype=stringconstn then
  1069. begin
  1070. include(pd.procoptions,po_msgstr);
  1071. tprocdef(pd).messageinf.str:=strnew(tstringconstnode(pt).value_str);
  1072. end
  1073. else
  1074. if is_constintnode(pt) then
  1075. begin
  1076. include(pd.procoptions,po_msgint);
  1077. tprocdef(pd).messageinf.i:=tordconstnode(pt).value;
  1078. end
  1079. else
  1080. Message(parser_e_ill_msg_expr);
  1081. pt.free;
  1082. end;
  1083. procedure pd_reintroduce(pd:tabstractprocdef);
  1084. begin
  1085. if pd.deftype<>procdef then
  1086. internalerror(200401211);
  1087. if not(is_class_or_interface(tprocdef(pd)._class)) then
  1088. Message(parser_e_no_object_reintroduce);
  1089. end;
  1090. procedure pd_syscall(pd:tabstractprocdef);
  1091. {$ifdef powerpc}
  1092. var
  1093. vs : tparavarsym;
  1094. sym : tsym;
  1095. symtable : tsymtable;
  1096. {$endif powerpc}
  1097. begin
  1098. if pd.deftype<>procdef then
  1099. internalerror(2003042614);
  1100. tprocdef(pd).forwarddef:=false;
  1101. {$ifdef powerpc}
  1102. if target_info.system in [system_powerpc_morphos,system_m68k_amiga] then
  1103. begin
  1104. pd.has_paraloc_info:=true;
  1105. include(pd.procoptions,po_explicitparaloc);
  1106. if consume_sym(sym,symtable) then
  1107. begin
  1108. if (sym.typ=globalvarsym) and
  1109. (
  1110. (tabstractvarsym(sym).vartype.def.deftype=pointerdef) or
  1111. is_32bitint(tabstractvarsym(sym).vartype.def)
  1112. ) then
  1113. begin
  1114. tprocdef(pd).libsym:=sym;
  1115. vs:=tparavarsym.create('$syscalllib',paranr_syscall,vs_value,tabstractvarsym(sym).vartype,[vo_is_syscall_lib,vo_is_hidden_para,vo_has_explicit_paraloc]);
  1116. paramanager.parseparaloc(vs,'A6');
  1117. pd.parast.insert(vs);
  1118. end
  1119. else
  1120. Message(parser_e_32bitint_or_pointer_variable_expected);
  1121. end;
  1122. (paramanager as tppcparamanager).create_funcretloc_info(pd,calleeside);
  1123. (paramanager as tppcparamanager).create_funcretloc_info(pd,callerside);
  1124. end;
  1125. {$endif powerpc}
  1126. tprocdef(pd).extnumber:=get_intconst;
  1127. end;
  1128. procedure pd_external(pd:tabstractprocdef);
  1129. {
  1130. If import_dll=nil the procedure is assumed to be in another
  1131. object file. In that object file it should have the name to
  1132. which import_name is pointing to. Otherwise, the procedure is
  1133. assumed to be in the DLL to which import_dll is pointing to. In
  1134. that case either import_nr<>0 or import_name<>nil is true, so
  1135. the procedure is either imported by number or by name. (DM)
  1136. }
  1137. begin
  1138. if pd.deftype<>procdef then
  1139. internalerror(2003042615);
  1140. with tprocdef(pd) do
  1141. begin
  1142. forwarddef:=false;
  1143. { forbid local external procedures }
  1144. if parast.symtablelevel>normal_function_level then
  1145. Message(parser_e_no_local_proc_external);
  1146. { If the procedure should be imported from a DLL, a constant string follows.
  1147. This isn't really correct, an contant string expression follows
  1148. so we check if an semicolon follows, else a string constant have to
  1149. follow (FK) }
  1150. if not(token=_SEMICOLON) and not(idtoken=_NAME) then
  1151. begin
  1152. import_dll:=stringdup(get_stringconst);
  1153. if (idtoken=_NAME) then
  1154. begin
  1155. consume(_NAME);
  1156. import_name:=stringdup(get_stringconst);
  1157. if import_name^='' then
  1158. message(parser_e_empty_import_name);
  1159. end;
  1160. if (idtoken=_INDEX) then
  1161. begin
  1162. {After the word index follows the index number in the DLL.}
  1163. consume(_INDEX);
  1164. import_nr:=get_intconst;
  1165. end;
  1166. { default is to used the realname of the procedure }
  1167. if (import_nr=0) and not assigned(import_name) then
  1168. import_name:=stringdup(procsym.realname);
  1169. end
  1170. else
  1171. begin
  1172. if (idtoken=_NAME) then
  1173. begin
  1174. consume(_NAME);
  1175. import_name:=stringdup(get_stringconst);
  1176. if import_name^='' then
  1177. message(parser_e_empty_import_name);
  1178. end;
  1179. end;
  1180. end;
  1181. end;
  1182. type
  1183. pd_handler=procedure(pd:tabstractprocdef);
  1184. proc_dir_rec=record
  1185. idtok : ttoken;
  1186. pd_flags : tpdflags;
  1187. handler : pd_handler;
  1188. pocall : tproccalloption;
  1189. pooption : tprocoptions;
  1190. mutexclpocall : tproccalloptions;
  1191. mutexclpotype : tproctypeoptions;
  1192. mutexclpo : tprocoptions;
  1193. end;
  1194. const
  1195. {Should contain the number of procedure directives we support.}
  1196. num_proc_directives=36;
  1197. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  1198. (
  1199. (
  1200. idtok:_ABSTRACT;
  1201. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1202. handler : @pd_abstract;
  1203. pocall : pocall_none;
  1204. pooption : [po_abstractmethod];
  1205. mutexclpocall : [pocall_internproc,pocall_inline];
  1206. mutexclpotype : [];
  1207. mutexclpo : [po_exports,po_interrupt,po_external]
  1208. ),(
  1209. idtok:_ALIAS;
  1210. pd_flags : [pd_implemen,pd_body,pd_notobjintf];
  1211. handler : @pd_alias;
  1212. pocall : pocall_none;
  1213. pooption : [];
  1214. mutexclpocall : [pocall_inline];
  1215. mutexclpotype : [];
  1216. mutexclpo : [po_external]
  1217. ),(
  1218. idtok:_ASMNAME;
  1219. pd_flags : [pd_interface,pd_implemen,pd_notobjintf];
  1220. handler : @pd_asmname;
  1221. pocall : pocall_cdecl;
  1222. pooption : [po_external];
  1223. mutexclpocall : [pocall_internproc,pocall_inline];
  1224. mutexclpotype : [];
  1225. mutexclpo : [po_external]
  1226. ),(
  1227. idtok:_ASSEMBLER;
  1228. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  1229. handler : nil;
  1230. pocall : pocall_none;
  1231. pooption : [po_assembler];
  1232. mutexclpocall : [];
  1233. mutexclpotype : [];
  1234. mutexclpo : [po_external]
  1235. ),(
  1236. idtok:_C; {same as cdecl for mode mac}
  1237. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1238. handler : nil;
  1239. pocall : pocall_cdecl;
  1240. pooption : [];
  1241. mutexclpocall : [];
  1242. mutexclpotype : [potype_constructor,potype_destructor];
  1243. mutexclpo : [po_assembler,po_external]
  1244. ),(
  1245. idtok:_CDECL;
  1246. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1247. handler : nil;
  1248. pocall : pocall_cdecl;
  1249. pooption : [];
  1250. mutexclpocall : [];
  1251. mutexclpotype : [potype_constructor,potype_destructor];
  1252. mutexclpo : [po_assembler,po_external]
  1253. ),(
  1254. idtok:_DYNAMIC;
  1255. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1256. handler : @pd_virtual;
  1257. pocall : pocall_none;
  1258. pooption : [po_virtualmethod];
  1259. mutexclpocall : [pocall_internproc,pocall_inline];
  1260. mutexclpotype : [];
  1261. mutexclpo : [po_exports,po_interrupt,po_external,po_overridingmethod]
  1262. ),(
  1263. idtok:_EXPORT;
  1264. pd_flags : [pd_body,pd_interface,pd_implemen,pd_notobjintf];
  1265. handler : @pd_export;
  1266. pocall : pocall_none;
  1267. pooption : [po_exports,po_global];
  1268. mutexclpocall : [pocall_internproc,pocall_inline];
  1269. mutexclpotype : [potype_constructor,potype_destructor];
  1270. mutexclpo : [po_external,po_interrupt]
  1271. ),(
  1272. idtok:_EXTERNAL;
  1273. pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf];
  1274. handler : @pd_external;
  1275. pocall : pocall_none;
  1276. pooption : [po_external];
  1277. mutexclpocall : [pocall_internproc,pocall_inline,pocall_syscall];
  1278. mutexclpotype : [potype_constructor,potype_destructor];
  1279. mutexclpo : [po_exports,po_interrupt,po_assembler]
  1280. ),(
  1281. idtok:_FAR;
  1282. pd_flags : [pd_implemen,pd_body,pd_interface,pd_procvar,pd_notobject,pd_notobjintf];
  1283. handler : @pd_far;
  1284. pocall : pocall_none;
  1285. pooption : [];
  1286. mutexclpocall : [pocall_internproc,pocall_inline];
  1287. mutexclpotype : [];
  1288. mutexclpo : []
  1289. ),(
  1290. idtok:_FAR16;
  1291. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar,pd_notobject];
  1292. handler : nil;
  1293. pocall : pocall_far16;
  1294. pooption : [];
  1295. mutexclpocall : [];
  1296. mutexclpotype : [];
  1297. mutexclpo : [po_external]
  1298. ),(
  1299. idtok:_FORWARD;
  1300. pd_flags : [pd_implemen,pd_notobject,pd_notobjintf];
  1301. handler : @pd_forward;
  1302. pocall : pocall_none;
  1303. pooption : [];
  1304. mutexclpocall : [pocall_internproc,pocall_inline];
  1305. mutexclpotype : [];
  1306. mutexclpo : [po_external]
  1307. ),(
  1308. idtok:_OLDFPCCALL;
  1309. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1310. handler : nil;
  1311. pocall : pocall_oldfpccall;
  1312. pooption : [];
  1313. mutexclpocall : [];
  1314. mutexclpotype : [];
  1315. mutexclpo : []
  1316. ),(
  1317. idtok:_INLINE;
  1318. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  1319. handler : @pd_inline;
  1320. pocall : pocall_inline;
  1321. pooption : [];
  1322. mutexclpocall : [];
  1323. mutexclpotype : [potype_constructor,potype_destructor];
  1324. mutexclpo : [po_exports,po_external,po_interrupt,po_virtualmethod]
  1325. ),(
  1326. idtok:_INTERNCONST;
  1327. pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf];
  1328. handler : @pd_internconst;
  1329. pocall : pocall_none;
  1330. pooption : [po_internconst];
  1331. mutexclpocall : [];
  1332. mutexclpotype : [potype_operator];
  1333. mutexclpo : []
  1334. ),(
  1335. idtok:_INTERNPROC;
  1336. pd_flags : [pd_interface,pd_notobject,pd_notobjintf];
  1337. handler : @pd_internproc;
  1338. pocall : pocall_internproc;
  1339. pooption : [];
  1340. mutexclpocall : [];
  1341. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1342. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_virtualmethod]
  1343. ),(
  1344. idtok:_INTERRUPT;
  1345. pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf];
  1346. handler : @pd_interrupt;
  1347. pocall : pocall_none;
  1348. pooption : [po_interrupt];
  1349. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,pocall_stdcall,
  1350. pocall_inline,pocall_pascal,pocall_far16,pocall_oldfpccall];
  1351. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1352. mutexclpo : [po_external]
  1353. ),(
  1354. idtok:_IOCHECK;
  1355. pd_flags : [pd_implemen,pd_body,pd_notobjintf];
  1356. handler : nil;
  1357. pocall : pocall_none;
  1358. pooption : [po_iocheck];
  1359. mutexclpocall : [pocall_internproc];
  1360. mutexclpotype : [];
  1361. mutexclpo : [po_external]
  1362. ),(
  1363. idtok:_MESSAGE;
  1364. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1365. handler : @pd_message;
  1366. pocall : pocall_none;
  1367. pooption : []; { can be po_msgstr or po_msgint }
  1368. mutexclpocall : [pocall_inline,pocall_internproc];
  1369. mutexclpotype : [potype_constructor,potype_destructor,potype_operator];
  1370. mutexclpo : [po_interrupt,po_external]
  1371. ),(
  1372. idtok:_NEAR;
  1373. pd_flags : [pd_implemen,pd_body,pd_procvar,pd_notobjintf];
  1374. handler : @pd_near;
  1375. pocall : pocall_none;
  1376. pooption : [];
  1377. mutexclpocall : [pocall_internproc];
  1378. mutexclpotype : [];
  1379. mutexclpo : []
  1380. ),(
  1381. idtok:_NOSTACKFRAME;
  1382. pd_flags : [pd_implemen,pd_body,pd_procvar,pd_notobjintf];
  1383. handler : nil;
  1384. pocall : pocall_none;
  1385. pooption : [po_nostackframe];
  1386. mutexclpocall : [pocall_internproc];
  1387. mutexclpotype : [];
  1388. mutexclpo : []
  1389. ),(
  1390. idtok:_OVERLOAD;
  1391. pd_flags : [pd_implemen,pd_interface,pd_body];
  1392. handler : @pd_overload;
  1393. pocall : pocall_none;
  1394. pooption : [po_overload];
  1395. mutexclpocall : [pocall_internproc];
  1396. mutexclpotype : [];
  1397. mutexclpo : []
  1398. ),(
  1399. idtok:_OVERRIDE;
  1400. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1401. handler : @pd_override;
  1402. pocall : pocall_none;
  1403. pooption : [po_overridingmethod,po_virtualmethod];
  1404. mutexclpocall : [pocall_inline,pocall_internproc];
  1405. mutexclpotype : [];
  1406. mutexclpo : [po_exports,po_external,po_interrupt,po_virtualmethod]
  1407. ),(
  1408. idtok:_PASCAL;
  1409. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1410. handler : nil;
  1411. pocall : pocall_pascal;
  1412. pooption : [];
  1413. mutexclpocall : [];
  1414. mutexclpotype : [potype_constructor,potype_destructor];
  1415. mutexclpo : [po_external]
  1416. ),(
  1417. idtok:_PUBLIC;
  1418. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobject,pd_notobjintf];
  1419. handler : @pd_public;
  1420. pocall : pocall_none;
  1421. pooption : [po_public,po_global];
  1422. mutexclpocall : [pocall_internproc,pocall_inline];
  1423. mutexclpotype : [];
  1424. mutexclpo : [po_external]
  1425. ),(
  1426. idtok:_REGISTER;
  1427. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1428. handler : nil;
  1429. pocall : pocall_register;
  1430. pooption : [];
  1431. mutexclpocall : [];
  1432. mutexclpotype : [potype_constructor,potype_destructor];
  1433. mutexclpo : [po_external]
  1434. ),(
  1435. idtok:_REINTRODUCE;
  1436. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1437. handler : @pd_reintroduce;
  1438. pocall : pocall_none;
  1439. pooption : [po_reintroduce];
  1440. mutexclpocall : [pocall_inline,pocall_internproc];
  1441. mutexclpotype : [];
  1442. mutexclpo : [po_external,po_interrupt,po_exports,po_overridingmethod]
  1443. ),(
  1444. idtok:_SAFECALL;
  1445. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1446. handler : nil;
  1447. pocall : pocall_safecall;
  1448. pooption : [];
  1449. mutexclpocall : [];
  1450. mutexclpotype : [potype_constructor,potype_destructor];
  1451. mutexclpo : [po_external]
  1452. ),(
  1453. idtok:_SOFTFLOAT;
  1454. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1455. handler : nil;
  1456. pocall : pocall_softfloat;
  1457. pooption : [];
  1458. mutexclpocall : [];
  1459. mutexclpotype : [potype_constructor,potype_destructor];
  1460. { it's available with po_external because the libgcc floating point routines on the arm
  1461. uses this calling convention }
  1462. mutexclpo : []
  1463. ),(
  1464. idtok:_STATIC;
  1465. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1466. handler : @pd_static;
  1467. pocall : pocall_none;
  1468. pooption : [po_staticmethod];
  1469. mutexclpocall : [pocall_inline,pocall_internproc];
  1470. mutexclpotype : [potype_constructor,potype_destructor];
  1471. mutexclpo : [po_external,po_interrupt,po_exports]
  1472. ),(
  1473. idtok:_STDCALL;
  1474. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1475. handler : nil;
  1476. pocall : pocall_stdcall;
  1477. pooption : [];
  1478. mutexclpocall : [];
  1479. mutexclpotype : [potype_constructor,potype_destructor];
  1480. mutexclpo : [po_external]
  1481. ),(
  1482. idtok:_SYSCALL;
  1483. pd_flags : [pd_interface,pd_implemen,pd_notobject,pd_notobjintf];
  1484. handler : @pd_syscall;
  1485. pocall : pocall_syscall;
  1486. pooption : [];
  1487. mutexclpocall : [];
  1488. mutexclpotype : [potype_constructor,potype_destructor];
  1489. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  1490. ),(
  1491. idtok:_VIRTUAL;
  1492. pd_flags : [pd_interface,pd_object,pd_notobjintf];
  1493. handler : @pd_virtual;
  1494. pocall : pocall_none;
  1495. pooption : [po_virtualmethod];
  1496. mutexclpocall : [pocall_inline,pocall_internproc];
  1497. mutexclpotype : [];
  1498. mutexclpo : [po_external,po_interrupt,po_exports,po_overridingmethod]
  1499. ),(
  1500. idtok:_CPPDECL;
  1501. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  1502. handler : nil;
  1503. pocall : pocall_cppdecl;
  1504. pooption : [];
  1505. mutexclpocall : [];
  1506. mutexclpotype : [potype_constructor,potype_destructor];
  1507. mutexclpo : [po_assembler,po_external,po_virtualmethod]
  1508. ),(
  1509. idtok:_VARARGS;
  1510. pd_flags : [pd_interface,pd_implemen,pd_procvar];
  1511. handler : nil;
  1512. pocall : pocall_none;
  1513. pooption : [po_varargs];
  1514. mutexclpocall : [pocall_internproc,pocall_stdcall,pocall_register,
  1515. pocall_inline,pocall_far16,pocall_oldfpccall];
  1516. mutexclpotype : [];
  1517. mutexclpo : [po_assembler,po_interrupt]
  1518. ),(
  1519. idtok:_COMPILERPROC;
  1520. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  1521. handler : nil;
  1522. pocall : pocall_compilerproc;
  1523. pooption : [];
  1524. mutexclpocall : [];
  1525. mutexclpotype : [potype_constructor,potype_destructor];
  1526. mutexclpo : [po_interrupt]
  1527. )
  1528. );
  1529. function check_proc_directive(isprocvar:boolean):boolean;
  1530. var
  1531. i : longint;
  1532. begin
  1533. result:=false;
  1534. for i:=1 to num_proc_directives do
  1535. if proc_direcdata[i].idtok=idtoken then
  1536. begin
  1537. if ((not isprocvar) or
  1538. (pd_procvar in proc_direcdata[i].pd_flags)) and
  1539. { don't eat a public directive in classes }
  1540. not((idtoken=_PUBLIC) and (symtablestack.symtabletype=objectsymtable)) then
  1541. result:=true;
  1542. exit;
  1543. end;
  1544. end;
  1545. function parse_proc_direc(pd:tabstractprocdef;var pdflags:tpdflags):boolean;
  1546. {
  1547. Parse the procedure directive, returns true if a correct directive is found
  1548. }
  1549. var
  1550. p : longint;
  1551. found : boolean;
  1552. name : stringid;
  1553. begin
  1554. parse_proc_direc:=false;
  1555. name:=tokeninfo^[idtoken].str;
  1556. found:=false;
  1557. { Hint directive? Then exit immediatly }
  1558. if (m_hintdirective in aktmodeswitches) then
  1559. begin
  1560. case idtoken of
  1561. _LIBRARY,
  1562. _PLATFORM,
  1563. _UNIMPLEMENTED,
  1564. _DEPRECATED :
  1565. exit;
  1566. end;
  1567. end;
  1568. { C directive is MAC only, because it breaks too much existing code
  1569. on other platforms (PFV) }
  1570. if (idtoken=_C) and
  1571. not(m_mac in aktmodeswitches) then
  1572. exit;
  1573. { retrieve data for directive if found }
  1574. for p:=1 to num_proc_directives do
  1575. if proc_direcdata[p].idtok=idtoken then
  1576. begin
  1577. found:=true;
  1578. break;
  1579. end;
  1580. { Check if the procedure directive is known }
  1581. if not found then
  1582. begin
  1583. { parsing a procvar type the name can be any
  1584. next variable !! }
  1585. if ((pdflags * [pd_procvar,pd_object])=[]) and
  1586. not(idtoken=_PROPERTY) then
  1587. Message1(parser_w_unknown_proc_directive_ignored,name);
  1588. exit;
  1589. end;
  1590. { static needs a special treatment }
  1591. if (idtoken=_STATIC) and not (cs_static_keyword in aktmoduleswitches) then
  1592. exit;
  1593. { Conflicts between directives ? }
  1594. if (pd.proctypeoption in proc_direcdata[p].mutexclpotype) or
  1595. (pd.proccalloption in proc_direcdata[p].mutexclpocall) or
  1596. ((pd.procoptions*proc_direcdata[p].mutexclpo)<>[]) then
  1597. begin
  1598. Message1(parser_e_proc_dir_conflict,name);
  1599. exit;
  1600. end;
  1601. { set calling convention }
  1602. if proc_direcdata[p].pocall<>pocall_none then
  1603. begin
  1604. if (po_hascallingconvention in pd.procoptions) then
  1605. begin
  1606. Message2(parser_w_proc_overriding_calling,
  1607. proccalloptionStr[pd.proccalloption],
  1608. proccalloptionStr[proc_direcdata[p].pocall]);
  1609. end;
  1610. { check if the target processor supports this calling convention }
  1611. if not(proc_direcdata[p].pocall in supported_calling_conventions) then
  1612. begin
  1613. Message1(parser_e_illegal_calling_convention,proccalloptionStr[proc_direcdata[p].pocall]);
  1614. { recover }
  1615. proc_direcdata[p].pocall:=pocall_stdcall;
  1616. end;
  1617. pd.proccalloption:=proc_direcdata[p].pocall;
  1618. include(pd.procoptions,po_hascallingconvention);
  1619. end;
  1620. { check if method and directive not for object, like public.
  1621. This needs to be checked also for procvars }
  1622. if (pd_notobject in proc_direcdata[p].pd_flags) and
  1623. (pd.owner.symtabletype=objectsymtable) then
  1624. exit;
  1625. if pd.deftype=procdef then
  1626. begin
  1627. { Check if the directive is only for objects }
  1628. if (pd_object in proc_direcdata[p].pd_flags) and
  1629. not assigned(tprocdef(pd)._class) then
  1630. exit;
  1631. { check if method and directive not for interface }
  1632. if (pd_notobjintf in proc_direcdata[p].pd_flags) and
  1633. is_interface(tprocdef(pd)._class) then
  1634. exit;
  1635. end
  1636. { don't eat public in object/class declarions }
  1637. else if (pd.deftype=procvardef) and (proc_direcdata[p].idtok=_PUBLIC) and
  1638. (symtablestack.symtabletype=objectsymtable) then
  1639. exit;
  1640. { consume directive, and turn flag on }
  1641. consume(token);
  1642. parse_proc_direc:=true;
  1643. { Check the pd_flags if the directive should be allowed }
  1644. if (pd_interface in pdflags) and
  1645. not(pd_interface in proc_direcdata[p].pd_flags) then
  1646. begin
  1647. Message1(parser_e_proc_dir_not_allowed_in_interface,name);
  1648. exit;
  1649. end;
  1650. if (pd_implemen in pdflags) and
  1651. not(pd_implemen in proc_direcdata[p].pd_flags) then
  1652. begin
  1653. Message1(parser_e_proc_dir_not_allowed_in_implementation,name);
  1654. exit;
  1655. end;
  1656. if (pd_procvar in pdflags) and
  1657. not(pd_procvar in proc_direcdata[p].pd_flags) then
  1658. begin
  1659. Message1(parser_e_proc_dir_not_allowed_in_procvar,name);
  1660. exit;
  1661. end;
  1662. { Return the new pd_flags }
  1663. if not(pd_body in proc_direcdata[p].pd_flags) then
  1664. exclude(pdflags,pd_body);
  1665. { Add the correct flag }
  1666. pd.procoptions:=pd.procoptions+proc_direcdata[p].pooption;
  1667. { Call the handler }
  1668. if pointer(proc_direcdata[p].handler)<>nil then
  1669. proc_direcdata[p].handler(pd);
  1670. end;
  1671. procedure proc_set_mangledname(pd:tprocdef);
  1672. begin
  1673. { When the mangledname is already set we aren't allowed to change
  1674. it because it can already be used somewhere (PFV) }
  1675. if not(po_has_mangledname in pd.procoptions) then
  1676. begin
  1677. { External Procedures }
  1678. if (po_external in pd.procoptions) then
  1679. begin
  1680. { import by number? }
  1681. if pd.import_nr<>0 then
  1682. begin
  1683. { Nothing to do }
  1684. end
  1685. else
  1686. { external name specified }
  1687. if assigned(pd.import_name) then
  1688. begin
  1689. { Win32 imports need to use the normal name since to functions
  1690. can refer to the same DLL function. This is also needed for compatability
  1691. with Delphi and TP7 }
  1692. if not(
  1693. assigned(pd.import_dll) and
  1694. (target_info.system in [system_i386_win32,system_i386_wdosx,
  1695. system_i386_emx,system_i386_os2])
  1696. ) then
  1697. begin
  1698. if not(pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
  1699. pd.setmangledname(pd.import_name^)
  1700. else
  1701. pd.setmangledname(target_info.Cprefix+pd.import_name^);
  1702. end;
  1703. end
  1704. else
  1705. begin
  1706. { Default names when importing variables }
  1707. case pd.proccalloption of
  1708. pocall_cdecl :
  1709. begin
  1710. if assigned(pd._class) then
  1711. pd.setmangledname(target_info.Cprefix+pd._class.objrealname^+'_'+pd.procsym.realname)
  1712. else
  1713. pd.setmangledname(target_info.Cprefix+pd.procsym.realname);
  1714. end;
  1715. pocall_cppdecl :
  1716. begin
  1717. pd.setmangledname(target_info.Cprefix+pd.cplusplusmangledname);
  1718. end;
  1719. else
  1720. begin
  1721. {In MacPas a single "external" has the same effect as "external name 'xxx'" }
  1722. if (m_mac in aktmodeswitches) then
  1723. tprocdef(pd).setmangledname(tprocdef(pd).procsym.realname);
  1724. end;
  1725. end;
  1726. end;
  1727. end
  1728. else
  1729. { Normal procedures }
  1730. begin
  1731. case pd.proccalloption of
  1732. pocall_compilerproc :
  1733. begin
  1734. pd.setmangledname(lower(pd.procsym.name));
  1735. end;
  1736. end;
  1737. end;
  1738. end;
  1739. { Public/exported alias names }
  1740. if (po_public in pd.procoptions) and
  1741. not(po_has_public_name in pd.procoptions) then
  1742. begin
  1743. case pd.proccalloption of
  1744. pocall_cdecl :
  1745. begin
  1746. if assigned(pd._class) then
  1747. pd.aliasnames.insert(target_info.Cprefix+pd._class.objrealname^+'_'+pd.procsym.realname)
  1748. else
  1749. pd.aliasnames.insert(target_info.Cprefix+pd.procsym.realname);
  1750. end;
  1751. pocall_cppdecl :
  1752. begin
  1753. pd.aliasnames.insert(target_info.Cprefix+pd.cplusplusmangledname);
  1754. end;
  1755. end;
  1756. { prevent adding the alias a second time }
  1757. include(pd.procoptions,po_has_public_name);
  1758. end;
  1759. end;
  1760. procedure handle_calling_convention(pd:tabstractprocdef);
  1761. begin
  1762. { set the default calling convention if none provided }
  1763. if not(po_hascallingconvention in pd.procoptions) then
  1764. pd.proccalloption:=aktdefproccall
  1765. else
  1766. begin
  1767. if pd.proccalloption=pocall_none then
  1768. internalerror(200309081);
  1769. end;
  1770. { handle proccall specific settings }
  1771. case pd.proccalloption of
  1772. pocall_cdecl,
  1773. pocall_cppdecl :
  1774. begin
  1775. { check C cdecl para types }
  1776. pd.parast.foreach_static(@check_c_para,nil);
  1777. end;
  1778. pocall_far16 :
  1779. begin
  1780. { Temporary stub, must be rewritten to support OS/2 far16 }
  1781. Message1(parser_w_proc_directive_ignored,'FAR16');
  1782. end;
  1783. pocall_inline :
  1784. begin
  1785. if not(cs_support_inline in aktmoduleswitches) then
  1786. begin
  1787. Message(parser_e_proc_inline_not_supported);
  1788. pd.proccalloption:=pocall_default;
  1789. end;
  1790. end;
  1791. end;
  1792. { For varargs directive also cdecl and external must be defined }
  1793. if (po_varargs in pd.procoptions) then
  1794. begin
  1795. { check first for external in the interface, if available there
  1796. then the cdecl must also be there since there is no implementation
  1797. available to contain it }
  1798. if parse_only then
  1799. begin
  1800. { if external is available, then cdecl must also be available,
  1801. procvars don't need external }
  1802. if not((po_external in pd.procoptions) or
  1803. (pd.deftype=procvardef)) and
  1804. not(pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
  1805. Message(parser_e_varargs_need_cdecl_and_external);
  1806. end
  1807. else
  1808. begin
  1809. { both must be defined now }
  1810. if not((po_external in pd.procoptions) or
  1811. (pd.deftype=procvardef)) or
  1812. not(pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
  1813. Message(parser_e_varargs_need_cdecl_and_external);
  1814. end;
  1815. end;
  1816. { Make var parameters regable, this must be done after the calling
  1817. convention is set. }
  1818. pd.parast.foreach_static(@set_addr_param_regable,pd);
  1819. { insert hidden high parameters }
  1820. pd.parast.foreach_static(@insert_hidden_para,pd);
  1821. { insert hidden self parameter }
  1822. insert_self_and_vmt_para(pd);
  1823. { insert funcret parameter if required }
  1824. insert_funcret_para(pd);
  1825. { insert parentfp parameter if required }
  1826. insert_parentfp_para(pd);
  1827. { Calculate parameter tlist }
  1828. pd.calcparas;
  1829. end;
  1830. procedure parse_proc_directives(pd:tabstractprocdef;var pdflags:tpdflags);
  1831. {
  1832. Parse the procedure directives. It does not matter if procedure directives
  1833. are written using ;procdir; or ['procdir'] syntax.
  1834. }
  1835. var
  1836. res : boolean;
  1837. begin
  1838. if (m_mac in aktmodeswitches) and (cs_externally_visible in aktlocalswitches) then
  1839. begin
  1840. tprocdef(pd).aliasnames.insert(tprocdef(pd).procsym.realname);
  1841. include(pd.procoptions,po_public);
  1842. include(pd.procoptions,po_has_public_name);
  1843. include(pd.procoptions,po_global);
  1844. end;
  1845. while token in [_ID,_LECKKLAMMER] do
  1846. begin
  1847. if try_to_consume(_LECKKLAMMER) then
  1848. begin
  1849. repeat
  1850. parse_proc_direc(pd,pdflags);
  1851. until not try_to_consume(_COMMA);
  1852. consume(_RECKKLAMMER);
  1853. { we always expect at least '[];' }
  1854. res:=true;
  1855. end
  1856. else
  1857. begin
  1858. res:=parse_proc_direc(pd,pdflags);
  1859. end;
  1860. { A procedure directive normally followed by a semicolon, but in
  1861. a const section or reading a type we should stop when _EQUAL is found,
  1862. because a constant/default value follows }
  1863. if res then
  1864. begin
  1865. if (block_type in [bt_const,bt_type]) and
  1866. (token=_EQUAL) then
  1867. break;
  1868. { support procedure proc;stdcall export; }
  1869. if not(check_proc_directive((pd.deftype=procvardef))) then
  1870. consume(_SEMICOLON);
  1871. end
  1872. else
  1873. break;
  1874. end;
  1875. end;
  1876. procedure parse_var_proc_directives(sym:tsym);
  1877. var
  1878. pdflags : tpdflags;
  1879. pd : tabstractprocdef;
  1880. begin
  1881. pdflags:=[pd_procvar];
  1882. pd:=nil;
  1883. case sym.typ of
  1884. fieldvarsym,
  1885. globalvarsym,
  1886. localvarsym,
  1887. paravarsym :
  1888. pd:=tabstractprocdef(tabstractvarsym(sym).vartype.def);
  1889. typedconstsym :
  1890. pd:=tabstractprocdef(ttypedconstsym(sym).typedconsttype.def);
  1891. typesym :
  1892. pd:=tabstractprocdef(ttypesym(sym).restype.def);
  1893. else
  1894. internalerror(2003042617);
  1895. end;
  1896. if pd.deftype<>procvardef then
  1897. internalerror(2003042618);
  1898. { names should never be used anyway }
  1899. parse_proc_directives(pd,pdflags);
  1900. end;
  1901. procedure parse_object_proc_directives(pd:tabstractprocdef);
  1902. var
  1903. pdflags : tpdflags;
  1904. begin
  1905. pdflags:=[pd_object];
  1906. parse_proc_directives(pd,pdflags);
  1907. end;
  1908. function proc_add_definition(var pd:tprocdef):boolean;
  1909. {
  1910. Add definition aprocdef to the overloaded definitions of aprocsym. If a
  1911. forwarddef is found and reused it returns true
  1912. }
  1913. var
  1914. hd : tprocdef;
  1915. ad,fd : tsym;
  1916. s1,s2 : stringid;
  1917. i : cardinal;
  1918. forwardfound : boolean;
  1919. po_comp : tprocoptions;
  1920. aprocsym : tprocsym;
  1921. begin
  1922. forwardfound:=false;
  1923. aprocsym:=tprocsym(pd.procsym);
  1924. { check overloaded functions if the same function already exists }
  1925. for i:=1 to aprocsym.procdef_count do
  1926. begin
  1927. hd:=aprocsym.procdef[i];
  1928. { Skip overloaded definitions that are declared in other
  1929. units }
  1930. if hd.procsym<>aprocsym then
  1931. continue;
  1932. { check the parameters, for delphi/tp it is possible to
  1933. leave the parameters away in the implementation (forwarddef=false).
  1934. But for an overload declared function this is not allowed }
  1935. if { check if empty implementation arguments match is allowed }
  1936. (
  1937. not(m_repeat_forward in aktmodeswitches) and
  1938. not(pd.forwarddef) and
  1939. (pd.maxparacount=0) and
  1940. not(po_overload in hd.procoptions)
  1941. ) or
  1942. { check arguments }
  1943. (
  1944. (compare_paras(pd.paras,hd.paras,cp_none,[cpo_comparedefaultvalue])>=te_equal) and
  1945. { for operators equal_paras is not enough !! }
  1946. ((pd.proctypeoption<>potype_operator) or (optoken<>_ASSIGNMENT) or
  1947. equal_defs(hd.rettype.def,pd.rettype.def))
  1948. ) then
  1949. begin
  1950. { Check if we've found the forwarddef, if found then
  1951. we need to update the forward def with the current
  1952. implementation settings }
  1953. if hd.forwarddef then
  1954. begin
  1955. forwardfound:=true;
  1956. { Check if the procedure type and return type are correct,
  1957. also the parameters must match also with the type }
  1958. if (hd.proctypeoption<>pd.proctypeoption) or
  1959. (
  1960. (m_repeat_forward in aktmodeswitches) and
  1961. (not((pd.maxparacount=0) or
  1962. (compare_paras(pd.paras,hd.paras,cp_all,[cpo_comparedefaultvalue])>=te_equal)))
  1963. ) or
  1964. (
  1965. ((m_repeat_forward in aktmodeswitches) or
  1966. not(is_void(pd.rettype.def))) and
  1967. (not equal_defs(hd.rettype.def,pd.rettype.def))) then
  1968. begin
  1969. MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,
  1970. pd.fullprocname(false));
  1971. aprocsym.write_parameter_lists(pd);
  1972. break;
  1973. end;
  1974. { Check if both are declared forward }
  1975. if hd.forwarddef and pd.forwarddef then
  1976. begin
  1977. MessagePos1(pd.fileinfo,parser_e_function_already_declared_public_forward,
  1978. pd.fullprocname(false));
  1979. end;
  1980. { internconst or internproc only need to be defined once }
  1981. if (hd.proccalloption=pocall_internproc) then
  1982. pd.proccalloption:=hd.proccalloption
  1983. else
  1984. if (pd.proccalloption=pocall_internproc) then
  1985. hd.proccalloption:=pd.proccalloption;
  1986. { Check calling convention }
  1987. if (hd.proccalloption<>pd.proccalloption) then
  1988. begin
  1989. { In delphi it is possible to specify the calling
  1990. convention in the interface or implementation if
  1991. there was no convention specified in the other
  1992. part }
  1993. if (m_delphi in aktmodeswitches) then
  1994. begin
  1995. if not(po_hascallingconvention in pd.procoptions) then
  1996. pd.proccalloption:=hd.proccalloption
  1997. else
  1998. if not(po_hascallingconvention in hd.procoptions) then
  1999. hd.proccalloption:=pd.proccalloption
  2000. else
  2001. begin
  2002. MessagePos(pd.fileinfo,parser_e_call_convention_dont_match_forward);
  2003. aprocsym.write_parameter_lists(pd);
  2004. { restore interface settings }
  2005. pd.proccalloption:=hd.proccalloption;
  2006. end;
  2007. end
  2008. else
  2009. begin
  2010. MessagePos(pd.fileinfo,parser_e_call_convention_dont_match_forward);
  2011. aprocsym.write_parameter_lists(pd);
  2012. { restore interface settings }
  2013. pd.proccalloption:=hd.proccalloption;
  2014. end;
  2015. end;
  2016. { Check procedure options, Delphi requires that class is
  2017. repeated in the implementation for class methods }
  2018. if (m_fpc in aktmodeswitches) then
  2019. po_comp:=[po_varargs,po_methodpointer,po_interrupt]
  2020. else
  2021. po_comp:=[po_classmethod,po_methodpointer];
  2022. if ((po_comp * hd.procoptions)<>(po_comp * pd.procoptions)) then
  2023. begin
  2024. MessagePos1(pd.fileinfo,parser_e_header_dont_match_forward,
  2025. pd.fullprocname(false));
  2026. aprocsym.write_parameter_lists(pd);
  2027. { This error is non-fatal, we can recover }
  2028. end;
  2029. { Forward declaration is external? }
  2030. if (po_external in hd.procoptions) then
  2031. MessagePos(pd.fileinfo,parser_e_proc_already_external)
  2032. else
  2033. { Body declaration is external? }
  2034. if (po_external in pd.procoptions) then
  2035. begin
  2036. { Win32 supports declaration in interface and external in
  2037. implementation for dll imports. Support this for backwards
  2038. compatibility with Tp7 and Delphi }
  2039. if not(
  2040. (target_info.system in [system_i386_win32,system_i386_wdosx,
  2041. system_i386_emx,system_i386_os2]) and
  2042. assigned(pd.import_dll)
  2043. ) then
  2044. MessagePos(pd.fileinfo,parser_e_proc_no_external_allowed);
  2045. end;
  2046. { Check parameters }
  2047. if (m_repeat_forward in aktmodeswitches) or
  2048. (pd.minparacount>0) then
  2049. begin
  2050. { If mangled names are equal then they have the same amount of arguments }
  2051. { We can check the names of the arguments }
  2052. { both symtables are in the same order from left to right }
  2053. ad:=tsym(hd.parast.symindex.first);
  2054. fd:=tsym(pd.parast.symindex.first);
  2055. repeat
  2056. { skip default parameter constsyms }
  2057. while assigned(ad) and (ad.typ<>paravarsym) do
  2058. ad:=tsym(ad.indexnext);
  2059. while assigned(fd) and (fd.typ<>paravarsym) do
  2060. fd:=tsym(fd.indexnext);
  2061. { stop when one of the two lists is at the end }
  2062. if not assigned(ad) or not assigned(fd) then
  2063. break;
  2064. { retrieve names, remove reg for register parameters }
  2065. s1:=ad.name;
  2066. s2:=fd.name;
  2067. { compare names }
  2068. if (s1<>s2) then
  2069. begin
  2070. MessagePos3(pd.fileinfo,parser_e_header_different_var_names,
  2071. aprocsym.name,s1,s2);
  2072. break;
  2073. end;
  2074. ad:=tsym(ad.indexnext);
  2075. fd:=tsym(fd.indexnext);
  2076. until false;
  2077. if assigned(ad) xor assigned(fd) then
  2078. internalerror(200204178);
  2079. end;
  2080. { Everything is checked, now we can update the forward declaration
  2081. with the new data from the implementation }
  2082. hd.forwarddef:=pd.forwarddef;
  2083. hd.hasforward:=true;
  2084. hd.procoptions:=hd.procoptions+pd.procoptions;
  2085. if hd.extnumber=65535 then
  2086. hd.extnumber:=pd.extnumber;
  2087. while not pd.aliasnames.empty do
  2088. hd.aliasnames.insert(pd.aliasnames.getfirst);
  2089. { update fileinfo so position references the implementation,
  2090. also update funcretsym if it is already generated }
  2091. hd.fileinfo:=pd.fileinfo;
  2092. if assigned(hd.funcretsym) then
  2093. hd.funcretsym.fileinfo:=pd.fileinfo;
  2094. { import names }
  2095. if assigned(pd.import_dll) then
  2096. begin
  2097. stringdispose(hd.import_dll);
  2098. hd.import_dll:=stringdup(pd.import_dll^);
  2099. end;
  2100. if assigned(pd.import_name) then
  2101. begin
  2102. stringdispose(hd.import_name);
  2103. hd.import_name:=stringdup(pd.import_name^);
  2104. end;
  2105. hd.import_nr:=pd.import_nr;
  2106. { for compilerproc defines we need to rename and update the
  2107. symbolname to lowercase }
  2108. if (pd.proccalloption=pocall_compilerproc) then
  2109. begin
  2110. { rename to lowercase so users can't access it }
  2111. aprocsym.owner.rename(aprocsym.name,lower(aprocsym.name));
  2112. { also update the realname that is stored in the ppu }
  2113. stringdispose(aprocsym._realname);
  2114. aprocsym._realname:=stringdup('$'+aprocsym.name);
  2115. { the mangeled name is already changed by the pd_compilerproc }
  2116. { handler. It must be done immediately because if we have a }
  2117. { call to a compilerproc before it's implementation is }
  2118. { encountered, it must already use the new mangled name (JM) }
  2119. end;
  2120. { the procdef will be released by the symtable, we release
  2121. at least the parast }
  2122. pd.releasemem;
  2123. pd:=hd;
  2124. end
  2125. else
  2126. begin
  2127. { abstract methods aren't forward defined, but this }
  2128. { needs another error message }
  2129. if (po_abstractmethod in hd.procoptions) then
  2130. MessagePos(pd.fileinfo,parser_e_abstract_no_definition)
  2131. else
  2132. begin
  2133. MessagePos(pd.fileinfo,parser_e_overloaded_have_same_parameters);
  2134. aprocsym.write_parameter_lists(pd);
  2135. end;
  2136. end;
  2137. { we found one proc with the same arguments, there are no others
  2138. so we can stop }
  2139. break;
  2140. end;
  2141. { check for allowing overload directive }
  2142. if not(m_fpc in aktmodeswitches) then
  2143. begin
  2144. { overload directive turns on overloading }
  2145. if ((po_overload in pd.procoptions) or
  2146. (po_overload in hd.procoptions)) then
  2147. begin
  2148. { check if all procs have overloading, but not if the proc is a method or
  2149. already declared forward, then the check is already done }
  2150. if not(hd.hasforward or
  2151. assigned(pd._class) or
  2152. (pd.forwarddef<>hd.forwarddef) or
  2153. ((po_overload in pd.procoptions) and
  2154. (po_overload in hd.procoptions))) then
  2155. begin
  2156. MessagePos1(pd.fileinfo,parser_e_no_overload_for_all_procs,aprocsym.realname);
  2157. break;
  2158. end;
  2159. end
  2160. else
  2161. begin
  2162. if not(hd.forwarddef) then
  2163. begin
  2164. MessagePos(pd.fileinfo,parser_e_procedure_overloading_is_off);
  2165. break;
  2166. end;
  2167. end;
  2168. end; { equal arguments }
  2169. end;
  2170. { if we didn't reuse a forwarddef then we add the procdef to the overloaded
  2171. list }
  2172. if not forwardfound then
  2173. aprocsym.addprocdef(pd);
  2174. proc_add_definition:=forwardfound;
  2175. end;
  2176. end.
  2177. {
  2178. $Log$
  2179. Revision 1.218 2004-12-07 16:11:52 peter
  2180. * set vo_explicit_paraloc flag
  2181. Revision 1.217 2004/12/05 12:28:11 peter
  2182. * procvar handling for tp procvar mode fixed
  2183. * proc to procvar moved from addrnode to typeconvnode
  2184. * inlininginfo is now allocated only for inline routines that
  2185. can be inlined, introduced a new flag po_has_inlining_info
  2186. Revision 1.216 2004/12/05 00:32:56 olle
  2187. + bugfix for $Z+ for mode macpas
  2188. Revision 1.215 2004/11/29 21:50:08 peter
  2189. * public is allowd in interface
  2190. Revision 1.214 2004/11/29 17:48:34 peter
  2191. * when importing by index don't change mangledname
  2192. Revision 1.213 2004/11/22 12:22:25 jonas
  2193. * fixed importing of cdecl routines for OS'es which have a cprefix
  2194. Revision 1.212 2004/11/21 17:54:59 peter
  2195. * ttempcreatenode.create_reg merged into .create with parameter
  2196. whether a register is allowed
  2197. * funcret_paraloc renamed to funcretloc
  2198. Revision 1.211 2004/11/21 16:33:19 peter
  2199. * fixed message methods
  2200. * fixed typo with win32 dll import from implementation
  2201. * released external check
  2202. Revision 1.210 2004/11/19 08:17:01 michael
  2203. * Split po_public into po_public and po_global (Peter)
  2204. Revision 1.209 2004/11/17 22:41:41 peter
  2205. * make some checks EXTDEBUG only for now so linux cycles again
  2206. Revision 1.208 2004/11/17 22:21:35 peter
  2207. mangledname setting moved to place after the complete proc declaration is read
  2208. import generation moved to place where body is also parsed (still gives problems with win32)
  2209. Revision 1.207 2004/11/16 22:09:57 peter
  2210. * _mangledname for symbols moved only to symbols that really need it
  2211. * overload number removed, add function result type to the mangledname fo
  2212. procdefs
  2213. Revision 1.206 2004/11/16 20:32:40 peter
  2214. * fixes for win32 mangledname
  2215. Revision 1.205 2004/11/15 23:35:31 peter
  2216. * tparaitem removed, use tparavarsym instead
  2217. * parameter order is now calculated from paranr value in tparavarsym
  2218. Revision 1.204 2004/11/14 16:26:29 florian
  2219. * fixed morphos syscall
  2220. Revision 1.203 2004/11/11 19:31:33 peter
  2221. * fixed compile of powerpc,sparc,arm
  2222. Revision 1.202 2004/11/09 22:32:59 peter
  2223. * small m68k updates to bring it up2date
  2224. * give better error for external local variable
  2225. Revision 1.201 2004/11/09 17:26:47 peter
  2226. * fixed wrong typecasts
  2227. Revision 1.200 2004/11/08 22:09:59 peter
  2228. * tvarsym splitted
  2229. Revision 1.199 2004/11/05 21:16:55 peter
  2230. * rename duplicate symbols and insert with unique name in the
  2231. symtable
  2232. Revision 1.198 2004/10/31 18:54:24 peter
  2233. * $fpctarget expands to <cpu>-<os>
  2234. * allow * in middle of the path to support ../*/units/$fpctarget
  2235. Revision 1.197 2004/10/24 20:01:08 peter
  2236. * remove saveregister calling convention
  2237. Revision 1.196 2004/10/24 13:48:50 peter
  2238. * don't give warning for property as unknwon proc directive
  2239. Revision 1.195 2004/10/24 11:44:28 peter
  2240. * small regvar fixes
  2241. * loadref parameter removed from concatcopy,incrrefcount,etc
  2242. Revision 1.194 2004/10/15 09:14:17 mazen
  2243. - remove $IFDEF DELPHI and related code
  2244. - remove $IFDEF FPCPROCVAR and related code
  2245. Revision 1.193 2004/10/11 15:45:35 peter
  2246. * mark non-regable after calling convention is set
  2247. Revision 1.192 2004/10/10 21:08:55 peter
  2248. * parameter regvar fixes
  2249. Revision 1.191 2004/10/08 17:09:43 peter
  2250. * tvarsym.varregable added, split vo_regable from varoptions
  2251. Revision 1.190 2004/08/29 11:28:41 peter
  2252. fixed crash with error in default value
  2253. allow assembler directive in interface
  2254. Revision 1.189 2004/08/25 15:57:19 peter
  2255. * fix for tw3261
  2256. Revision 1.188 2004/08/22 20:11:38 florian
  2257. * morphos now takes any pointer var. as libbase
  2258. * alignment for sparc fixed
  2259. * int -> double conversion on sparc fixed
  2260. Revision 1.187 2004/08/22 11:24:27 peter
  2261. * don't insert result variables for constructor/destructors
  2262. Revision 1.186 2004/08/13 17:53:37 jonas
  2263. * only set the mangled name immediately for external procedures in macpas
  2264. mode if the procedure isn't cdecl (so that the c-prefix is taken into
  2265. account, necessary for Mac OS X)
  2266. Revision 1.185 2004/08/08 12:35:09 florian
  2267. * proc. var declarations in a class doesn't eat a public anymore
  2268. Revision 1.184 2004/07/17 13:51:57 florian
  2269. * function result location for syscalls on MOS hopefully correctly set now
  2270. Revision 1.183 2004/07/14 23:19:21 olle
  2271. + added external facilities for macpas
  2272. Revision 1.182 2004/06/20 08:55:30 florian
  2273. * logs truncated
  2274. Revision 1.181 2004/06/16 20:07:09 florian
  2275. * dwarf branch merged
  2276. Revision 1.180 2004/05/23 20:54:39 peter
  2277. * fixed 3114
  2278. Revision 1.179 2004/05/23 19:06:26 peter
  2279. * expect : after function when it is a forwarddef
  2280. Revision 1.178 2004/05/12 13:21:09 karoly
  2281. * few small changes to add syscall support to M68k/Amiga target
  2282. Revision 1.177 2004/05/11 22:52:48 olle
  2283. * Moved import_implicit_external to symsym
  2284. }