2
0

pdecsub.pas 134 KB

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