pdecsub.pas 146 KB

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