pdecsub.pas 126 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl, Daniel Mantione
  3. Does the parsing of the procedures/functions
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit pdecsub;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. { common }
  22. cclasses,
  23. { scanner }
  24. tokens,
  25. { symtable }
  26. symconst,symtype,symdef,symsym;
  27. type
  28. tpdflag=(
  29. pd_body, { directive needs a body }
  30. pd_implemen, { directive can be used in implementation section }
  31. pd_interface, { directive can be used in interface section }
  32. pd_object, { directive can be used with object declaration }
  33. pd_record, { directive can be used with record declaration }
  34. pd_procvar, { directive can be used with procvar declaration }
  35. pd_notobject, { directive can not be used with object declaration }
  36. pd_notrecord, { directive can not be used with record declaration }
  37. pd_notobjintf, { directive can not be used with interface declaration }
  38. pd_notprocvar, { directive can not be used with procvar declaration }
  39. pd_dispinterface,{ directive can be used with dispinterface methods }
  40. pd_cppobject, { directive can be used with cppclass }
  41. pd_objcclass, { directive can be used with objcclass }
  42. pd_objcprot, { directive can be used with objcprotocol }
  43. pd_nothelper, { directive can not be used with record/class helper declaration }
  44. pd_javaclass, { directive can be used with Java class }
  45. pd_intfjava { directive can be used with Java interface }
  46. );
  47. tpdflags=set of tpdflag;
  48. function check_proc_directive(isprocvar:boolean):boolean;
  49. function proc_get_importname(pd:tprocdef):string;
  50. procedure proc_set_mangledname(pd:tprocdef);
  51. procedure parse_parameter_dec(pd:tabstractprocdef);
  52. procedure parse_proc_directives(pd:tabstractprocdef;var pdflags:tpdflags);
  53. procedure parse_var_proc_directives(sym:tsym);
  54. procedure parse_object_proc_directives(pd:tabstractprocdef);
  55. procedure parse_record_proc_directives(pd:tabstractprocdef);
  56. function parse_proc_head(astruct:tabstractrecorddef;potype:tproctypeoption;isgeneric:boolean;genericdef:tdef;generictypelist:tfphashobjectlist;out pd:tprocdef):boolean;
  57. function parse_proc_dec(isclassmethod:boolean;astruct:tabstractrecorddef;isgeneric:boolean):tprocdef;
  58. procedure parse_proc_dec_finish(pd:tprocdef;isclassmethod:boolean;astruct:tabstractrecorddef);
  59. { parse a record method declaration (not a (class) constructor/destructor) }
  60. function parse_record_method_dec(astruct: tabstractrecorddef; is_classdef: boolean;hadgeneric:boolean): tprocdef;
  61. { helper functions - they insert nested objects hierarchy to the symtablestack
  62. with object hierarchy
  63. }
  64. function push_child_hierarchy(obj:tabstractrecorddef):integer;
  65. function pop_child_hierarchy(obj:tabstractrecorddef):integer;
  66. function push_nested_hierarchy(obj:tabstractrecorddef):integer;
  67. function pop_nested_hierarchy(obj:tabstractrecorddef):integer;
  68. implementation
  69. uses
  70. SysUtils,
  71. { common }
  72. cutils,
  73. { global }
  74. globtype,globals,verbose,constexp,
  75. systems,
  76. cpuinfo,
  77. { assembler }
  78. aasmbase,
  79. { symtable }
  80. symbase,symcpu,symtable,symutil,defutil,defcmp,
  81. { parameter handling }
  82. paramgr,cpupara,
  83. { pass 1 }
  84. fmodule,node,htypechk,ncon,nld,
  85. objcutil,
  86. { parser }
  87. scanner,
  88. syscinfo,
  89. pbase,pexpr,ptype,pdecl,pparautl,pgenutil
  90. {$ifdef jvm}
  91. ,pjvm
  92. {$endif}
  93. ;
  94. const
  95. { Please leave this here, this module should NOT use
  96. these variables.
  97. Declaring it as string here results in an error when compiling (PFV) }
  98. current_procinfo = 'error';
  99. function push_child_hierarchy(obj:tabstractrecorddef):integer;
  100. var
  101. _class,hp : tobjectdef;
  102. begin
  103. if obj.typ=recorddef then
  104. begin
  105. symtablestack.push(obj.symtable);
  106. result:=1;
  107. exit;
  108. end;
  109. result:=0;
  110. { insert class hierarchy in the reverse order }
  111. hp:=nil;
  112. repeat
  113. _class:=tobjectdef(obj);
  114. while _class.childof<>hp do
  115. _class:=_class.childof;
  116. hp:=_class;
  117. symtablestack.push(_class.symtable);
  118. inc(result);
  119. until hp=obj;
  120. end;
  121. function push_nested_hierarchy(obj:tabstractrecorddef):integer;
  122. begin
  123. result:=0;
  124. if obj.owner.symtabletype in [ObjectSymtable,recordsymtable] then
  125. inc(result,push_nested_hierarchy(tabstractrecorddef(obj.owner.defowner)));
  126. inc(result,push_child_hierarchy(obj));
  127. end;
  128. function pop_child_hierarchy(obj:tabstractrecorddef):integer;
  129. var
  130. _class : tobjectdef;
  131. begin
  132. if obj.typ=recorddef then
  133. begin
  134. symtablestack.pop(obj.symtable);
  135. result:=1;
  136. exit;
  137. end;
  138. result:=0;
  139. _class:=tobjectdef(obj);
  140. while assigned(_class) do
  141. begin
  142. symtablestack.pop(_class.symtable);
  143. _class:=_class.childof;
  144. inc(result);
  145. end;
  146. end;
  147. function pop_nested_hierarchy(obj:tabstractrecorddef):integer;
  148. begin
  149. result:=pop_child_hierarchy(obj);
  150. if obj.owner.symtabletype in [ObjectSymtable,recordsymtable] then
  151. inc(result,pop_nested_hierarchy(tabstractrecorddef(obj.owner.defowner)));
  152. end;
  153. procedure check_msg_para(p:TObject;arg:pointer);
  154. begin
  155. if (tsym(p).typ<>paravarsym) then
  156. exit;
  157. with tparavarsym(p) do
  158. begin
  159. { Count parameters }
  160. if (paranr>=10) then
  161. inc(plongint(arg)^);
  162. { First parameter must be var }
  163. if (paranr=10) and
  164. (varspez<>vs_var) then
  165. MessagePos(fileinfo,parser_e_ill_msg_param);
  166. end;
  167. end;
  168. procedure parse_parameter_dec(pd:tabstractprocdef);
  169. {
  170. handle_procvar needs the same changes
  171. }
  172. type
  173. tppv = (pv_none,pv_proc,pv_func);
  174. var
  175. sc : TFPObjectList;
  176. hdef : tdef;
  177. arrayelementdef : tdef;
  178. vs : tparavarsym;
  179. i : longint;
  180. srsym : tsym;
  181. pv : tprocvardef;
  182. varspez : Tvarspez;
  183. defaultvalue : tconstsym;
  184. defaultrequired : boolean;
  185. old_block_type : tblock_type;
  186. currparast : tparasymtable;
  187. parseprocvar : tppv;
  188. locationstr : string;
  189. paranr : integer;
  190. dummytype : ttypesym;
  191. explicit_paraloc,
  192. need_array,
  193. is_univ: boolean;
  194. stoptions : TSingleTypeOptions;
  195. procedure handle_default_para_value;
  196. var
  197. convpd : tprocdef;
  198. doconv : tconverttype;
  199. nodetype : tnodetype;
  200. bt : tblock_type;
  201. begin
  202. { only allowed for types that can be represented by a
  203. constant expression }
  204. if try_to_consume(_EQ) then
  205. begin
  206. if (hdef.typ in [recorddef,variantdef,filedef,formaldef]) or
  207. is_object(hdef) or
  208. ((hdef.typ=arraydef) and
  209. not is_dynamic_array(hdef)) then
  210. Message1(type_e_invalid_default_value,FullTypeName(hdef,nil));
  211. vs:=tparavarsym(sc[0]);
  212. if sc.count>1 then
  213. Message(parser_e_default_value_only_one_para);
  214. if not(vs.varspez in [vs_value,vs_const,vs_constref]) then
  215. Message(parser_e_default_value_val_const);
  216. bt:=block_type;
  217. block_type:=bt_const;
  218. { prefix 'def' to the parameter name }
  219. defaultvalue:=ReadConstant('$def'+vs.name,vs.fileinfo,nodetype);
  220. block_type:=bt;
  221. if assigned(defaultvalue) then
  222. begin
  223. include(defaultvalue.symoptions,sp_internal);
  224. pd.parast.insert(defaultvalue);
  225. { check whether the default value is of the correct
  226. type }
  227. if compare_defs_ext(defaultvalue.constdef,hdef,nodetype,doconv,convpd,[])<=te_convert_operator then
  228. MessagePos2(defaultvalue.fileinfo,type_e_incompatible_types,FullTypeName(defaultvalue.constdef,hdef),FullTypeName(hdef,defaultvalue.constdef));
  229. end;
  230. defaultrequired:=true;
  231. end
  232. else
  233. begin
  234. if defaultrequired then
  235. Message1(parser_e_default_value_expected_for_para,vs.name);
  236. end;
  237. end;
  238. begin
  239. old_block_type:=block_type;
  240. explicit_paraloc:=false;
  241. consume(_LKLAMMER);
  242. { Delphi/Kylix supports nonsense like }
  243. { procedure p(); }
  244. if try_to_consume(_RKLAMMER) and
  245. not(m_tp7 in current_settings.modeswitches) then
  246. exit;
  247. { parsing a proc or procvar ? }
  248. currparast:=tparasymtable(pd.parast);
  249. { reset }
  250. sc:=TFPObjectList.create(false);
  251. defaultrequired:=false;
  252. paranr:=0;
  253. block_type:=bt_var;
  254. is_univ:=false;
  255. repeat
  256. parseprocvar:=pv_none;
  257. if try_to_consume(_VAR) then
  258. varspez:=vs_var
  259. else
  260. if try_to_consume(_CONST) then
  261. varspez:=vs_const
  262. else
  263. if (m_out in current_settings.modeswitches) and
  264. try_to_consume(_OUT) then
  265. varspez:=vs_out
  266. else
  267. if try_to_consume(_CONSTREF) then
  268. varspez:=vs_constref
  269. else
  270. if (m_mac in current_settings.modeswitches) and
  271. try_to_consume(_POINTPOINTPOINT) then
  272. begin
  273. include(pd.procoptions,po_varargs);
  274. break;
  275. end
  276. else
  277. if (m_nested_procvars in current_settings.modeswitches) and
  278. try_to_consume(_PROCEDURE) then
  279. begin
  280. parseprocvar:=pv_proc;
  281. varspez:=vs_const;
  282. end
  283. else
  284. if (m_nested_procvars in current_settings.modeswitches) and
  285. try_to_consume(_FUNCTION) then
  286. begin
  287. parseprocvar:=pv_func;
  288. varspez:=vs_const;
  289. end
  290. else
  291. varspez:=vs_value;
  292. defaultvalue:=nil;
  293. hdef:=nil;
  294. { read identifiers and insert with error type }
  295. sc.clear;
  296. repeat
  297. inc(paranr);
  298. vs:=cparavarsym.create(orgpattern,paranr*10,varspez,generrordef,[]);
  299. currparast.insert(vs);
  300. if assigned(vs.owner) then
  301. sc.add(vs)
  302. else
  303. vs.free;
  304. consume(_ID);
  305. until not try_to_consume(_COMMA);
  306. locationstr:='';
  307. { macpas anonymous procvar }
  308. if parseprocvar<>pv_none then
  309. begin
  310. { inline procvar definitions are always nested procvars }
  311. pv:=cprocvardef.create(normal_function_level+1);
  312. if token=_LKLAMMER then
  313. parse_parameter_dec(pv);
  314. if parseprocvar=pv_func then
  315. begin
  316. block_type:=bt_var_type;
  317. consume(_COLON);
  318. single_type(pv.returndef,[]);
  319. block_type:=bt_var;
  320. end;
  321. hdef:=pv;
  322. { possible proc directives }
  323. if check_proc_directive(true) then
  324. begin
  325. dummytype:=ctypesym.create('unnamed',hdef);
  326. parse_var_proc_directives(tsym(dummytype));
  327. dummytype.typedef:=nil;
  328. hdef.typesym:=nil;
  329. dummytype.free;
  330. end;
  331. { Add implicit hidden parameters and function result }
  332. handle_calling_convention(pv,hcc_default_actions_intf);
  333. {$ifdef jvm}
  334. { anonymous -> no name }
  335. jvm_create_procvar_class('',pv);
  336. {$endif}
  337. end
  338. else
  339. { read type declaration, force reading for value paras }
  340. if (token=_COLON) or (varspez=vs_value) then
  341. begin
  342. consume(_COLON);
  343. { check for an open array }
  344. need_array:=false;
  345. { bitpacked open array are not yet supported }
  346. if (token=_PACKED) and
  347. not(cs_bitpacking in current_settings.localswitches) then
  348. begin
  349. consume(_PACKED);
  350. need_array:=true;
  351. end;
  352. if (token=_ARRAY) or
  353. need_array then
  354. begin
  355. consume(_ARRAY);
  356. consume(_OF);
  357. { define range and type of range }
  358. hdef:=carraydef.create_openarray;
  359. { array of const ? }
  360. if (token=_CONST) and (m_objpas in current_settings.modeswitches) then
  361. begin
  362. consume(_CONST);
  363. srsym:=search_system_type('TVARREC');
  364. tarraydef(hdef).elementdef:=ttypesym(srsym).typedef;
  365. include(tarraydef(hdef).arrayoptions,ado_IsArrayOfConst);
  366. end
  367. else
  368. begin
  369. { define field type }
  370. if m_delphi in current_settings.modeswitches then
  371. stoptions:=[stoAllowSpecialization]
  372. else
  373. stoptions:=[];
  374. single_type(arrayelementdef,stoptions);
  375. tarraydef(hdef).elementdef:=arrayelementdef;
  376. end;
  377. end
  378. else
  379. begin
  380. if (m_mac in current_settings.modeswitches) then
  381. is_univ:=try_to_consume(_UNIV);
  382. if try_to_consume(_TYPE) then
  383. hdef:=ctypedformaltype
  384. else
  385. begin
  386. block_type:=bt_var_type;
  387. single_type(hdef,[stoAllowSpecialization]);
  388. block_type:=bt_var;
  389. end;
  390. { open string ? }
  391. if is_shortstring(hdef) then
  392. begin
  393. case varspez of
  394. vs_var,vs_out:
  395. begin
  396. { not 100% Delphi-compatible: type xstr=string[255] cannot
  397. become an openstring there, while here it can }
  398. if (cs_openstring in current_settings.moduleswitches) and
  399. (tstringdef(hdef).len=255) then
  400. hdef:=openshortstringtype
  401. end;
  402. vs_value:
  403. begin
  404. { value "openstring" parameters don't make sense (the
  405. original string can never be modified, so there's no
  406. use in passing its original length), so change these
  407. into regular shortstring parameters (seems to be what
  408. Delphi also does) }
  409. if is_open_string(hdef) then
  410. hdef:=cshortstringtype;
  411. end;
  412. else
  413. ;
  414. end;
  415. end;
  416. if (target_info.system in [system_powerpc_morphos,system_m68k_amiga]) then
  417. begin
  418. if (idtoken=_LOCATION) then
  419. begin
  420. consume(_LOCATION);
  421. locationstr:=cstringpattern;
  422. consume(_CSTRING);
  423. end
  424. else
  425. begin
  426. if explicit_paraloc then
  427. Message(parser_e_paraloc_all_paras);
  428. locationstr:='';
  429. end;
  430. end
  431. else
  432. locationstr:='';
  433. { default parameter }
  434. if (m_default_para in current_settings.modeswitches) then
  435. handle_default_para_value;
  436. end;
  437. end
  438. else
  439. hdef:=cformaltype;
  440. { File types are only allowed for var and out parameters }
  441. if (hdef.typ=filedef) and
  442. not(varspez in [vs_out,vs_var]) then
  443. CGMessage(cg_e_file_must_call_by_reference);
  444. { Dispinterfaces are restricted to using only automatable types }
  445. if (pd.typ=procdef) and is_dispinterface(tprocdef(pd).struct) and
  446. not is_automatable(hdef) then
  447. Message1(type_e_not_automatable,hdef.typename);
  448. { univ cannot be used with types whose size is not known at compile
  449. time }
  450. if is_univ and
  451. not is_valid_univ_para_type(hdef) then
  452. Message1(parser_e_invalid_univ_para,hdef.typename);
  453. for i:=0 to sc.count-1 do
  454. begin
  455. vs:=tparavarsym(sc[i]);
  456. vs.univpara:=is_univ;
  457. { update varsym }
  458. vs.vardef:=hdef;
  459. vs.defaultconstsym:=defaultvalue;
  460. if (target_info.system in [system_powerpc_morphos,system_m68k_amiga]) then
  461. begin
  462. if locationstr<>'' then
  463. begin
  464. if sc.count>1 then
  465. Message(parser_e_paraloc_only_one_para);
  466. if (paranr>1) and not(explicit_paraloc) then
  467. Message(parser_e_paraloc_all_paras);
  468. explicit_paraloc:=true;
  469. include(vs.varoptions,vo_has_explicit_paraloc);
  470. if not(paramanager.parseparaloc(vs,locationstr)) then
  471. message(parser_e_illegal_explicit_paraloc);
  472. end
  473. else
  474. if explicit_paraloc then
  475. Message(parser_e_paraloc_all_paras);
  476. end;
  477. end;
  478. until not try_to_consume(_SEMICOLON);
  479. if explicit_paraloc then
  480. include(pd.procoptions,po_explicitparaloc);
  481. { remove parasymtable from stack }
  482. sc.free;
  483. { reset object options }
  484. block_type:=old_block_type;
  485. consume(_RKLAMMER);
  486. end;
  487. function parse_proc_head(astruct:tabstractrecorddef;potype:tproctypeoption;isgeneric:boolean;genericdef:tdef;generictypelist:tfphashobjectlist;out pd:tprocdef):boolean;
  488. var
  489. hs : string;
  490. orgsp,sp,orgspnongen,spnongen : TIDString;
  491. dummysym,srsym : tsym;
  492. checkstack : psymtablestackitem;
  493. oldfilepos,
  494. classstartfilepos,
  495. procstartfilepos : tfileposinfo;
  496. i,
  497. index : longint;
  498. hadspecialize,
  499. firstpart,
  500. found,
  501. searchagain : boolean;
  502. st,
  503. genericst: TSymtable;
  504. aprocsym : tprocsym;
  505. popclass : integer;
  506. ImplIntf : TImplementedInterface;
  507. old_parse_generic : boolean;
  508. old_current_structdef: tabstractrecorddef;
  509. old_current_genericdef,
  510. old_current_specializedef: tstoreddef;
  511. lasttoken,lastidtoken: ttoken;
  512. genericparams : tfphashobjectlist;
  513. procedure parse_operator_name;
  514. begin
  515. if (lasttoken in [first_overloaded..last_overloaded]) then
  516. begin
  517. optoken:=token;
  518. end
  519. else
  520. begin
  521. case lasttoken of
  522. _CARET:
  523. Message1(parser_e_overload_operator_failed,'**');
  524. _ID:
  525. case lastidtoken of
  526. _ENUMERATOR:optoken:=_OP_ENUMERATOR;
  527. _EXPLICIT:optoken:=_OP_EXPLICIT;
  528. _INC:optoken:=_OP_INC;
  529. _DEC:optoken:=_OP_DEC;
  530. _INITIALIZE:optoken:=_OP_INITIALIZE;
  531. _FINALIZE:optoken:=_OP_FINALIZE;
  532. _ADDREF:optoken:=_OP_ADDREF;
  533. _COPY:optoken:=_OP_COPY;
  534. else
  535. if (m_delphi in current_settings.modeswitches) then
  536. case lastidtoken of
  537. _IMPLICIT:optoken:=_ASSIGNMENT;
  538. _NEGATIVE:optoken:=_MINUS;
  539. _POSITIVE:optoken:=_PLUS;
  540. _LOGICALNOT:optoken:=_OP_NOT;
  541. _IN:optoken:=_OP_IN;
  542. _EQUAL:optoken:=_EQ;
  543. _NOTEQUAL:optoken:=_NE;
  544. _GREATERTHAN:optoken:=_GT;
  545. _GREATERTHANOREQUAL:optoken:=_GTE;
  546. _LESSTHAN:optoken:=_LT;
  547. _LESSTHANOREQUAL:optoken:=_LTE;
  548. _ADD:optoken:=_PLUS;
  549. _SUBTRACT:optoken:=_MINUS;
  550. _MULTIPLY:optoken:=_STAR;
  551. _DIVIDE:optoken:=_SLASH;
  552. _INTDIVIDE:optoken:=_OP_DIV;
  553. _MODULUS:optoken:=_OP_MOD;
  554. _LEFTSHIFT:optoken:=_OP_SHL;
  555. _RIGHTSHIFT:optoken:=_OP_SHR;
  556. _LOGICALAND:optoken:=_OP_AND;
  557. _LOGICALOR:optoken:=_OP_OR;
  558. _LOGICALXOR:optoken:=_OP_XOR;
  559. _BITWISEAND:optoken:=_OP_AND;
  560. _BITWISEOR:optoken:=_OP_OR;
  561. _BITWISEXOR:optoken:=_OP_XOR;
  562. else
  563. Message1(parser_e_overload_operator_failed,'');
  564. end
  565. else
  566. Message1(parser_e_overload_operator_failed,'');
  567. end
  568. else
  569. Message1(parser_e_overload_operator_failed,'');
  570. end;
  571. end;
  572. sp:=overloaded_names[optoken];
  573. orgsp:=sp;
  574. spnongen:=sp;
  575. orgspnongen:=orgsp;
  576. end;
  577. procedure consume_proc_name;
  578. var
  579. s : string;
  580. i : longint;
  581. sym : ttypesym;
  582. begin
  583. lasttoken:=token;
  584. lastidtoken:=idtoken;
  585. if assigned(genericparams) then
  586. for i:=0 to genericparams.count-1 do
  587. begin
  588. sym:=ttypesym(genericparams[i]);
  589. if tstoreddef(sym.typedef).is_registered then
  590. begin
  591. sym.typedef.free;
  592. sym.typedef:=nil;
  593. end;
  594. sym.free;
  595. end;
  596. genericparams.free;
  597. genericparams:=nil;
  598. hadspecialize:=false;
  599. if potype=potype_operator then
  600. optoken:=NOTOKEN;
  601. if (potype=potype_operator) and (token<>_ID) then
  602. begin
  603. parse_operator_name;
  604. consume(token);
  605. end
  606. else
  607. begin
  608. sp:=pattern;
  609. orgsp:=orgpattern;
  610. spnongen:=sp;
  611. orgspnongen:=orgsp;
  612. if firstpart and
  613. not (m_delphi in current_settings.modeswitches) and
  614. (idtoken=_SPECIALIZE) then
  615. hadspecialize:=true;
  616. consume(_ID);
  617. if (isgeneric or (m_delphi in current_settings.modeswitches)) and
  618. (token in [_LT,_LSHARPBRACKET]) then
  619. begin
  620. consume(token);
  621. if token in [_GT,_RSHARPBRACKET] then
  622. message(type_e_type_id_expected)
  623. else
  624. begin
  625. genericparams:=parse_generic_parameters(true);
  626. if not assigned(genericparams) then
  627. internalerror(2015061201);
  628. if genericparams.count=0 then
  629. internalerror(2015061202);
  630. s:='';
  631. str(genericparams.count,s);
  632. spnongen:=sp;
  633. orgspnongen:=orgsp;
  634. sp:=sp+'$'+s;
  635. orgsp:=orgsp+'$'+s;
  636. end;
  637. if not try_to_consume(_GT) then
  638. consume(_RSHARPBRACKET);
  639. end;
  640. end;
  641. firstpart:=false;
  642. end;
  643. function search_object_name(sp:TIDString;gen_error:boolean):tsym;
  644. var
  645. storepos:tfileposinfo;
  646. srsymtable:TSymtable;
  647. begin
  648. storepos:=current_tokenpos;
  649. current_tokenpos:=procstartfilepos;
  650. searchsym(sp,result,srsymtable);
  651. if not assigned(result) then
  652. begin
  653. if gen_error then
  654. identifier_not_found(orgsp);
  655. result:=generrorsym;
  656. end;
  657. current_tokenpos:=storepos;
  658. end;
  659. procedure consume_generic_interface;
  660. var
  661. genparalist : tfpobjectlist;
  662. prettyname,
  663. specializename : ansistring;
  664. genname,
  665. ugenname : tidstring;
  666. gencount : string;
  667. begin
  668. consume(_LSHARPBRACKET);
  669. genparalist:=tfpobjectlist.create(false);
  670. if not parse_generic_specialization_types(genparalist,nil,prettyname,specializename) then
  671. srsym:=generrorsym
  672. else
  673. begin
  674. str(genparalist.count,gencount);
  675. genname:=sp+'$'+gencount;
  676. { ToDo: handle nested interfaces }
  677. genname:=generate_generic_name(genname,specializename,'');
  678. ugenname:=upper(genname);
  679. srsym:=search_object_name(ugenname,false);
  680. if not assigned(srsym) then
  681. begin
  682. Message1(type_e_generic_declaration_does_not_match,sp+'<'+prettyname+'>');
  683. srsym:=nil;
  684. exit;
  685. end;
  686. end;
  687. genparalist.free;
  688. consume(_RSHARPBRACKET);
  689. end;
  690. function handle_generic_interface:boolean;
  691. var
  692. i : longint;
  693. sym : ttypesym;
  694. typesrsym : tsym;
  695. typesrsymtable : tsymtable;
  696. specializename,
  697. prettyname: ansistring;
  698. error : boolean;
  699. genname,
  700. ugenname : tidstring;
  701. module : tmodule;
  702. begin
  703. result:=false;
  704. if not assigned(genericparams) then
  705. exit;
  706. specializename:='$';
  707. prettyname:='';
  708. error:=false;
  709. for i:=0 to genericparams.count-1 do
  710. begin
  711. sym:=ttypesym(genericparams[i]);
  712. { ToDo: position }
  713. if not searchsym(upper(sym.RealName),typesrsym,typesrsymtable) then
  714. begin
  715. message1(sym_e_id_not_found,sym.name);
  716. error:=true;
  717. continue;
  718. end;
  719. if typesrsym.typ<>typesym then
  720. begin
  721. message(type_e_type_id_expected);
  722. error:=true;
  723. continue;
  724. end;
  725. module:=find_module_from_symtable(ttypesym(typesrsym).typedef.owner);
  726. if not assigned(module) then
  727. internalerror(2016112803);
  728. specializename:=specializename+'_$'+hexstr(module.moduleid,8)+'$$'+ttypesym(typesrsym).typedef.unique_id_str;
  729. if i>0 then
  730. prettyname:=prettyname+',';
  731. prettyname:=prettyname+ttypesym(typesrsym).prettyname;
  732. end;
  733. result:=true;
  734. if error then
  735. begin
  736. srsym:=generrorsym;
  737. exit;
  738. end;
  739. { ToDo: handle nested interfaces }
  740. genname:=generate_generic_name(sp,specializename,'');
  741. ugenname:=upper(genname);
  742. srsym:=search_object_name(ugenname,false);
  743. if not assigned(srsym) then
  744. begin
  745. Message1(type_e_generic_declaration_does_not_match,sp+'<'+prettyname+'>');
  746. srsym:=generrorsym;
  747. end;
  748. end;
  749. procedure specialize_generic_interface;
  750. var
  751. node : tnode;
  752. begin
  753. node:=factor(false,[ef_type_only,ef_had_specialize]);
  754. if node.nodetype=typen then
  755. begin
  756. sp:=ttypenode(node).typedef.typesym.name;
  757. end
  758. else
  759. sp:='';
  760. end;
  761. function check_generic_parameters(def:tstoreddef):boolean;
  762. var
  763. i : longint;
  764. decltype,
  765. impltype : ttypesym;
  766. implname : tsymstr;
  767. begin
  768. result:=true;
  769. if not assigned(def.genericparas) then
  770. internalerror(2018090102);
  771. if not assigned(genericparams) then
  772. internalerror(2018090103);
  773. if def.genericparas.count<>genericparams.count then
  774. internalerror(2018090104);
  775. for i:=0 to def.genericparas.count-1 do
  776. begin
  777. decltype:=ttypesym(def.genericparas[i]);
  778. impltype:=ttypesym(genericparams[i]);
  779. implname:=upper(genericparams.nameofindex(i));
  780. if decltype.name<>implname then
  781. begin
  782. messagepos1(impltype.fileinfo,sym_e_generic_type_param_mismatch,impltype.realname);
  783. messagepos1(decltype.fileinfo,sym_e_generic_type_param_decl,decltype.realname);
  784. result:=false;
  785. end;
  786. if df_genconstraint in impltype.typedef.defoptions then
  787. begin
  788. messagepos(tstoreddef(impltype.typedef).genconstraintdata.fileinfo,parser_e_generic_constraints_not_allowed_here);
  789. result:=false;
  790. end;
  791. end;
  792. end;
  793. begin
  794. sp:='';
  795. orgsp:='';
  796. spnongen:='';
  797. orgspnongen:='';
  798. { Save the position where this procedure really starts }
  799. procstartfilepos:=current_tokenpos;
  800. old_parse_generic:=parse_generic;
  801. firstpart:=true;
  802. result:=false;
  803. pd:=nil;
  804. aprocsym:=nil;
  805. srsym:=nil;
  806. genericparams:=nil;
  807. hadspecialize:=false;
  808. if not assigned(genericdef) then
  809. begin
  810. consume_proc_name;
  811. { examine interface map: function/procedure iname.functionname=locfuncname }
  812. if assigned(astruct) and
  813. (astruct.typ=objectdef) and
  814. assigned(tobjectdef(astruct).ImplementedInterfaces) and
  815. (tobjectdef(astruct).ImplementedInterfaces.count>0) and
  816. (
  817. (token=_POINT) or
  818. (
  819. hadspecialize and
  820. (token=_ID)
  821. )
  822. ) then
  823. begin
  824. if hadspecialize and (token=_ID) then
  825. specialize_generic_interface;
  826. consume(_POINT);
  827. if hadspecialize or not handle_generic_interface then
  828. srsym:=search_object_name(sp,true);
  829. { qualifier is interface? }
  830. ImplIntf:=nil;
  831. if assigned(srsym) and
  832. (srsym.typ=typesym) and
  833. (ttypesym(srsym).typedef.typ=objectdef) then
  834. ImplIntf:=find_implemented_interface(tobjectdef(astruct),tobjectdef(ttypesym(srsym).typedef));
  835. if ImplIntf=nil then
  836. begin
  837. Message(parser_e_interface_id_expected);
  838. { error recovery }
  839. consume(_ID);
  840. if try_to_consume(_EQ) then
  841. consume(_ID);
  842. exit;
  843. end
  844. else
  845. { in case of a generic or specialized interface we need to use the
  846. name of the def instead of the symbol, so that always the correct
  847. name is used }
  848. if [df_generic,df_specialization]*ttypesym(srsym).typedef.defoptions<>[] then
  849. sp:=tobjectdef(ttypesym(srsym).typedef).objname^;
  850. { must be a directly implemented interface }
  851. if Assigned(ImplIntf.ImplementsGetter) then
  852. Message2(parser_e_implements_no_mapping,ImplIntf.IntfDef.typename,astruct.objrealname^);
  853. consume(_ID);
  854. { Create unique name <interface>.<method> }
  855. hs:=sp+'.'+pattern;
  856. consume(_EQ);
  857. if assigned(ImplIntf) and
  858. (token=_ID) then
  859. ImplIntf.AddMapping(hs,pattern);
  860. consume(_ID);
  861. result:=true;
  862. exit;
  863. end;
  864. if assigned(genericparams) and assigned(current_genericdef) then
  865. Message(parser_f_no_generic_inside_generic);
  866. { method ? }
  867. srsym:=nil;
  868. if not assigned(astruct) and
  869. (symtablestack.top.symtablelevel=main_program_level) and
  870. try_to_consume(_POINT) then
  871. begin
  872. repeat
  873. classstartfilepos:=procstartfilepos;
  874. searchagain:=false;
  875. { throw the error at the right location }
  876. oldfilepos:=current_filepos;
  877. current_filepos:=procstartfilepos;
  878. if not assigned(astruct) and not assigned(srsym) then
  879. srsym:=search_object_name(sp,true);
  880. current_filepos:=oldfilepos;
  881. { we need to check whether the names of the generic parameter
  882. types match with the one in the declaration of a class/record,
  883. but we need to do this before consume_proc_name frees the
  884. type parameters of the class part }
  885. if (srsym.typ=typesym) and
  886. (ttypesym(srsym).typedef.typ in [objectdef,recorddef]) and
  887. tstoreddef(ttypesym(srsym).typedef).is_generic and
  888. assigned(genericparams) then
  889. { this is recoverable, so no further action necessary }
  890. check_generic_parameters(tstoreddef(ttypesym(srsym).typedef));
  891. { consume proc name }
  892. procstartfilepos:=current_tokenpos;
  893. consume_proc_name;
  894. { qualifier is class name ? }
  895. if (srsym.typ=typesym) and
  896. (ttypesym(srsym).typedef.typ in [objectdef,recorddef]) then
  897. begin
  898. astruct:=tabstractrecorddef(ttypesym(srsym).typedef);
  899. if (token<>_POINT) then
  900. if (potype in [potype_class_constructor,potype_class_destructor]) then
  901. sp:=lower(sp)
  902. else
  903. if (potype=potype_operator) and (optoken=NOTOKEN) then
  904. parse_operator_name;
  905. srsym:=tsym(astruct.symtable.Find(sp));
  906. if assigned(srsym) then
  907. begin
  908. if srsym.typ=procsym then
  909. aprocsym:=tprocsym(srsym)
  910. else
  911. if (srsym.typ=typesym) and
  912. (ttypesym(srsym).typedef.typ in [objectdef,recorddef]) then
  913. begin
  914. searchagain:=true;
  915. consume(_POINT);
  916. end
  917. else
  918. begin
  919. { we use a different error message for tp7 so it looks more compatible }
  920. if (m_fpc in current_settings.modeswitches) then
  921. Message1(parser_e_overloaded_no_procedure,srsym.realname)
  922. else
  923. Message(parser_e_methode_id_expected);
  924. { rename the name to an unique name to avoid an
  925. error when inserting the symbol in the symtable }
  926. orgsp:=orgsp+'$'+tostr(current_filepos.line);
  927. end;
  928. end
  929. else
  930. begin
  931. MessagePos(procstartfilepos,parser_e_methode_id_expected);
  932. { recover by making it a normal procedure instead of method }
  933. astruct:=nil;
  934. end;
  935. end
  936. else
  937. MessagePos(classstartfilepos,parser_e_class_id_expected);
  938. until not searchagain;
  939. end
  940. else
  941. begin
  942. { check for constructor/destructor/class operators which are not allowed here }
  943. if (not parse_only) and
  944. ((potype in [potype_constructor,potype_destructor,
  945. potype_class_constructor,potype_class_destructor]) or
  946. ((potype=potype_operator) and (m_delphi in current_settings.modeswitches))) then
  947. Message(parser_e_only_methods_allowed);
  948. repeat
  949. { only 1 class constructor and destructor is allowed in the class and
  950. the check was already done with oo_has_class_constructor or
  951. oo_has_class_destructor -> skip searching
  952. (bug #28801) }
  953. if (potype in [potype_class_constructor,potype_class_destructor]) then
  954. break;
  955. searchagain:=false;
  956. current_tokenpos:=procstartfilepos;
  957. if (potype=potype_operator)and(optoken=NOTOKEN) then
  958. parse_operator_name;
  959. srsym:=tsym(symtablestack.top.Find(sp));
  960. { Also look in the globalsymtable if we didn't found
  961. the symbol in the localsymtable }
  962. if not assigned(srsym) and
  963. not(parse_only) and
  964. (symtablestack.top=current_module.localsymtable) and
  965. assigned(current_module.globalsymtable) then
  966. srsym:=tsym(current_module.globalsymtable.Find(sp));
  967. { Check if overloaded is a procsym }
  968. if assigned(srsym) then
  969. begin
  970. if srsym.typ=procsym then
  971. aprocsym:=tprocsym(srsym)
  972. else
  973. begin
  974. { when the other symbol is a unit symbol then hide the unit
  975. symbol, this is not supported in tp7 }
  976. if not(m_tp7 in current_settings.modeswitches) and
  977. (srsym.typ=unitsym) then
  978. begin
  979. HideSym(srsym);
  980. searchagain:=true;
  981. end
  982. else
  983. if (m_delphi in current_settings.modeswitches) and
  984. (srsym.typ=absolutevarsym) and
  985. ([vo_is_funcret,vo_is_result]*tabstractvarsym(srsym).varoptions=[vo_is_funcret]) then
  986. begin
  987. HideSym(srsym);
  988. searchagain:=true;
  989. end
  990. else if (srsym.typ=typesym) and
  991. (sp_generic_dummy in srsym.symoptions) and
  992. (ttypesym(srsym).typedef.typ=undefineddef) then
  993. begin
  994. { this is a generic dummy symbol that has not yet
  995. been used; so we rename the dummy symbol and continue
  996. as if nothing happened }
  997. hidesym(srsym);
  998. searchagain:=true;
  999. end
  1000. else
  1001. begin
  1002. { we use a different error message for tp7 so it looks more compatible }
  1003. if (m_fpc in current_settings.modeswitches) then
  1004. Message1(parser_e_overloaded_no_procedure,srsym.realname)
  1005. else
  1006. Message1(sym_e_duplicate_id,srsym.realname);
  1007. { rename the name to an unique name to avoid an
  1008. error when inserting the symbol in the symtable }
  1009. orgsp:=orgsp+'$'+tostr(current_filepos.line);
  1010. end;
  1011. end;
  1012. end;
  1013. until not searchagain;
  1014. end;
  1015. { test again if assigned, it can be reset to recover }
  1016. if not assigned(aprocsym) then
  1017. begin
  1018. { create a new procsym and set the real filepos }
  1019. current_tokenpos:=procstartfilepos;
  1020. { for operator we have only one procsym for each overloaded
  1021. operation }
  1022. if (potype=potype_operator) then
  1023. begin
  1024. aprocsym:=Tprocsym(symtablestack.top.Find(sp));
  1025. if aprocsym=nil then
  1026. aprocsym:=cprocsym.create('$'+sp);
  1027. end
  1028. else
  1029. if (potype in [potype_class_constructor,potype_class_destructor]) then
  1030. aprocsym:=cprocsym.create('$'+lower(sp))
  1031. else
  1032. aprocsym:=cprocsym.create(orgsp);
  1033. symtablestack.top.insert(aprocsym);
  1034. end;
  1035. end;
  1036. { to get the correct symtablelevel we must ignore ObjectSymtables }
  1037. st:=nil;
  1038. checkstack:=symtablestack.stack;
  1039. while assigned(checkstack) do
  1040. begin
  1041. st:=checkstack^.symtable;
  1042. if st.symtabletype in [staticsymtable,globalsymtable,localsymtable] then
  1043. break;
  1044. checkstack:=checkstack^.next;
  1045. end;
  1046. pd:=cprocdef.create(st.symtablelevel+1,not assigned(genericdef));
  1047. pd.struct:=astruct;
  1048. pd.procsym:=aprocsym;
  1049. pd.proctypeoption:=potype;
  1050. if assigned(genericparams) then
  1051. begin
  1052. include(pd.defoptions,df_generic);
  1053. { push the parameter symtable so that constraint definitions are added
  1054. there and not in the owner symtable }
  1055. symtablestack.push(pd.parast);
  1056. { register the parameters }
  1057. for i:=0 to genericparams.count-1 do
  1058. begin
  1059. ttypesym(genericparams[i]).register_sym;
  1060. tstoreddef(ttypesym(genericparams[i]).typedef).register_def;
  1061. end;
  1062. insert_generic_parameter_types(pd,nil,genericparams);
  1063. { the list is no longer required }
  1064. genericparams.free;
  1065. genericparams:=nil;
  1066. symtablestack.pop(pd.parast);
  1067. parse_generic:=true;
  1068. { also generate a dummy symbol if none exists already }
  1069. if assigned(astruct) then
  1070. dummysym:=tsym(astruct.symtable.find(spnongen))
  1071. else
  1072. begin
  1073. dummysym:=tsym(symtablestack.top.find(spnongen));
  1074. if not assigned(dummysym) and
  1075. (symtablestack.top=current_module.localsymtable) and
  1076. assigned(current_module.globalsymtable) then
  1077. dummysym:=tsym(current_module.globalsymtable.find(spnongen));
  1078. end;
  1079. if not assigned(dummysym) then
  1080. begin
  1081. dummysym:=ctypesym.create(orgspnongen,cundefineddef.create(true));
  1082. if assigned(astruct) then
  1083. astruct.symtable.insert(dummysym)
  1084. else
  1085. symtablestack.top.insert(dummysym);
  1086. end;
  1087. include(dummysym.symoptions,sp_generic_dummy);
  1088. { start token recorder for the declaration }
  1089. pd.init_genericdecl;
  1090. current_scanner.startrecordtokens(pd.genericdecltokenbuf);
  1091. end
  1092. else if assigned(genericdef) then
  1093. insert_generic_parameter_types(pd,tstoreddef(genericdef),generictypelist);
  1094. { methods inherit df_generic or df_specialization from the objectdef }
  1095. if assigned(pd.struct) and
  1096. (pd.parast.symtablelevel=normal_function_level) then
  1097. begin
  1098. if (df_generic in pd.struct.defoptions) then
  1099. begin
  1100. include(pd.defoptions,df_generic);
  1101. parse_generic:=true;
  1102. end;
  1103. if (df_specialization in pd.struct.defoptions) then
  1104. begin
  1105. if assigned(current_specializedef) then
  1106. begin
  1107. include(pd.defoptions,df_specialization);
  1108. { Find corresponding genericdef, we need it later to
  1109. replay the tokens to generate the body }
  1110. if not assigned(pd.struct.genericdef) then
  1111. internalerror(200512113);
  1112. genericst:=pd.struct.genericdef.GetSymtable(gs_record);
  1113. if not assigned(genericst) then
  1114. internalerror(200512114);
  1115. { when searching for the correct procdef to use as genericdef we need to ignore
  1116. everything except procdefs so that we can find the correct indices }
  1117. index:=0;
  1118. found:=false;
  1119. for i:=0 to pd.owner.deflist.count-1 do
  1120. begin
  1121. if tdef(pd.owner.deflist[i]).typ<>procdef then
  1122. continue;
  1123. if pd.owner.deflist[i]=pd then
  1124. begin
  1125. found:=true;
  1126. break;
  1127. end;
  1128. inc(index);
  1129. end;
  1130. if not found then
  1131. internalerror(2014052301);
  1132. for i:=0 to genericst.deflist.count-1 do
  1133. begin
  1134. if tdef(genericst.deflist[i]).typ<>procdef then
  1135. continue;
  1136. if index=0 then
  1137. pd.genericdef:=tstoreddef(genericst.deflist[i]);
  1138. dec(index);
  1139. end;
  1140. if not assigned(pd.genericdef) or
  1141. (pd.genericdef.typ<>procdef) then
  1142. internalerror(200512115);
  1143. end
  1144. else
  1145. Message(parser_e_explicit_method_implementation_for_specializations_not_allowed);
  1146. end;
  1147. end;
  1148. { methods need to be exported }
  1149. if assigned(astruct) and
  1150. (
  1151. (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) or
  1152. (symtablestack.top.symtablelevel=main_program_level)
  1153. ) then
  1154. include(pd.procoptions,po_global);
  1155. { symbol options that need to be kept per procdef }
  1156. pd.fileinfo:=procstartfilepos;
  1157. pd.visibility:=symtablestack.top.currentvisibility;
  1158. if symtablestack.top.currentlyoptional then
  1159. include(pd.procoptions,po_optional);
  1160. { parse parameters }
  1161. if token=_LKLAMMER then
  1162. begin
  1163. old_current_structdef:=nil;
  1164. old_current_genericdef:=current_genericdef;
  1165. old_current_specializedef:=nil;
  1166. { Add ObjectSymtable to be able to find nested type definitions }
  1167. popclass:=0;
  1168. if assigned(pd.struct) and
  1169. (pd.parast.symtablelevel>=normal_function_level) and
  1170. not(symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then
  1171. begin
  1172. popclass:=push_nested_hierarchy(pd.struct);
  1173. old_current_structdef:=current_structdef;
  1174. old_current_specializedef:=current_specializedef;
  1175. current_structdef:=pd.struct;
  1176. if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
  1177. current_genericdef:=current_structdef;
  1178. if assigned(current_structdef) and (df_specialization in current_structdef.defoptions) then
  1179. current_specializedef:=current_structdef;
  1180. end;
  1181. if pd.is_generic then
  1182. current_genericdef:=pd;
  1183. { Add parameter symtable }
  1184. if pd.parast.symtabletype<>staticsymtable then
  1185. symtablestack.push(pd.parast);
  1186. parse_parameter_dec(pd);
  1187. if pd.parast.symtabletype<>staticsymtable then
  1188. symtablestack.pop(pd.parast);
  1189. current_genericdef:=old_current_genericdef;
  1190. if popclass>0 then
  1191. begin
  1192. current_structdef:=old_current_structdef;
  1193. current_specializedef:=old_current_specializedef;
  1194. dec(popclass,pop_nested_hierarchy(pd.struct));
  1195. if popclass<>0 then
  1196. internalerror(201011260); // 11 nov 2010 index 0
  1197. end;
  1198. end;
  1199. parse_generic:=old_parse_generic;
  1200. result:=true;
  1201. end;
  1202. procedure parse_proc_dec_finish(pd:tprocdef;isclassmethod:boolean;astruct:tabstractrecorddef);
  1203. var
  1204. locationstr: string;
  1205. i: integer;
  1206. found: boolean;
  1207. procedure read_returndef(pd: tprocdef);
  1208. var
  1209. popclass: integer;
  1210. old_parse_generic: boolean;
  1211. old_current_structdef: tabstractrecorddef;
  1212. old_current_genericdef,
  1213. old_current_specializedef: tstoreddef;
  1214. begin
  1215. old_parse_generic:=parse_generic;
  1216. { Add ObjectSymtable to be able to find generic type definitions }
  1217. popclass:=0;
  1218. old_current_structdef:=nil;
  1219. old_current_genericdef:=current_genericdef;
  1220. old_current_specializedef:=current_specializedef;
  1221. current_genericdef:=nil;
  1222. current_specializedef:=nil;
  1223. if assigned(pd.struct) and
  1224. (pd.parast.symtablelevel>=normal_function_level) and
  1225. not (symtablestack.top.symtabletype in [ObjectSymtable,recordsymtable]) then
  1226. begin
  1227. popclass:=push_nested_hierarchy(pd.struct);
  1228. old_current_structdef:=current_structdef;
  1229. current_structdef:=pd.struct;
  1230. end;
  1231. if df_generic in pd.defoptions then
  1232. begin
  1233. if pd.is_generic then
  1234. current_genericdef:=pd
  1235. else if assigned(pd.struct) then
  1236. current_genericdef:=pd.struct
  1237. else
  1238. internalerror(2016090202);
  1239. end;
  1240. if df_specialization in pd.defoptions then
  1241. begin
  1242. if pd.is_specialization then
  1243. current_specializedef:=pd
  1244. else if assigned(pd.struct) then
  1245. current_specializedef:=pd.struct
  1246. else
  1247. internalerror(2016090203);
  1248. end;
  1249. parse_generic:=(df_generic in pd.defoptions);
  1250. if pd.is_generic or pd.is_specialization then
  1251. symtablestack.push(pd.parast);
  1252. single_type(pd.returndef,[stoAllowSpecialization]);
  1253. // Issue #24863, enabled only for the main progra commented out for now because it breaks building of RTL and needs extensive
  1254. // testing and/or RTL patching.
  1255. {
  1256. if ((pd.returndef=cvarianttype) or (pd.returndef=colevarianttype)) and
  1257. not(cs_compilesystem in current_settings.moduleswitches) then
  1258. include(current_module.moduleflags,mf_uses_variants);
  1259. }
  1260. if is_dispinterface(pd.struct) and not is_automatable(pd.returndef) then
  1261. Message1(type_e_not_automatable,pd.returndef.typename);
  1262. if pd.is_generic or pd.is_specialization then
  1263. symtablestack.pop(pd.parast);
  1264. if popclass>0 then
  1265. begin
  1266. current_structdef:=old_current_structdef;
  1267. dec(popclass,pop_nested_hierarchy(pd.struct));
  1268. if popclass<>0 then
  1269. internalerror(201012020);
  1270. end;
  1271. current_genericdef:=old_current_genericdef;
  1272. current_specializedef:=old_current_specializedef;
  1273. parse_generic:=old_parse_generic;
  1274. end;
  1275. begin
  1276. locationstr:='';
  1277. case pd.proctypeoption of
  1278. potype_procedure:
  1279. begin
  1280. pd.returndef:=voidtype;
  1281. if isclassmethod then
  1282. include(pd.procoptions,po_classmethod);
  1283. end;
  1284. potype_function:
  1285. begin
  1286. if try_to_consume(_COLON) then
  1287. begin
  1288. read_returndef(pd);
  1289. if (target_info.system in [system_m68k_amiga]) then
  1290. begin
  1291. if (idtoken=_LOCATION) then
  1292. begin
  1293. if po_explicitparaloc in pd.procoptions then
  1294. begin
  1295. consume(_LOCATION);
  1296. locationstr:=cstringpattern;
  1297. consume(_CSTRING);
  1298. end
  1299. else
  1300. { I guess this needs a new message... (KB) }
  1301. Message(parser_e_paraloc_all_paras);
  1302. end
  1303. else
  1304. begin
  1305. if po_explicitparaloc in pd.procoptions then
  1306. { assign default locationstr, if none specified }
  1307. { and we've arguments with explicit paraloc }
  1308. locationstr:='D0';
  1309. end;
  1310. end;
  1311. end
  1312. else
  1313. begin
  1314. if (
  1315. parse_only and
  1316. not(is_interface(pd.struct))
  1317. ) or
  1318. (m_repeat_forward in current_settings.modeswitches) then
  1319. begin
  1320. consume(_COLON);
  1321. consume_all_until(_SEMICOLON);
  1322. end;
  1323. end;
  1324. if isclassmethod then
  1325. include(pd.procoptions,po_classmethod);
  1326. end;
  1327. potype_constructor,
  1328. potype_class_constructor:
  1329. begin
  1330. if not isclassmethod and
  1331. assigned(pd) and
  1332. assigned(pd.struct) then
  1333. begin
  1334. { Set return type, class constructors return the
  1335. created instance, object constructors return boolean }
  1336. if is_class(pd.struct) or
  1337. is_record(pd.struct) or
  1338. is_javaclass(pd.struct) then
  1339. pd.returndef:=pd.struct
  1340. else
  1341. if is_objectpascal_helper(pd.struct) then
  1342. pd.returndef:=tobjectdef(pd.struct).extendeddef
  1343. else
  1344. {$ifdef CPU64bitaddr}
  1345. pd.returndef:=bool64type;
  1346. {$else CPU64bitaddr}
  1347. pd.returndef:=bool32type;
  1348. {$endif CPU64bitaddr}
  1349. end
  1350. else
  1351. pd.returndef:=voidtype;
  1352. end;
  1353. potype_class_destructor,
  1354. potype_destructor:
  1355. begin
  1356. if assigned(pd) then
  1357. pd.returndef:=voidtype;
  1358. end;
  1359. potype_operator:
  1360. begin
  1361. { operators always need to be searched in all units (that
  1362. contain operators) }
  1363. include(pd.procoptions,po_overload);
  1364. pd.procsym.owner.includeoption(sto_has_operator);
  1365. if pd.parast.symtablelevel>normal_function_level then
  1366. Message(parser_e_no_local_operator);
  1367. if isclassmethod then
  1368. begin
  1369. include(pd.procoptions,po_classmethod);
  1370. { any class operator is also static }
  1371. include(pd.procoptions,po_staticmethod);
  1372. end;
  1373. if token<>_ID then
  1374. begin
  1375. if not(m_result in current_settings.modeswitches) then
  1376. consume(_ID);
  1377. end
  1378. else
  1379. begin
  1380. pd.resultname:=stringdup(orgpattern);
  1381. consume(_ID);
  1382. end;
  1383. { operators without result (management operators) }
  1384. if optoken in [_OP_INITIALIZE, _OP_FINALIZE, _OP_ADDREF, _OP_COPY] then
  1385. begin
  1386. { single var parameter to point the record }
  1387. if (optoken in [_OP_INITIALIZE, _OP_FINALIZE, _OP_ADDREF]) and
  1388. (
  1389. (pd.parast.SymList.Count<>1) or
  1390. (tparavarsym(pd.parast.SymList[0]).vardef<>pd.struct) or
  1391. (tparavarsym(pd.parast.SymList[0]).varspez<>vs_var)
  1392. ) then
  1393. Message(parser_e_overload_impossible)
  1394. { constref (source) and var (dest) parameter to point the records }
  1395. else if (optoken=_OP_COPY) and
  1396. (
  1397. (pd.parast.SymList.Count<>2) or
  1398. (tparavarsym(pd.parast.SymList[0]).vardef<>pd.struct) or
  1399. (tparavarsym(pd.parast.SymList[0]).varspez<>vs_constref) or
  1400. (tparavarsym(pd.parast.SymList[1]).vardef<>pd.struct) or
  1401. (tparavarsym(pd.parast.SymList[1]).varspez<>vs_var)
  1402. ) then
  1403. Message(parser_e_overload_impossible);
  1404. trecordsymtable(pd.procsym.Owner).includemanagementoperator(
  1405. token2managementoperator(optoken));
  1406. pd.returndef:=voidtype
  1407. end
  1408. else
  1409. if not try_to_consume(_COLON) then
  1410. begin
  1411. consume(_COLON);
  1412. pd.returndef:=generrordef;
  1413. consume_all_until(_SEMICOLON);
  1414. end
  1415. else
  1416. begin
  1417. read_returndef(pd);
  1418. { check that class operators have either return type of structure or }
  1419. { at least one argument of that type }
  1420. if (po_classmethod in pd.procoptions) and
  1421. (pd.returndef <> pd.struct) then
  1422. begin
  1423. found:=false;
  1424. for i := 0 to pd.parast.SymList.Count - 1 do
  1425. if tparavarsym(pd.parast.SymList[i]).vardef=pd.struct then
  1426. begin
  1427. found:=true;
  1428. break;
  1429. end;
  1430. if not found then
  1431. if assigned(pd.struct) then
  1432. Message1(parser_e_at_least_one_argument_must_be_of_type,pd.struct.RttiName)
  1433. else
  1434. MessagePos(pd.fileinfo,type_e_type_id_expected);
  1435. end;
  1436. if not assigned(pd.struct) or assigned(astruct) then
  1437. begin
  1438. if (optoken in [_ASSIGNMENT,_OP_EXPLICIT]) and
  1439. equal_defs(pd.returndef,tparavarsym(pd.parast.SymList[0]).vardef) and
  1440. (pd.returndef.typ<>undefineddef) and (tparavarsym(pd.parast.SymList[0]).vardef.typ<>undefineddef) then
  1441. message(parser_e_no_such_assignment)
  1442. else if not isoperatoracceptable(pd,optoken) then
  1443. Message(parser_e_overload_impossible);
  1444. end;
  1445. end;
  1446. end;
  1447. else
  1448. internalerror(2015052202);
  1449. end;
  1450. if (pd.proccalloption in cdecl_pocalls) and
  1451. (pd.paras.count>0) and
  1452. is_array_of_const(tparavarsym(pd.paras[pd.paras.count-1]).vardef) then
  1453. begin
  1454. include(pd.procoptions,po_variadic);
  1455. end;
  1456. { file types can't be function results }
  1457. if assigned(pd) and
  1458. (pd.returndef.typ=filedef) then
  1459. message(parser_e_illegal_function_result);
  1460. { support procedure proc stdcall export; }
  1461. if not(check_proc_directive(false)) then
  1462. begin
  1463. if (token=_COLON) and not(Assigned(pd) and is_void(pd.returndef)) then
  1464. begin
  1465. message(parser_e_field_not_allowed_here);
  1466. consume_all_until(_SEMICOLON);
  1467. end;
  1468. consume(_SEMICOLON);
  1469. end;
  1470. if locationstr<>'' then
  1471. begin
  1472. if not(paramanager.parsefuncretloc(pd,upper(locationstr))) then
  1473. { I guess this needs a new message... (KB) }
  1474. message(parser_e_illegal_explicit_paraloc);
  1475. end;
  1476. end;
  1477. function parse_proc_dec(isclassmethod:boolean;astruct:tabstractrecorddef;isgeneric:boolean):tprocdef;
  1478. var
  1479. pd : tprocdef;
  1480. old_block_type : tblock_type;
  1481. recover : boolean;
  1482. procedure finish_intf_mapping;
  1483. begin
  1484. if token=_COLON then
  1485. begin
  1486. message(parser_e_field_not_allowed_here);
  1487. consume_all_until(_SEMICOLON);
  1488. end;
  1489. consume(_SEMICOLON);
  1490. end;
  1491. begin
  1492. pd:=nil;
  1493. recover:=false;
  1494. case token of
  1495. _FUNCTION :
  1496. begin
  1497. consume(_FUNCTION);
  1498. if parse_proc_head(astruct,potype_function,isgeneric,nil,nil,pd) then
  1499. begin
  1500. { pd=nil when it is a interface mapping }
  1501. if assigned(pd) then
  1502. parse_proc_dec_finish(pd,isclassmethod,astruct)
  1503. else
  1504. finish_intf_mapping;
  1505. end
  1506. else
  1507. begin
  1508. { recover }
  1509. consume(_COLON);
  1510. consume_all_until(_SEMICOLON);
  1511. recover:=true;
  1512. end;
  1513. end;
  1514. _PROCEDURE :
  1515. begin
  1516. consume(_PROCEDURE);
  1517. if parse_proc_head(astruct,potype_procedure,isgeneric,nil,nil,pd) then
  1518. begin
  1519. { pd=nil when it is an interface mapping }
  1520. if assigned(pd) then
  1521. parse_proc_dec_finish(pd,isclassmethod,astruct)
  1522. else
  1523. finish_intf_mapping;
  1524. end
  1525. else
  1526. recover:=true;
  1527. end;
  1528. _CONSTRUCTOR :
  1529. begin
  1530. consume(_CONSTRUCTOR);
  1531. if isclassmethod then
  1532. recover:=not parse_proc_head(astruct,potype_class_constructor,false,nil,nil,pd)
  1533. else
  1534. recover:=not parse_proc_head(astruct,potype_constructor,false,nil,nil,pd);
  1535. if not recover then
  1536. parse_proc_dec_finish(pd,isclassmethod,astruct);
  1537. end;
  1538. _DESTRUCTOR :
  1539. begin
  1540. consume(_DESTRUCTOR);
  1541. if isclassmethod then
  1542. recover:=not parse_proc_head(astruct,potype_class_destructor,false,nil,nil,pd)
  1543. else
  1544. recover:=not parse_proc_head(astruct,potype_destructor,false,nil,nil,pd);
  1545. if not recover then
  1546. parse_proc_dec_finish(pd,isclassmethod,astruct);
  1547. end;
  1548. else
  1549. if (token=_OPERATOR) or
  1550. (isclassmethod and (idtoken=_OPERATOR)) then
  1551. begin
  1552. { we need to set the block type to bt_body, so that operator names
  1553. like ">", "=>" or "<>" are parsed correctly instead of e.g.
  1554. _LSHARPBRACKET and _RSHARPBRACKET for "<>" }
  1555. old_block_type:=block_type;
  1556. block_type:=bt_body;
  1557. consume(_OPERATOR);
  1558. parse_proc_head(astruct,potype_operator,false,nil,nil,pd);
  1559. block_type:=old_block_type;
  1560. if assigned(pd) then
  1561. parse_proc_dec_finish(pd,isclassmethod,astruct)
  1562. else
  1563. begin
  1564. { recover }
  1565. try_to_consume(_ID);
  1566. consume(_COLON);
  1567. consume_all_until(_SEMICOLON);
  1568. recover:=true;
  1569. end;
  1570. end;
  1571. end;
  1572. if recover and not(check_proc_directive(false)) then
  1573. begin
  1574. if (token=_COLON) and not(Assigned(pd) and is_void(pd.returndef)) then
  1575. begin
  1576. message(parser_e_field_not_allowed_here);
  1577. consume_all_until(_SEMICOLON);
  1578. end;
  1579. consume(_SEMICOLON);
  1580. end;
  1581. { we've parsed the final semicolon, so stop recording tokens }
  1582. if assigned(pd) and
  1583. (df_generic in pd.defoptions) and
  1584. assigned(pd.genericdecltokenbuf) then
  1585. current_scanner.stoprecordtokens;
  1586. result:=pd;
  1587. end;
  1588. function parse_record_method_dec(astruct: tabstractrecorddef; is_classdef: boolean;hadgeneric:boolean): tprocdef;
  1589. var
  1590. oldparse_only: boolean;
  1591. begin
  1592. oldparse_only:=parse_only;
  1593. parse_only:=true;
  1594. result:=parse_proc_dec(is_classdef,astruct,hadgeneric);
  1595. { this is for error recovery as well as forward }
  1596. { interface mappings, i.e. mapping to a method }
  1597. { which isn't declared yet }
  1598. if assigned(result) then
  1599. begin
  1600. parse_record_proc_directives(result);
  1601. { since records have no inheritance, don't allow non-static
  1602. class methods. Delphi does the same. }
  1603. if (result.proctypeoption<>potype_operator) and
  1604. is_classdef and
  1605. not (po_staticmethod in result.procoptions) then
  1606. MessagePos(result.fileinfo, parser_e_class_methods_only_static_in_records);
  1607. // we can't add hidden params here because record is not yet defined
  1608. // and therefore record size which has influence on paramter passing rules may change too
  1609. // look at record_dec to see where calling conventions are applied (issue #0021044)
  1610. handle_calling_convention(result,hcc_default_actions_intf_struct);
  1611. { add definition to procsym }
  1612. proc_add_definition(result);
  1613. if result.is_generic then
  1614. astruct.symtable.includeoption(sto_has_generic);
  1615. end;
  1616. maybe_parse_hint_directives(result);
  1617. parse_only:=oldparse_only;
  1618. end;
  1619. {****************************************************************************
  1620. Procedure directive handlers
  1621. ****************************************************************************}
  1622. procedure pd_compilerproc(pd:tabstractprocdef);
  1623. var
  1624. v : Tconstexprint;
  1625. begin
  1626. { check for optional syssym index }
  1627. if try_to_consume(_COLON) then
  1628. begin
  1629. v:=get_intconst;
  1630. if (v<int64(low(longint))) or (v>int64(high(longint))) then
  1631. message3(type_e_range_check_error_bounds,tostr(v),tostr(low(longint)),tostr(high(longint)))
  1632. else if not assigned(tsyssym.find_by_number(longint(v.svalue))) then
  1633. message1(parser_e_invalid_internal_function_index,tostr(v))
  1634. else
  1635. tprocdef(pd).extnumber:=longint(v.svalue);
  1636. end;
  1637. end;
  1638. procedure pd_far(pd:tabstractprocdef);
  1639. begin
  1640. pd.declared_far;
  1641. end;
  1642. procedure pd_near(pd:tabstractprocdef);
  1643. begin
  1644. pd.declared_near;
  1645. end;
  1646. procedure pd_export(pd:tabstractprocdef);
  1647. begin
  1648. if pd.typ<>procdef then
  1649. internalerror(200304264);
  1650. if assigned(tprocdef(pd).struct) then
  1651. Message(parser_e_methods_dont_be_export);
  1652. if pd.parast.symtablelevel>normal_function_level then
  1653. Message(parser_e_dont_nest_export);
  1654. end;
  1655. procedure pd_forward(pd:tabstractprocdef);
  1656. begin
  1657. if pd.typ<>procdef then
  1658. internalerror(200304265);
  1659. tprocdef(pd).forwarddef:=true;
  1660. end;
  1661. procedure pd_alias(pd:tabstractprocdef);
  1662. begin
  1663. if pd.typ<>procdef then
  1664. internalerror(200304266);
  1665. consume(_COLON);
  1666. tprocdef(pd).aliasnames.insert(get_stringconst);
  1667. include(pd.procoptions,po_has_public_name);
  1668. end;
  1669. procedure pd_public(pd:tabstractprocdef);
  1670. begin
  1671. if pd.typ<>procdef then
  1672. internalerror(200304266);
  1673. if try_to_consume(_NAME) then
  1674. begin
  1675. tprocdef(pd).aliasnames.insert(get_stringconst);
  1676. include(pd.procoptions,po_has_public_name);
  1677. end;
  1678. end;
  1679. procedure pd_asmname(pd:tabstractprocdef);
  1680. begin
  1681. if pd.typ<>procdef then
  1682. internalerror(200304267);
  1683. if token=_CCHAR then
  1684. begin
  1685. tprocdef(pd).aliasnames.insert(target_info.Cprefix+pattern);
  1686. consume(_CCHAR)
  1687. end
  1688. else
  1689. begin
  1690. tprocdef(pd).aliasnames.insert(target_info.Cprefix+cstringpattern);
  1691. consume(_CSTRING);
  1692. end;
  1693. { we don't need anything else }
  1694. tprocdef(pd).forwarddef:=false;
  1695. end;
  1696. procedure pd_internconst(pd:tabstractprocdef);
  1697. var v:Tconstexprint;
  1698. begin
  1699. if pd.typ<>procdef then
  1700. internalerror(200304268);
  1701. consume(_COLON);
  1702. v:=get_intconst;
  1703. if (v<int64(low(longint))) or (v>int64(high(longint))) then
  1704. message3(type_e_range_check_error_bounds,tostr(v),tostr(low(longint)),tostr(high(longint)))
  1705. else
  1706. Tprocdef(pd).extnumber:=longint(v.svalue);
  1707. end;
  1708. procedure pd_internproc(pd:tabstractprocdef);
  1709. var v:Tconstexprint;
  1710. begin
  1711. if pd.typ<>procdef then
  1712. internalerror(200304268);
  1713. consume(_COLON);
  1714. v:=get_intconst;
  1715. if (v<int64(low(longint))) or (v>int64(high(longint))) then
  1716. message3(type_e_range_check_error_bounds,tostr(v),tostr(low(longint)),tostr(high(longint)))
  1717. else
  1718. Tprocdef(pd).extnumber:=longint(v.svalue);
  1719. { the proc is defined }
  1720. tprocdef(pd).forwarddef:=false;
  1721. end;
  1722. procedure pd_interrupt(pd:tabstractprocdef);
  1723. begin
  1724. if pd.parast.symtablelevel>normal_function_level then
  1725. Message(parser_e_dont_nest_interrupt);
  1726. end;
  1727. procedure pd_abstract(pd:tabstractprocdef);
  1728. begin
  1729. if pd.typ<>procdef then
  1730. internalerror(200304269);
  1731. if is_objectpascal_helper(tprocdef(pd).struct) then
  1732. Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_ABSTRACT].str);
  1733. if assigned(tprocdef(pd).struct) and
  1734. (oo_is_sealed in tprocdef(pd).struct.objectoptions) then
  1735. Message(parser_e_sealed_class_cannot_have_abstract_methods)
  1736. else if (po_virtualmethod in pd.procoptions) then
  1737. begin
  1738. include(pd.procoptions,po_abstractmethod);
  1739. { one more abstract method }
  1740. inc(tobjectdef(pd.owner.defowner).abstractcnt);
  1741. end
  1742. else
  1743. Message(parser_e_only_virtual_methods_abstract);
  1744. { the method is defined }
  1745. tprocdef(pd).forwarddef:=false;
  1746. end;
  1747. procedure pd_final(pd:tabstractprocdef);
  1748. begin
  1749. if pd.typ<>procdef then
  1750. internalerror(200910170);
  1751. if is_objectpascal_helper(tprocdef(pd).struct) and
  1752. (m_objfpc in current_settings.modeswitches) then
  1753. Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_FINAL].str);
  1754. if (po_virtualmethod in pd.procoptions) or
  1755. (is_javaclass(tprocdef(pd).struct) and
  1756. (po_classmethod in pd.procoptions)) then
  1757. include(pd.procoptions,po_finalmethod)
  1758. else
  1759. Message(parser_e_only_virtual_methods_final);
  1760. end;
  1761. procedure pd_enumerator(pd:tabstractprocdef);
  1762. begin
  1763. if pd.typ<>procdef then
  1764. internalerror(200910250);
  1765. if (token = _ID) then
  1766. begin
  1767. if pattern='MOVENEXT' then
  1768. begin
  1769. if oo_has_enumerator_movenext in tprocdef(pd).struct.objectoptions then
  1770. message(parser_e_only_one_enumerator_movenext);
  1771. pd.calcparas;
  1772. if (pd.proctypeoption = potype_function) and is_boolean(pd.returndef) and
  1773. (pd.minparacount = 0) then
  1774. begin
  1775. include(tprocdef(pd).struct.objectoptions, oo_has_enumerator_movenext);
  1776. include(pd.procoptions,po_enumerator_movenext);
  1777. end
  1778. else
  1779. Message(parser_e_enumerator_movenext_is_not_valid)
  1780. end
  1781. else
  1782. Message1(parser_e_invalid_enumerator_identifier, pattern);
  1783. consume(token);
  1784. end
  1785. else
  1786. Message(parser_e_enumerator_identifier_required);
  1787. end;
  1788. procedure pd_virtual(pd:tabstractprocdef);
  1789. {$ifdef WITHDMT}
  1790. var
  1791. pt : tnode;
  1792. {$endif WITHDMT}
  1793. begin
  1794. if (not assigned(pd.owner.defowner) or
  1795. not is_java_class_or_interface(tdef(pd.owner.defowner))) and
  1796. (po_external in pd.procoptions) then
  1797. Message2(parser_e_proc_dir_conflict,'EXTERNAL','"VIRTUAL"');
  1798. if pd.typ<>procdef then
  1799. internalerror(2003042610);
  1800. if (pd.proctypeoption=potype_constructor) and
  1801. is_object(tprocdef(pd).struct) then
  1802. Message(parser_e_constructor_cannot_be_not_virtual);
  1803. if pd.is_generic then
  1804. message(parser_e_genfuncs_cannot_be_virtual);
  1805. if is_objectpascal_helper(tprocdef(pd).struct) and
  1806. (m_objfpc in current_settings.modeswitches) then
  1807. Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_VIRTUAL].str);
  1808. {$ifdef WITHDMT}
  1809. if is_object(tprocdef(pd).struct) and
  1810. (token<>_SEMICOLON) then
  1811. begin
  1812. { any type of parameter is allowed here! }
  1813. pt:=comp_expr(true);
  1814. if is_constintnode(pt) then
  1815. begin
  1816. include(pd.procoptions,po_msgint);
  1817. pd.messageinf.i:=pt.value;
  1818. end
  1819. else
  1820. Message(parser_e_ill_msg_expr);
  1821. disposetree(pt);
  1822. end;
  1823. {$endif WITHDMT}
  1824. end;
  1825. procedure pd_dispid(pd:tabstractprocdef);
  1826. var pt:Tnode;
  1827. begin
  1828. if pd.typ<>procdef then
  1829. internalerror(200604301);
  1830. pt:=comp_expr([ef_accept_equal]);
  1831. if is_constintnode(pt) then
  1832. if (Tordconstnode(pt).value<int64(low(longint))) or (Tordconstnode(pt).value>int64(high(longint))) then
  1833. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(longint)),tostr(high(longint)))
  1834. else
  1835. Tprocdef(pd).dispid:=Tordconstnode(pt).value.svalue
  1836. else
  1837. message(parser_e_dispid_must_be_ord_const);
  1838. pt.free;
  1839. end;
  1840. procedure pd_static(pd:tabstractprocdef);
  1841. begin
  1842. if pd.typ<>procdef then
  1843. internalerror(2013032001);
  1844. if not assigned(tprocdef(pd).struct) then
  1845. internalerror(2013032002);
  1846. include(tprocdef(pd).procsym.symoptions,sp_static);
  1847. { "static" is not allowed for operators or normal methods (except in objects) }
  1848. if (pd.proctypeoption=potype_operator) or
  1849. (
  1850. not (po_classmethod in pd.procoptions) and
  1851. not is_object(tprocdef(pd).struct)
  1852. )
  1853. then
  1854. Message1(parser_e_dir_not_allowed,arraytokeninfo[_STATIC].str);
  1855. include(pd.procoptions,po_staticmethod);
  1856. end;
  1857. procedure pd_override(pd:tabstractprocdef);
  1858. begin
  1859. if pd.typ<>procdef then
  1860. internalerror(2003042611);
  1861. if is_objectpascal_helper(tprocdef(pd).struct) then
  1862. begin
  1863. if m_objfpc in current_settings.modeswitches then
  1864. Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_OVERRIDE].str)
  1865. end
  1866. else if not(is_class_or_interface_or_objc_or_java(tprocdef(pd).struct)) then
  1867. Message(parser_e_no_object_override)
  1868. else if is_objccategory(tprocdef(pd).struct) then
  1869. Message(parser_e_no_category_override)
  1870. else if (po_external in pd.procoptions) and
  1871. not is_objc_class_or_protocol(tprocdef(pd).struct) and
  1872. not is_cppclass(tprocdef(pd).struct) and
  1873. not is_java_class_or_interface(tprocdef(pd).struct) then
  1874. Message2(parser_e_proc_dir_conflict,'OVERRIDE','"EXTERNAL"');
  1875. end;
  1876. procedure pd_overload(pd:tabstractprocdef);
  1877. begin
  1878. if pd.typ<>procdef then
  1879. internalerror(2003042612);
  1880. include(tprocdef(pd).procsym.symoptions,sp_has_overloaded);
  1881. end;
  1882. procedure pd_message(pd:tabstractprocdef);
  1883. var
  1884. pt : tnode;
  1885. paracnt : longint;
  1886. begin
  1887. if pd.typ<>procdef then
  1888. internalerror(2003042613);
  1889. if is_objectpascal_helper(tprocdef(pd).struct) then
  1890. begin
  1891. if m_objfpc in current_settings.modeswitches then
  1892. Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_MESSAGE].str);
  1893. end
  1894. else
  1895. if not is_class(tprocdef(pd).struct) and
  1896. not is_objc_class_or_protocol(tprocdef(pd).struct) then
  1897. Message(parser_e_msg_only_for_classes);
  1898. if ([po_msgstr,po_msgint]*pd.procoptions)<>[] then
  1899. Message(parser_e_multiple_messages);
  1900. { check parameter type }
  1901. if not is_objc_class_or_protocol(tprocdef(pd).struct) then
  1902. begin
  1903. if po_external in pd.procoptions then
  1904. Message2(parser_e_proc_dir_conflict,'MESSAGE','"EXTERNAL"');
  1905. paracnt:=0;
  1906. pd.parast.SymList.ForEachCall(@check_msg_para,@paracnt);
  1907. if paracnt<>1 then
  1908. Message(parser_e_ill_msg_param);
  1909. end;
  1910. pt:=comp_expr([ef_accept_equal]);
  1911. { message is 1-character long }
  1912. if is_constcharnode(pt) then
  1913. begin
  1914. include(pd.procoptions,po_msgstr);
  1915. tprocdef(pd).messageinf.str:=stringdup(chr(byte(tordconstnode(pt).value.uvalue and $FF)));
  1916. end
  1917. else if pt.nodetype=stringconstn then
  1918. begin
  1919. include(pd.procoptions,po_msgstr);
  1920. if (tstringconstnode(pt).len>255) then
  1921. Message(parser_e_message_string_too_long);
  1922. tprocdef(pd).messageinf.str:=stringdup(tstringconstnode(pt).value_str);
  1923. end
  1924. else
  1925. if is_constintnode(pt) and
  1926. (is_class(tprocdef(pd).struct) or
  1927. is_objectpascal_helper(tprocdef(pd).struct)) then
  1928. begin
  1929. include(pd.procoptions,po_msgint);
  1930. if (Tordconstnode(pt).value<int64(low(Tprocdef(pd).messageinf.i))) or
  1931. (Tordconstnode(pt).value>int64(high(Tprocdef(pd).messageinf.i))) then
  1932. message3(type_e_range_check_error_bounds,tostr(Tordconstnode(pt).value),tostr(low(Tprocdef(pd).messageinf.i)),tostr(high(Tprocdef(pd).messageinf.i)))
  1933. else
  1934. Tprocdef(pd).messageinf.i:=tordconstnode(pt).value.svalue;
  1935. end
  1936. else
  1937. Message(parser_e_ill_msg_expr);
  1938. { check whether the selector name is valid in case of Objective-C }
  1939. if (po_msgstr in pd.procoptions) and
  1940. is_objc_class_or_protocol(tprocdef(pd).struct) and
  1941. not objcvalidselectorname(@tprocdef(pd).messageinf.str^[1],length(tprocdef(pd).messageinf.str^)) then
  1942. Message1(type_e_invalid_objc_selector_name,tprocdef(pd).messageinf.str^);
  1943. pt.free;
  1944. end;
  1945. procedure pd_reintroduce(pd:tabstractprocdef);
  1946. begin
  1947. if pd.typ<>procdef then
  1948. internalerror(200401211);
  1949. if is_objectpascal_helper(tprocdef(pd).struct) then
  1950. begin
  1951. if m_objfpc in current_settings.modeswitches then
  1952. Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_REINTRODUCE].str);
  1953. end
  1954. else
  1955. if not(is_class_or_interface_or_object(tprocdef(pd).struct)) and
  1956. not(is_objccategory(tprocdef(pd).struct)) and
  1957. not(is_javaclass(tprocdef(pd).struct)) then
  1958. Message(parser_e_no_object_reintroduce);
  1959. end;
  1960. procedure pd_syscall(pd:tabstractprocdef);
  1961. procedure include_po_syscall;
  1962. var
  1963. syscall: psyscallinfo;
  1964. begin
  1965. case target_info.system of
  1966. system_arm_palmos,
  1967. system_m68k_palmos,
  1968. system_m68k_atari,
  1969. system_m68k_amiga,
  1970. system_powerpc_amiga:
  1971. include(pd.procoptions,get_default_syscall);
  1972. system_powerpc_morphos,
  1973. system_arm_aros,
  1974. system_i386_aros,
  1975. system_x86_64_aros:
  1976. begin
  1977. syscall:=get_syscall_by_token(idtoken);
  1978. if assigned(syscall) then
  1979. begin
  1980. if target_info.system in syscall^.validon then
  1981. begin
  1982. consume(idtoken);
  1983. include(pd.procoptions,syscall^.procoption);
  1984. end
  1985. end
  1986. else
  1987. include(pd.procoptions,get_default_syscall);
  1988. end;
  1989. else
  1990. internalerror(2019050526);
  1991. end;
  1992. end;
  1993. function po_syscall_to_varoptions: tvaroptions;
  1994. begin
  1995. result:=[vo_is_syscall_lib,vo_is_hidden_para];
  1996. if ([po_syscall_legacy,po_syscall_basereg,po_syscall_basenone] * tprocdef(pd).procoptions) <> [] then
  1997. include(result,vo_has_explicit_paraloc);
  1998. end;
  1999. function po_syscall_to_regname: string;
  2000. begin
  2001. if po_syscall_legacy in tprocdef(pd).procoptions then
  2002. result:='a6'
  2003. { let nobase on MorphOS store the libbase in r12 as well, because
  2004. we will need the libbase anyway during the call generation }
  2005. else if (po_syscall_basenone in tprocdef(pd).procoptions) and
  2006. (target_info.system = system_powerpc_morphos) then
  2007. result:='r12'
  2008. else if po_syscall_basereg in tprocdef(pd).procoptions then
  2009. begin
  2010. case target_info.system of
  2011. system_i386_aros:
  2012. result:='eax';
  2013. system_x86_64_aros:
  2014. result:='rax';
  2015. system_powerpc_morphos:
  2016. result:='r12';
  2017. else
  2018. internalerror(2016090201);
  2019. end;
  2020. end
  2021. else
  2022. internalerror(2016090101);
  2023. end;
  2024. {$if defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)}
  2025. const
  2026. syscall_paranr: array[boolean] of aint =
  2027. ( paranr_syscall_lib_last, paranr_syscall_lib_first );
  2028. var
  2029. vs : tparavarsym;
  2030. sym : tsym;
  2031. symtable : TSymtable;
  2032. v: Tconstexprint;
  2033. vo: tvaroptions;
  2034. paranr: aint;
  2035. {$endif defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)}
  2036. begin
  2037. if (pd.typ<>procdef) and (target_info.system <> system_powerpc_amiga) then
  2038. internalerror(2003042614);
  2039. tprocdef(pd).forwarddef:=false;
  2040. {$if defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)}
  2041. include_po_syscall;
  2042. if target_info.system in [system_arm_palmos, system_m68k_palmos] then
  2043. begin
  2044. v:=get_intconst;
  2045. tprocdef(pd).extnumber:=longint(v.svalue);
  2046. if ((v<0) or (v>high(word))) then
  2047. message(parser_e_range_check_error);
  2048. if try_to_consume(_COMMA) then
  2049. begin
  2050. v:=get_intconst;
  2051. if ((v<0) or (v>high(word))) then
  2052. message(parser_e_range_check_error);
  2053. tprocdef(pd).import_nr:=longint(v.svalue);
  2054. include(pd.procoptions,po_syscall_has_importnr);
  2055. end;
  2056. exit;
  2057. end;
  2058. if target_info.system = system_m68k_atari then
  2059. begin
  2060. v:=get_intconst;
  2061. if ((v<0) or (v>15)) then
  2062. message(parser_e_range_check_error)
  2063. else
  2064. tprocdef(pd).extnumber:=longint(v.svalue);
  2065. v:=get_intconst;
  2066. if ((v<0) or (v>high(smallint))) then
  2067. message(parser_e_range_check_error)
  2068. else
  2069. tprocdef(pd).import_nr:=longint(v.svalue);
  2070. exit;
  2071. end;
  2072. if consume_sym(sym,symtable) then
  2073. if (sym.typ=staticvarsym) and
  2074. ((tabstractvarsym(sym).vardef.typ=pointerdef) or
  2075. is_32bitint(tabstractvarsym(sym).vardef)) then
  2076. begin
  2077. include(pd.procoptions,po_syscall_has_libsym);
  2078. tcpuprocdef(pd).libsym:=sym;
  2079. vo:=po_syscall_to_varoptions;
  2080. paranr:=syscall_paranr[po_syscall_basefirst in tprocdef(pd).procoptions];
  2081. vs:=cparavarsym.create('$syscalllib',paranr,vs_value,tabstractvarsym(sym).vardef,vo);
  2082. if vo_has_explicit_paraloc in vo then
  2083. if not paramanager.parseparaloc(vs,po_syscall_to_regname) then
  2084. internalerror(2016120301);
  2085. pd.parast.insert(vs);
  2086. end
  2087. else
  2088. Message(parser_e_32bitint_or_pointer_variable_expected);
  2089. paramanager.create_funcretloc_info(pd,calleeside);
  2090. paramanager.create_funcretloc_info(pd,callerside);
  2091. v:=get_intconst;
  2092. if (v<low(Tprocdef(pd).extnumber)) or (v>high(Tprocdef(pd).extnumber)) then
  2093. message3(type_e_range_check_error_bounds,tostr(v),tostr(low(Tprocdef(pd).extnumber)),tostr(high(Tprocdef(pd).extnumber)))
  2094. else
  2095. if target_info.system in [system_arm_aros,system_i386_aros,system_x86_64_aros] then
  2096. Tprocdef(pd).extnumber:=v.uvalue * sizeof(pint)
  2097. else
  2098. Tprocdef(pd).extnumber:=v.uvalue;
  2099. {$endif defined(powerpc) or defined(m68k) or defined(i386) or defined(x86_64) or defined(arm)}
  2100. end;
  2101. procedure pd_external(pd:tabstractprocdef);
  2102. {
  2103. If import_dll=nil the procedure is assumed to be in another
  2104. object file. In that object file it should have the name to
  2105. which import_name is pointing to. Otherwise, the procedure is
  2106. assumed to be in the DLL to which import_dll is pointing to. In
  2107. that case either import_nr<>0 or import_name<>nil is true, so
  2108. the procedure is either imported by number or by name. (DM)
  2109. }
  2110. var
  2111. hs : string;
  2112. v:Tconstexprint;
  2113. is_java_external: boolean;
  2114. begin
  2115. if pd.typ<>procdef then
  2116. internalerror(2003042615);
  2117. { Allow specifying a separate external name for methods in external Java
  2118. because its identifier naming constraints are laxer than FPC's
  2119. (e.g., case sensitive).
  2120. Limitation: only allows specifying the symbol name and not the package name,
  2121. and only for external classes/interfaces }
  2122. is_java_external:=
  2123. (pd.typ=procdef) and
  2124. is_java_class_or_interface(tdef(pd.owner.defowner)) and
  2125. (oo_is_external in tobjectdef(pd.owner.defowner).objectoptions);
  2126. with tprocdef(pd) do
  2127. begin
  2128. forwarddef:=false;
  2129. { forbid local external procedures }
  2130. if parast.symtablelevel>normal_function_level then
  2131. Message(parser_e_no_local_proc_external);
  2132. { If the procedure should be imported from a DLL, a constant string follows.
  2133. This isn't really correct, an contant string expression follows
  2134. so we check if an semicolon follows, else a string constant have to
  2135. follow (FK) }
  2136. if not is_java_external and
  2137. not(token=_SEMICOLON) and not(idtoken=_NAME) then
  2138. begin
  2139. { Always add library prefix and suffix to create an uniform name }
  2140. hs:=get_stringconst;
  2141. if ExtractFileExt(hs)='' then
  2142. hs:=ChangeFileExt(hs,target_info.sharedlibext);
  2143. if Copy(hs,1,length(target_info.sharedlibprefix))<>target_info.sharedlibprefix then
  2144. hs:=target_info.sharedlibprefix+hs;
  2145. { the JVM expects java/lang/Object rather than java.lang.Object }
  2146. if target_info.system in systems_jvm then
  2147. Replace(hs,'.','/');
  2148. import_dll:=stringdup(hs);
  2149. include(procoptions,po_has_importdll);
  2150. if (idtoken=_NAME) then
  2151. begin
  2152. consume(_NAME);
  2153. import_name:=stringdup(get_stringconst);
  2154. include(procoptions,po_has_importname);
  2155. if import_name^='' then
  2156. message(parser_e_empty_import_name);
  2157. end;
  2158. if (idtoken=_INDEX) then
  2159. begin
  2160. {After the word index follows the index number in the DLL.}
  2161. consume(_INDEX);
  2162. v:=get_intconst;
  2163. if (v<int64(low(import_nr))) or (v>int64(high(import_nr))) then
  2164. message(parser_e_range_check_error)
  2165. else
  2166. import_nr:=longint(v.svalue);
  2167. end;
  2168. { default is to used the realname of the procedure }
  2169. if (import_nr=0) and not assigned(import_name) then
  2170. begin
  2171. import_name:=stringdup(procsym.realname);
  2172. include(procoptions,po_has_importname);
  2173. end;
  2174. end
  2175. else
  2176. begin
  2177. if (idtoken=_NAME) or
  2178. is_java_external then
  2179. begin
  2180. consume(_NAME);
  2181. import_name:=stringdup(get_stringconst);
  2182. include(procoptions,po_has_importname);
  2183. if import_name^='' then
  2184. message(parser_e_empty_import_name);
  2185. end;
  2186. end;
  2187. end;
  2188. end;
  2189. procedure pd_weakexternal(pd:tabstractprocdef);
  2190. begin
  2191. if not(target_info.system in systems_weak_linking) then
  2192. message(parser_e_weak_external_not_supported)
  2193. else
  2194. pd_external(pd);
  2195. end;
  2196. procedure pd_winapi(pd:tabstractprocdef);
  2197. begin
  2198. if not(target_info.system in systems_all_windows+[system_i386_nativent]) then
  2199. pd.proccalloption:=pocall_cdecl
  2200. else
  2201. pd.proccalloption:=pocall_stdcall;
  2202. end;
  2203. procedure pd_hardfloat(pd:tabstractprocdef);
  2204. begin
  2205. if
  2206. {$if defined(arm)}
  2207. (current_settings.fputype=fpu_soft) or
  2208. {$endif defined(arm)}
  2209. (cs_fp_emulation in current_settings.moduleswitches) then
  2210. message(parser_e_cannot_use_hardfloat_in_a_softfloat_environment);
  2211. end;
  2212. type
  2213. pd_handler=procedure(pd:tabstractprocdef);
  2214. proc_dir_rec=record
  2215. idtok : ttoken;
  2216. pd_flags : tpdflags;
  2217. handler : pd_handler;
  2218. pocall : tproccalloption;
  2219. pooption : tprocoptions;
  2220. mutexclpocall : tproccalloptions;
  2221. mutexclpotype : tproctypeoptions;
  2222. mutexclpo : tprocoptions;
  2223. end;
  2224. const
  2225. {Should contain the number of procedure directives we support.}
  2226. num_proc_directives=53;
  2227. proc_direcdata:array[1..num_proc_directives] of proc_dir_rec=
  2228. (
  2229. (
  2230. idtok:_ABSTRACT;
  2231. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord,pd_javaclass];
  2232. handler : @pd_abstract;
  2233. pocall : pocall_none;
  2234. pooption : [po_abstractmethod];
  2235. mutexclpocall : [pocall_internproc];
  2236. mutexclpotype : [];
  2237. mutexclpo : [po_exports,po_interrupt,po_inline]
  2238. ),(
  2239. idtok:_ALIAS;
  2240. pd_flags : [pd_implemen,pd_body,pd_notobjintf];
  2241. handler : @pd_alias;
  2242. pocall : pocall_none;
  2243. pooption : [];
  2244. mutexclpocall : [];
  2245. mutexclpotype : [];
  2246. mutexclpo : [po_external,po_inline]
  2247. ),(
  2248. idtok:_ASMNAME;
  2249. pd_flags : [pd_interface,pd_implemen,pd_notobjintf];
  2250. handler : @pd_asmname;
  2251. pocall : pocall_cdecl;
  2252. pooption : [po_external];
  2253. mutexclpocall : [pocall_internproc];
  2254. mutexclpotype : [];
  2255. mutexclpo : [po_external,po_inline]
  2256. ),(
  2257. idtok:_ASSEMBLER;
  2258. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  2259. handler : nil;
  2260. pocall : pocall_none;
  2261. pooption : [po_assembler];
  2262. mutexclpocall : [];
  2263. mutexclpotype : [];
  2264. mutexclpo : [po_external]
  2265. ),(
  2266. idtok:_C; {same as cdecl for mode mac}
  2267. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2268. handler : nil;
  2269. pocall : pocall_cdecl;
  2270. pooption : [];
  2271. mutexclpocall : [];
  2272. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2273. mutexclpo : [po_assembler,po_external]
  2274. ),(
  2275. idtok:_CBLOCK;
  2276. pd_flags : [pd_procvar];
  2277. handler : nil;
  2278. pocall : pocall_none;
  2279. pooption : [po_is_block];
  2280. mutexclpocall : [];
  2281. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2282. mutexclpo : [po_assembler,po_external]
  2283. ),(
  2284. idtok:_CDECL;
  2285. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2286. handler : nil;
  2287. pocall : pocall_cdecl;
  2288. pooption : [];
  2289. mutexclpocall : [];
  2290. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2291. mutexclpo : [po_assembler,po_external]
  2292. ),(
  2293. idtok:_DISPID;
  2294. pd_flags : [pd_dispinterface];
  2295. handler : @pd_dispid;
  2296. pocall : pocall_none;
  2297. pooption : [po_dispid];
  2298. mutexclpocall : [pocall_internproc];
  2299. mutexclpotype : [potype_constructor,potype_destructor,potype_operator,potype_class_constructor,potype_class_destructor];
  2300. mutexclpo : [po_interrupt,po_external,po_inline]
  2301. ),(
  2302. idtok:_DYNAMIC;
  2303. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord];
  2304. handler : @pd_virtual;
  2305. pocall : pocall_none;
  2306. pooption : [po_virtualmethod];
  2307. mutexclpocall : [pocall_internproc];
  2308. mutexclpotype : [potype_class_constructor,potype_class_destructor];
  2309. mutexclpo : [po_exports,po_interrupt,po_external,po_overridingmethod,po_inline]
  2310. ),(
  2311. idtok:_EXPORT;
  2312. pd_flags : [pd_body,pd_interface,pd_implemen,pd_notobjintf,pd_notrecord,pd_nothelper];
  2313. handler : @pd_export;
  2314. pocall : pocall_none;
  2315. pooption : [po_exports,po_global];
  2316. mutexclpocall : [pocall_internproc];
  2317. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2318. mutexclpo : [po_external,po_interrupt,po_inline]
  2319. ),(
  2320. idtok:_EXTERNAL;
  2321. pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf,pd_cppobject,pd_notrecord,pd_nothelper,pd_javaclass,pd_intfjava];
  2322. handler : @pd_external;
  2323. pocall : pocall_none;
  2324. pooption : [po_external];
  2325. mutexclpocall : [pocall_syscall];
  2326. { allowed for external cpp classes }
  2327. mutexclpotype : [{potype_constructor,potype_destructor}potype_class_constructor,potype_class_destructor];
  2328. mutexclpo : [po_public,po_exports,po_interrupt,po_assembler,po_inline]
  2329. ),(
  2330. idtok:_FAR;
  2331. pd_flags : [pd_implemen,pd_body,pd_interface,pd_procvar,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
  2332. handler : @pd_far;
  2333. pocall : pocall_none;
  2334. pooption : [];
  2335. mutexclpocall : [pocall_internproc];
  2336. mutexclpotype : [];
  2337. mutexclpo : [po_inline]
  2338. ),(
  2339. idtok:_FAR16;
  2340. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar,pd_notobject,pd_notrecord,pd_nothelper];
  2341. handler : nil;
  2342. pocall : pocall_far16;
  2343. pooption : [];
  2344. mutexclpocall : [];
  2345. mutexclpotype : [];
  2346. mutexclpo : [po_external]
  2347. ),(
  2348. idtok:_FINAL;
  2349. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord,pd_javaclass];
  2350. handler : @pd_final;
  2351. pocall : pocall_none;
  2352. pooption : [po_finalmethod];
  2353. mutexclpocall : [pocall_internproc];
  2354. mutexclpotype : [];
  2355. mutexclpo : [po_exports,po_interrupt,po_inline]
  2356. ),(
  2357. idtok:_FORWARD;
  2358. pd_flags : [pd_implemen,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
  2359. handler : @pd_forward;
  2360. pocall : pocall_none;
  2361. pooption : [];
  2362. mutexclpocall : [pocall_internproc];
  2363. mutexclpotype : [];
  2364. mutexclpo : [po_external,po_inline]
  2365. ),(
  2366. idtok:_OLDFPCCALL;
  2367. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2368. handler : nil;
  2369. pocall : pocall_oldfpccall;
  2370. pooption : [];
  2371. mutexclpocall : [];
  2372. mutexclpotype : [];
  2373. mutexclpo : []
  2374. ),(
  2375. idtok:_INLINE;
  2376. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  2377. handler : nil;
  2378. pocall : pocall_none;
  2379. pooption : [po_inline];
  2380. mutexclpocall : [pocall_safecall];
  2381. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2382. mutexclpo : [po_noinline,po_exports,po_external,po_interrupt,po_virtualmethod,po_iocheck]
  2383. ),(
  2384. idtok:_NOINLINE;
  2385. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  2386. handler : nil;
  2387. pocall : pocall_none;
  2388. pooption : [po_noinline];
  2389. mutexclpocall : [];
  2390. mutexclpotype : [];
  2391. mutexclpo : [po_inline,po_external]
  2392. ),(
  2393. idtok:_INTERNCONST;
  2394. pd_flags : [pd_interface,pd_body,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
  2395. handler : @pd_internconst;
  2396. pocall : pocall_none;
  2397. pooption : [po_internconst];
  2398. mutexclpocall : [];
  2399. mutexclpotype : [potype_operator];
  2400. mutexclpo : []
  2401. ),(
  2402. idtok:_INTERNPROC;
  2403. pd_flags : [pd_interface,pd_implemen,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
  2404. handler : @pd_internproc;
  2405. pocall : pocall_internproc;
  2406. pooption : [];
  2407. mutexclpocall : [];
  2408. mutexclpotype : [potype_constructor,potype_destructor,potype_operator,potype_class_constructor,potype_class_destructor];
  2409. mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_virtualmethod]
  2410. ),(
  2411. idtok:_INTERRUPT;
  2412. pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
  2413. handler : @pd_interrupt;
  2414. {$ifdef i386}
  2415. pocall : pocall_oldfpccall;
  2416. {$else i386}
  2417. pocall : pocall_stdcall;
  2418. {$endif i386}
  2419. pooption : [po_interrupt];
  2420. mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,pocall_stdcall,pocall_mwpascal,
  2421. pocall_pascal,pocall_far16,pocall_oldfpccall,pocall_sysv_abi_cdecl,pocall_ms_abi_cdecl];
  2422. mutexclpotype : [potype_constructor,potype_destructor,potype_operator,potype_class_constructor,potype_class_destructor];
  2423. mutexclpo : [po_external,po_inline,po_exports]
  2424. ),(
  2425. idtok:_IOCHECK;
  2426. pd_flags : [pd_implemen,pd_body,pd_notobjintf];
  2427. handler : nil;
  2428. pocall : pocall_none;
  2429. pooption : [po_iocheck];
  2430. mutexclpocall : [pocall_internproc];
  2431. mutexclpotype : [];
  2432. mutexclpo : [po_external]
  2433. ),(
  2434. idtok:_LOCAL;
  2435. pd_flags : [pd_implemen,pd_body];
  2436. handler : nil;
  2437. pocall : pocall_none;
  2438. pooption : [po_kylixlocal];
  2439. mutexclpocall : [pocall_internproc,pocall_far16];
  2440. mutexclpotype : [];
  2441. mutexclpo : [po_external,po_exports]
  2442. ),(
  2443. idtok:_MESSAGE;
  2444. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass,pd_objcprot,pd_notrecord];
  2445. handler : @pd_message;
  2446. pocall : pocall_none;
  2447. pooption : []; { can be po_msgstr or po_msgint }
  2448. mutexclpocall : [pocall_internproc];
  2449. mutexclpotype : [potype_constructor,potype_destructor,potype_operator,potype_class_constructor,potype_class_destructor];
  2450. mutexclpo : [po_interrupt,po_inline]
  2451. ),(
  2452. idtok:_MWPASCAL;
  2453. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2454. handler : nil;
  2455. pocall : pocall_mwpascal;
  2456. pooption : [];
  2457. mutexclpocall : [];
  2458. mutexclpotype : [];
  2459. mutexclpo : []
  2460. ),(
  2461. idtok:_NEAR;
  2462. pd_flags : [pd_implemen,pd_body,pd_procvar,pd_notobjintf,pd_notrecord,pd_nothelper];
  2463. handler : @pd_near;
  2464. pocall : pocall_none;
  2465. pooption : [];
  2466. mutexclpocall : [pocall_internproc];
  2467. mutexclpotype : [];
  2468. mutexclpo : []
  2469. ),(
  2470. idtok:_NORETURN;
  2471. pd_flags : [pd_implemen,pd_interface,pd_body,pd_notobjintf];
  2472. handler : nil;
  2473. pocall : pocall_none;
  2474. pooption : [po_noreturn];
  2475. mutexclpocall : [];
  2476. mutexclpotype : [potype_constructor,potype_destructor,potype_operator,potype_class_constructor,potype_class_destructor];
  2477. mutexclpo : [po_interrupt,po_virtualmethod,po_iocheck]
  2478. ),(
  2479. idtok:_NOSTACKFRAME;
  2480. pd_flags : [pd_implemen,pd_body,pd_procvar,pd_notobjintf];
  2481. handler : nil;
  2482. pocall : pocall_none;
  2483. pooption : [po_nostackframe];
  2484. mutexclpocall : [pocall_internproc];
  2485. mutexclpotype : [];
  2486. mutexclpo : []
  2487. ),(
  2488. idtok:_OVERLOAD;
  2489. pd_flags : [pd_implemen,pd_interface,pd_body,pd_javaclass,pd_intfjava,pd_objcclass,pd_objcprot];
  2490. handler : @pd_overload;
  2491. pocall : pocall_none;
  2492. pooption : [po_overload];
  2493. mutexclpocall : [pocall_internproc];
  2494. mutexclpotype : [];
  2495. mutexclpo : []
  2496. ),(
  2497. idtok:_OVERRIDE;
  2498. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass,pd_javaclass,pd_intfjava,pd_notrecord];
  2499. handler : @pd_override;
  2500. pocall : pocall_none;
  2501. pooption : [po_overridingmethod,po_virtualmethod];
  2502. mutexclpocall : [pocall_internproc];
  2503. mutexclpotype : [];
  2504. mutexclpo : [po_exports,po_interrupt,po_virtualmethod,po_inline]
  2505. ),(
  2506. idtok:_PASCAL;
  2507. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2508. handler : nil;
  2509. pocall : pocall_pascal;
  2510. pooption : [];
  2511. mutexclpocall : [];
  2512. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2513. mutexclpo : [po_external]
  2514. ),(
  2515. idtok:_PUBLIC;
  2516. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobject,pd_notobjintf,pd_notrecord,pd_nothelper];
  2517. handler : @pd_public;
  2518. pocall : pocall_none;
  2519. pooption : [po_public,po_global];
  2520. mutexclpocall : [pocall_internproc];
  2521. mutexclpotype : [];
  2522. mutexclpo : [po_external,po_inline]
  2523. ),(
  2524. idtok:_REGISTER;
  2525. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2526. handler : nil;
  2527. pocall : pocall_register;
  2528. pooption : [];
  2529. mutexclpocall : [];
  2530. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2531. mutexclpo : [po_external]
  2532. ),(
  2533. idtok:_REINTRODUCE;
  2534. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_objcclass,pd_notrecord,pd_javaclass];
  2535. handler : @pd_reintroduce;
  2536. pocall : pocall_none;
  2537. pooption : [po_reintroduce];
  2538. mutexclpocall : [pocall_internproc];
  2539. mutexclpotype : [];
  2540. mutexclpo : [po_external,po_interrupt,po_exports,po_overridingmethod,po_inline]
  2541. ),(
  2542. idtok:_SAFECALL;
  2543. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2544. handler : nil;
  2545. pocall : pocall_safecall;
  2546. pooption : [];
  2547. mutexclpocall : [];
  2548. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2549. mutexclpo : [po_external]
  2550. ),(
  2551. idtok:_SOFTFLOAT;
  2552. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2553. handler : nil;
  2554. pocall : pocall_softfloat;
  2555. pooption : [];
  2556. mutexclpocall : [];
  2557. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2558. { it's available with po_external because the libgcc floating point routines on the arm
  2559. uses this calling convention }
  2560. mutexclpo : []
  2561. ),(
  2562. idtok:_STATIC;
  2563. pd_flags : [pd_interface,pd_implemen,pd_body,pd_object,pd_record,pd_javaclass,pd_notobjintf];
  2564. handler : @pd_static;
  2565. pocall : pocall_none;
  2566. pooption : [po_staticmethod];
  2567. mutexclpocall : [pocall_internproc];
  2568. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2569. mutexclpo : [po_interrupt,po_exports,po_virtualmethod]
  2570. ),(
  2571. idtok:_STDCALL;
  2572. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2573. handler : nil;
  2574. pocall : pocall_stdcall;
  2575. pooption : [];
  2576. mutexclpocall : [];
  2577. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2578. mutexclpo : [po_external]
  2579. ),(
  2580. idtok:_SYSCALL;
  2581. { Different kind of syscalls are valid for AOS68k, AOSPPC and MOS. }
  2582. { FIX ME!!! MorphOS/AOS68k pd_flags should be:
  2583. pd_interface, pd_implemen, pd_notobject, pd_notobjintf (KB) }
  2584. pd_flags : [pd_interface,pd_implemen,pd_procvar];
  2585. handler : @pd_syscall;
  2586. pocall : pocall_syscall;
  2587. pooption : [];
  2588. mutexclpocall : [];
  2589. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2590. mutexclpo : [po_external,po_assembler,po_interrupt,po_exports]
  2591. ),(
  2592. idtok:_VIRTUAL;
  2593. pd_flags : [pd_interface,pd_object,pd_notobjintf,pd_notrecord,pd_javaclass];
  2594. handler : @pd_virtual;
  2595. pocall : pocall_none;
  2596. pooption : [po_virtualmethod];
  2597. mutexclpocall : [pocall_internproc];
  2598. mutexclpotype : [potype_class_constructor,potype_class_destructor];
  2599. mutexclpo : PD_VIRTUAL_MUTEXCLPO
  2600. ),(
  2601. idtok:_CPPDECL;
  2602. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2603. handler : nil;
  2604. pocall : pocall_cppdecl;
  2605. pooption : [];
  2606. mutexclpocall : [];
  2607. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2608. mutexclpo : [po_assembler,po_external,po_virtualmethod]
  2609. ),(
  2610. idtok:_VARARGS;
  2611. pd_flags : [pd_interface,pd_implemen,pd_procvar,pd_objcclass,pd_objcprot];
  2612. handler : nil;
  2613. pocall : pocall_none;
  2614. pooption : [po_varargs];
  2615. mutexclpocall : [pocall_internproc,pocall_register,
  2616. pocall_far16,pocall_oldfpccall,pocall_mwpascal];
  2617. mutexclpotype : [];
  2618. mutexclpo : [po_assembler,po_interrupt,po_inline]
  2619. ),(
  2620. idtok:_COMPILERPROC;
  2621. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  2622. handler : @pd_compilerproc;
  2623. pocall : pocall_none;
  2624. pooption : [po_compilerproc];
  2625. mutexclpocall : [];
  2626. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2627. mutexclpo : [po_interrupt]
  2628. ),(
  2629. idtok:_WEAKEXTERNAL;
  2630. pd_flags : [pd_implemen,pd_interface,pd_notobject,pd_notobjintf,pd_cppobject,pd_notrecord,pd_nothelper];
  2631. handler : @pd_weakexternal;
  2632. pocall : pocall_none;
  2633. { mark it both external and weak external, so we don't have to
  2634. adapt all code for external symbols to also check for weak external
  2635. }
  2636. pooption : [po_external,po_weakexternal];
  2637. mutexclpocall : [pocall_internproc,pocall_syscall];
  2638. { allowed for external cpp classes }
  2639. mutexclpotype : [{potype_constructor,potype_destructor}potype_class_constructor,potype_class_destructor];
  2640. mutexclpo : [po_public,po_exports,po_interrupt,po_assembler,po_inline]
  2641. ),(
  2642. idtok:_WINAPI;
  2643. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2644. handler : @pd_winapi;
  2645. pocall : pocall_none;
  2646. pooption : [];
  2647. mutexclpocall : [pocall_stdcall,pocall_cdecl,pocall_mwpascal,pocall_sysv_abi_cdecl,pocall_ms_abi_cdecl];
  2648. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2649. mutexclpo : [po_external]
  2650. ),(
  2651. idtok:_ENUMERATOR;
  2652. pd_flags : [pd_interface,pd_object,pd_record];
  2653. handler : @pd_enumerator;
  2654. pocall : pocall_none;
  2655. pooption : [];
  2656. mutexclpocall : [pocall_internproc];
  2657. mutexclpotype : [];
  2658. mutexclpo : [po_exports,po_interrupt,po_external,po_inline]
  2659. ),(
  2660. idtok:_RTLPROC;
  2661. pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf];
  2662. handler : nil;
  2663. pocall : pocall_none;
  2664. pooption : [po_rtlproc];
  2665. mutexclpocall : [];
  2666. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2667. mutexclpo : [po_interrupt]
  2668. ),(
  2669. idtok:_HARDFLOAT;
  2670. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2671. handler : @pd_hardfloat;
  2672. pocall : pocall_hardfloat;
  2673. pooption : [];
  2674. mutexclpocall : [];
  2675. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2676. { it's available with po_external because the libgcc floating point routines on the arm
  2677. uses this calling convention }
  2678. mutexclpo : []
  2679. ),(
  2680. idtok:_SYSV_ABI_DEFAULT;
  2681. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2682. handler : nil;
  2683. pocall : pocall_sysv_abi_default;
  2684. pooption : [];
  2685. mutexclpocall : [];
  2686. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2687. mutexclpo : [po_interrupt]
  2688. ),(
  2689. idtok:_SYSV_ABI_CDECL;
  2690. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2691. handler : nil;
  2692. pocall : pocall_sysv_abi_cdecl;
  2693. pooption : [];
  2694. mutexclpocall : [];
  2695. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2696. mutexclpo : [po_interrupt]
  2697. ),(
  2698. idtok:_MS_ABI_DEFAULT;
  2699. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2700. handler : nil;
  2701. pocall : pocall_ms_abi_default;
  2702. pooption : [];
  2703. mutexclpocall : [];
  2704. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2705. mutexclpo : [po_interrupt]
  2706. ),(
  2707. idtok:_MS_ABI_CDECL;
  2708. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2709. handler : nil;
  2710. pocall : pocall_ms_abi_cdecl;
  2711. pooption : [];
  2712. mutexclpocall : [];
  2713. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2714. mutexclpo : [po_interrupt]
  2715. ),(
  2716. idtok:_VECTORCALL;
  2717. pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar];
  2718. handler : nil;
  2719. pocall : pocall_vectorcall;
  2720. pooption : [];
  2721. mutexclpocall : [];
  2722. mutexclpotype : [potype_constructor,potype_destructor,potype_class_constructor,potype_class_destructor];
  2723. mutexclpo : [po_interrupt]
  2724. )
  2725. );
  2726. function check_proc_directive(isprocvar:boolean):boolean;
  2727. var
  2728. i : longint;
  2729. begin
  2730. result:=false;
  2731. for i:=1 to num_proc_directives do
  2732. if proc_direcdata[i].idtok=idtoken then
  2733. begin
  2734. if ((not isprocvar) or
  2735. (pd_procvar in proc_direcdata[i].pd_flags)) and
  2736. { don't eat a public directive in classes }
  2737. not((idtoken=_PUBLIC) and (symtablestack.top.symtabletype=ObjectSymtable)) then
  2738. result:=true;
  2739. exit;
  2740. end;
  2741. end;
  2742. function find_proc_directive_index(tok: ttoken): longint; inline;
  2743. begin
  2744. result:=-1;
  2745. for result:=1 to num_proc_directives do
  2746. if proc_direcdata[result].idtok=tok then
  2747. exit;
  2748. result:=-1;
  2749. end;
  2750. function parse_proc_direc(pd:tabstractprocdef;var pdflags:tpdflags):boolean;
  2751. {
  2752. Parse the procedure directive, returns true if a correct directive is found
  2753. }
  2754. var
  2755. p : longint;
  2756. name : TIDString;
  2757. po_comp : tprocoptions;
  2758. tokenloc : TFilePosInfo;
  2759. begin
  2760. parse_proc_direc:=false;
  2761. name:=tokeninfo^[idtoken].str;
  2762. { Hint directive? Then exit immediatly }
  2763. if (m_hintdirective in current_settings.modeswitches) then
  2764. begin
  2765. case idtoken of
  2766. _LIBRARY,
  2767. _PLATFORM,
  2768. _UNIMPLEMENTED,
  2769. _EXPERIMENTAL,
  2770. _DEPRECATED :
  2771. if (m_delphi in current_settings.modeswitches) and (pd.typ=procdef) then
  2772. begin
  2773. maybe_parse_hint_directives(tprocdef(pd));
  2774. { could the new token still be a directive? }
  2775. if token<>_ID then
  2776. exit;
  2777. end
  2778. else
  2779. exit;
  2780. else
  2781. ;
  2782. end;
  2783. end;
  2784. { C directive is MacPas only, because it breaks too much existing code
  2785. on other platforms (PFV) }
  2786. if (idtoken=_C) and
  2787. not(m_mac in current_settings.modeswitches) then
  2788. exit;
  2789. { retrieve data for directive if found }
  2790. p:=find_proc_directive_index(idtoken);
  2791. { Check if the procedure directive is known }
  2792. if p=-1 then
  2793. begin
  2794. { parsing a procvar type the name can be any
  2795. next variable !! }
  2796. if ((pdflags * [pd_procvar,pd_object,pd_record,pd_objcclass,pd_objcprot])=[]) and
  2797. not(idtoken in [_PROPERTY,_GENERIC]) then
  2798. Message1(parser_w_unknown_proc_directive_ignored,pattern);
  2799. exit;
  2800. end;
  2801. { check if method and directive not for object, like public.
  2802. This needs to be checked also for procvars }
  2803. if (pd_notobject in proc_direcdata[p].pd_flags) and
  2804. (symtablestack.top.symtabletype=ObjectSymtable) and
  2805. { directive allowed for cpp classes? }
  2806. not((pd_cppobject in proc_direcdata[p].pd_flags) and is_cppclass(tdef(symtablestack.top.defowner))) and
  2807. not((pd_javaclass in proc_direcdata[p].pd_flags) and is_javaclass(tdef(symtablestack.top.defowner))) and
  2808. not((pd_intfjava in proc_direcdata[p].pd_flags) and is_javainterface(tdef(symtablestack.top.defowner))) then
  2809. exit;
  2810. if (pd_notrecord in proc_direcdata[p].pd_flags) and
  2811. (symtablestack.top.symtabletype=recordsymtable) then
  2812. exit;
  2813. { check if method and directive not for java class }
  2814. if not(pd_javaclass in proc_direcdata[p].pd_flags) and
  2815. is_javaclass(tdef(symtablestack.top.defowner)) then
  2816. exit;
  2817. { check if method and directive not for java interface }
  2818. if not(pd_intfjava in proc_direcdata[p].pd_flags) and
  2819. is_javainterface(tdef(symtablestack.top.defowner)) then
  2820. exit;
  2821. { Keep track of the token's position in the file so it's correctly indicated if an error occurs. }
  2822. tokenloc := current_tokenpos;
  2823. { consume directive, and turn flag on }
  2824. consume(token);
  2825. parse_proc_direc:=true;
  2826. { Conflicts between directives? }
  2827. if (pd.proctypeoption in proc_direcdata[p].mutexclpotype) then
  2828. begin
  2829. MessagePos2(tokenloc, parser_e_proc_dir_conflict,name,ProcTypeOptionKeywords[pd.proctypeoption]);
  2830. exit;
  2831. end;
  2832. if (pd.proccalloption in proc_direcdata[p].mutexclpocall) then
  2833. begin
  2834. MessagePos2(tokenloc, parser_e_proc_dir_conflict,name,'"' + UpCase(proccalloptionStr[pd.proccalloption]) + '"');
  2835. exit;
  2836. end;
  2837. po_comp := (pd.procoptions*proc_direcdata[p].mutexclpo);
  2838. if (po_comp<>[]) then
  2839. begin
  2840. MessagePos2(tokenloc, parser_e_proc_dir_conflict,name,get_first_proc_str(po_comp));
  2841. exit;
  2842. end;
  2843. { set calling convention }
  2844. if proc_direcdata[p].pocall<>pocall_none then
  2845. begin
  2846. if (po_hascallingconvention in pd.procoptions) then
  2847. begin
  2848. MessagePos2(tokenloc, parser_w_proc_overriding_calling,
  2849. proccalloptionStr[pd.proccalloption],
  2850. proccalloptionStr[proc_direcdata[p].pocall]);
  2851. end;
  2852. { check if the target processor supports this calling convention }
  2853. if not(proc_direcdata[p].pocall in supported_calling_conventions) then
  2854. begin
  2855. MessagePos1(tokenloc, parser_e_illegal_calling_convention,proccalloptionStr[proc_direcdata[p].pocall]);
  2856. { recover }
  2857. proc_direcdata[p].pocall:=pocall_stdcall;
  2858. end;
  2859. pd.proccalloption:=proc_direcdata[p].pocall;
  2860. include(pd.procoptions,po_hascallingconvention);
  2861. end;
  2862. if pd.typ=procdef then
  2863. begin
  2864. { Check if the directive is only for objects }
  2865. if (pd_object in proc_direcdata[p].pd_flags) and
  2866. not assigned(tprocdef(pd).struct) then
  2867. exit;
  2868. { Check if the directive is only for records }
  2869. if (pd_record in proc_direcdata[p].pd_flags) and
  2870. not assigned(tprocdef(pd).struct) then
  2871. exit;
  2872. { check if method and directive not for interface }
  2873. if (pd_notobjintf in proc_direcdata[p].pd_flags) and
  2874. is_interface(tprocdef(pd).struct) then
  2875. exit;
  2876. { check if method and directive not for interface }
  2877. if is_dispinterface(tprocdef(pd).struct) and
  2878. not(pd_dispinterface in proc_direcdata[p].pd_flags) then
  2879. exit;
  2880. { check if method and directive not for objcclass }
  2881. if is_objcclass(tprocdef(pd).struct) and
  2882. not(pd_objcclass in proc_direcdata[p].pd_flags) then
  2883. exit;
  2884. { check if method and directive not for objcprotocol }
  2885. if is_objcprotocol(tprocdef(pd).struct) and
  2886. not(pd_objcprot in proc_direcdata[p].pd_flags) then
  2887. exit;
  2888. { check if method and directive not for record/class helper }
  2889. if is_objectpascal_helper(tprocdef(pd).struct) and
  2890. (pd_nothelper in proc_direcdata[p].pd_flags) then
  2891. exit;
  2892. end;
  2893. { Check the pd_flags if the directive should be allowed }
  2894. if (pd_interface in pdflags) and
  2895. not(pd_interface in proc_direcdata[p].pd_flags) then
  2896. begin
  2897. MessagePos1(tokenloc, parser_e_proc_dir_not_allowed_in_interface,name);
  2898. exit;
  2899. end;
  2900. if (pd_implemen in pdflags) and
  2901. not(pd_implemen in proc_direcdata[p].pd_flags) then
  2902. begin
  2903. MessagePos1(tokenloc, parser_e_proc_dir_not_allowed_in_implementation,name);
  2904. exit;
  2905. end;
  2906. if (pd_procvar in pdflags) and
  2907. not(pd_procvar in proc_direcdata[p].pd_flags) then
  2908. begin
  2909. MessagePos1(tokenloc, parser_e_proc_dir_not_allowed_in_procvar,name);
  2910. exit;
  2911. end;
  2912. { Return the new pd_flags }
  2913. if not(pd_body in proc_direcdata[p].pd_flags) then
  2914. exclude(pdflags,pd_body);
  2915. { Add the correct flag }
  2916. pd.procoptions:=pd.procoptions+proc_direcdata[p].pooption;
  2917. { Call the handler }
  2918. if pointer(proc_direcdata[p].handler)<>nil then
  2919. proc_direcdata[p].handler(pd);
  2920. end;
  2921. function proc_get_importname(pd:tprocdef):string;
  2922. var
  2923. dllname, importname : string;
  2924. begin
  2925. result:='';
  2926. if not(po_external in pd.procoptions) then
  2927. internalerror(200412151);
  2928. { external name or number is specified }
  2929. if assigned(pd.import_name) or (pd.import_nr<>0) then
  2930. begin
  2931. if assigned(pd.import_dll) then
  2932. dllname:=pd.import_dll^
  2933. else
  2934. dllname:='';
  2935. if assigned(pd.import_name) then
  2936. importname:=pd.import_name^
  2937. else
  2938. importname:='';
  2939. proc_get_importname:=make_dllmangledname(dllname,
  2940. importname,pd.import_nr,pd.proccalloption);
  2941. end
  2942. else
  2943. begin
  2944. { Default names when importing variables }
  2945. case pd.proccalloption of
  2946. pocall_cdecl,
  2947. pocall_sysv_abi_cdecl,
  2948. pocall_ms_abi_cdecl:
  2949. begin
  2950. if assigned(pd.struct) then
  2951. result:=target_info.Cprefix+pd.struct.objrealname^+'_'+pd.procsym.realname
  2952. else
  2953. result:=target_info.Cprefix+pd.procsym.realname;
  2954. end;
  2955. pocall_cppdecl :
  2956. begin
  2957. result:=target_info.Cprefix+pd.cplusplusmangledname;
  2958. end;
  2959. else
  2960. begin
  2961. {In MacPas a single "external" has the same effect as "external name 'xxx'" }
  2962. { but according to MacPas mode description
  2963. Cprefix should still be used PM }
  2964. if (m_mac in current_settings.modeswitches) then
  2965. result:=target_info.Cprefix+tprocdef(pd).procsym.realname
  2966. else
  2967. result:=pd.procsym.realname;
  2968. end;
  2969. end;
  2970. end;
  2971. end;
  2972. procedure proc_set_mangledname(pd:tprocdef);
  2973. var
  2974. s : string;
  2975. begin
  2976. { When the mangledname is already set we aren't allowed to change
  2977. it because it can already be used somewhere (PFV) }
  2978. if not(po_has_mangledname in pd.procoptions) then
  2979. begin
  2980. if (po_external in pd.procoptions) then
  2981. begin
  2982. { External Procedures are only allowed to change the mangledname
  2983. in their first declaration }
  2984. if (pd.forwarddef or (not pd.hasforward)) then
  2985. begin
  2986. s:=proc_get_importname(pd);
  2987. if s<>'' then
  2988. begin
  2989. pd.setmangledname(s);
  2990. end;
  2991. { since this is an external declaration, there won't be an
  2992. implementation that needs to match the original symbol
  2993. again -> immediately convert here }
  2994. if po_compilerproc in pd.procoptions then
  2995. pd.setcompilerprocname;
  2996. end
  2997. end
  2998. else
  2999. { Normal procedures }
  3000. begin
  3001. if (po_compilerproc in pd.procoptions) then
  3002. begin
  3003. pd.setmangledname(lower(pd.procsym.name));
  3004. end;
  3005. end;
  3006. end;
  3007. { Public/exported alias names }
  3008. if (([po_public,po_exports]*pd.procoptions)<>[]) and
  3009. not(po_has_public_name in pd.procoptions) then
  3010. begin
  3011. case pd.proccalloption of
  3012. pocall_cdecl,
  3013. pocall_sysv_abi_cdecl,
  3014. pocall_ms_abi_cdecl:
  3015. begin
  3016. if assigned(pd.struct) then
  3017. pd.aliasnames.insert(target_info.Cprefix+pd.struct.objrealname^+'_'+pd.procsym.realname)
  3018. else
  3019. begin
  3020. { Export names are not mangled on Windows and OS/2, see also pexports.pas }
  3021. if (target_info.system in (systems_all_windows+[system_i386_emx, system_i386_os2])) and
  3022. (po_exports in pd.procoptions) then
  3023. pd.aliasnames.insert(pd.procsym.realname)
  3024. else
  3025. pd.aliasnames.insert(target_info.Cprefix+pd.procsym.realname);
  3026. end;
  3027. end;
  3028. pocall_cppdecl :
  3029. begin
  3030. pd.aliasnames.insert(target_info.Cprefix+pd.cplusplusmangledname);
  3031. end;
  3032. else
  3033. ;
  3034. end;
  3035. { prevent adding the alias a second time }
  3036. include(pd.procoptions,po_has_public_name);
  3037. end;
  3038. end;
  3039. procedure parse_proc_directives(pd:tabstractprocdef;var pdflags:tpdflags);
  3040. {
  3041. Parse the procedure directives. It does not matter if procedure directives
  3042. are written using ;procdir; or ['procdir'] syntax.
  3043. }
  3044. var
  3045. stoprecording,
  3046. res : boolean;
  3047. begin
  3048. if (m_mac in current_settings.modeswitches) and (cs_externally_visible in current_settings.localswitches) then
  3049. begin
  3050. tprocdef(pd).aliasnames.insert(target_info.Cprefix+tprocdef(pd).procsym.realname);
  3051. include(pd.procoptions,po_public);
  3052. include(pd.procoptions,po_has_public_name);
  3053. include(pd.procoptions,po_global);
  3054. end;
  3055. { methods from external class definitions are all external themselves }
  3056. if (pd.typ=procdef) and
  3057. assigned(tprocdef(pd).struct) and
  3058. (tprocdef(pd).struct.typ=objectdef) and
  3059. (oo_is_external in tobjectdef(tprocdef(pd).struct).objectoptions) then
  3060. tprocdef(pd).make_external;
  3061. { Class constructors and destructor are static class methods in real. }
  3062. { There are many places in the compiler where either class or static }
  3063. { method flag changes the behavior. It is simplier to add them to }
  3064. { the class constructors/destructors options than to fix all the }
  3065. { occurencies. (Paul) }
  3066. if pd.proctypeoption in [potype_class_constructor,potype_class_destructor] then
  3067. begin
  3068. include(pd.procoptions,po_classmethod);
  3069. include(pd.procoptions,po_staticmethod);
  3070. end;
  3071. { for a generic routine we also need to record the procedure }
  3072. { directives, but only if we aren't already recording for a }
  3073. { surrounding generic }
  3074. if pd.is_generic and (pd.typ=procdef) and not current_scanner.is_recording_tokens then
  3075. begin
  3076. current_scanner.startrecordtokens(tprocdef(pd).genericdecltokenbuf);
  3077. stoprecording:=true;
  3078. end
  3079. else
  3080. stoprecording:=false;
  3081. while (token=_ID) or
  3082. (
  3083. not (m_prefixed_attributes in current_settings.modeswitches) and
  3084. (token=_LECKKLAMMER)
  3085. ) do
  3086. begin
  3087. if not (m_prefixed_attributes in current_settings.modeswitches) and
  3088. try_to_consume(_LECKKLAMMER) then
  3089. begin
  3090. repeat
  3091. parse_proc_direc(pd,pdflags);
  3092. until not try_to_consume(_COMMA);
  3093. consume(_RECKKLAMMER);
  3094. { we always expect at least '[];' }
  3095. res:=true;
  3096. end
  3097. else
  3098. begin
  3099. res:=parse_proc_direc(pd,pdflags);
  3100. end;
  3101. { A procedure directive normally followed by a semicolon, but in
  3102. a const section or reading a type we should stop when _EQ is found,
  3103. because a constant/default value follows }
  3104. if res then
  3105. begin
  3106. if (block_type=bt_const_type) and
  3107. (token=_EQ) then
  3108. break;
  3109. { support procedure proc;stdcall export; }
  3110. if not(check_proc_directive((pd.typ=procvardef))) then
  3111. begin
  3112. { support "record p : procedure stdcall end;" and
  3113. "var p : procedure stdcall = nil;" }
  3114. if (pd_procvar in pdflags) and
  3115. (token in [_END,_RKLAMMER,_EQ]) then
  3116. break
  3117. else
  3118. begin
  3119. if (token=_COLON) then
  3120. begin
  3121. Message(parser_e_field_not_allowed_here);
  3122. consume_all_until(_SEMICOLON);
  3123. end;
  3124. consume(_SEMICOLON)
  3125. end;
  3126. end;
  3127. end
  3128. else
  3129. break;
  3130. end;
  3131. if stoprecording then
  3132. current_scanner.stoprecordtokens;
  3133. { nostackframe requires assembler, but assembler
  3134. may be specified in the implementation part only,
  3135. and in not required if the function is first forward declared
  3136. if it is a procdef that has forwardef set to true
  3137. we postpone the possible error message to the real implementation
  3138. parse_only does not need to be considered as po_nostackframe
  3139. is an implementation only directive }
  3140. if (po_nostackframe in pd.procoptions) and
  3141. not (po_assembler in pd.procoptions) and
  3142. ((pd.typ<>procdef) or not tprocdef(pd).forwarddef) then
  3143. message(parser_e_nostackframe_without_assembler);
  3144. end;
  3145. procedure parse_var_proc_directives(sym:tsym);
  3146. var
  3147. pdflags : tpdflags;
  3148. pd : tabstractprocdef;
  3149. begin
  3150. pdflags:=[pd_procvar];
  3151. pd:=nil;
  3152. case sym.typ of
  3153. fieldvarsym,
  3154. staticvarsym,
  3155. localvarsym,
  3156. paravarsym :
  3157. pd:=tabstractprocdef(tabstractvarsym(sym).vardef);
  3158. typesym :
  3159. pd:=tabstractprocdef(ttypesym(sym).typedef);
  3160. else
  3161. internalerror(2003042617);
  3162. end;
  3163. if pd.typ<>procvardef then
  3164. internalerror(2003042618);
  3165. { names should never be used anyway }
  3166. parse_proc_directives(pd,pdflags);
  3167. end;
  3168. procedure parse_object_proc_directives(pd:tabstractprocdef);
  3169. var
  3170. pdflags : tpdflags;
  3171. begin
  3172. pdflags:=[pd_object];
  3173. parse_proc_directives(pd,pdflags);
  3174. end;
  3175. procedure parse_record_proc_directives(pd:tabstractprocdef);
  3176. var
  3177. pdflags : tpdflags;
  3178. begin
  3179. pdflags:=[pd_record];
  3180. parse_proc_directives(pd,pdflags);
  3181. end;
  3182. end.