htypechk.pas 157 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit exports some help routines for the type checking
  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 htypechk;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,cmsgs,tokens,
  22. node,globtype,compinnr,
  23. symconst,symtype,symdef,symsym,symbase,
  24. pgentype;
  25. type
  26. Ttok2nodeRec=record
  27. tok : ttoken;
  28. nod : tnodetype;
  29. inr : tinlinenumber;
  30. op_overloading_supported : boolean;
  31. minargs : longint;
  32. maxargs : longint;
  33. end;
  34. Ttok2opRec=record
  35. tok : ttoken;
  36. managementoperator : tmanagementoperator;
  37. end;
  38. pcandidate = ^tcandidate;
  39. tcandidate = record
  40. next : pcandidate;
  41. data : tprocdef;
  42. wrongparaidx,
  43. firstparaidx : integer;
  44. exact_count,
  45. equal_count,
  46. cl1_count,
  47. cl2_count,
  48. cl3_count,
  49. cl4_count,
  50. cl5_count,
  51. cl6_count,
  52. coper_count : integer; { should be signed }
  53. ordinal_distance : double;
  54. invalid : boolean;
  55. {$ifndef DISABLE_FAST_OVERLOAD_PATCH}
  56. saved_validity : boolean;
  57. {$endif}
  58. wrongparanr : byte;
  59. end;
  60. tcallcandidates = class
  61. private
  62. FProcsym : tprocsym;
  63. FProcsymtable : tsymtable;
  64. FOperator : ttoken;
  65. FCandidateProcs : pcandidate;
  66. FIgnoredCandidateProcs: tfpobjectlist;
  67. FProcCnt : integer;
  68. FParaNode : tnode;
  69. FParaLength : smallint;
  70. FAllowVariant : boolean;
  71. procedure collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
  72. procedure collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean;spezcontext:tspecializationcontext);
  73. procedure create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
  74. procedure calc_distance(st_root:tsymtable;objcidcall: boolean);
  75. function proc_add(st:tsymtable;pd:tprocdef;objcidcall: boolean):pcandidate;
  76. function maybe_specialize(var pd:tprocdef;spezcontext:tspecializationcontext):boolean;
  77. public
  78. constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
  79. constructor create_operator(op:ttoken;ppn:tnode);
  80. destructor destroy;override;
  81. procedure list(all:boolean);
  82. {$ifdef EXTDEBUG}
  83. procedure dump_info(lvl:longint);
  84. {$endif EXTDEBUG}
  85. procedure get_information;
  86. function choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
  87. procedure find_wrong_para;
  88. property Count:integer read FProcCnt;
  89. end;
  90. type
  91. tregableinfoflag = (
  92. // can be put in a register if it's the address of a var/out/const parameter
  93. ra_addr_regable,
  94. { orthogonal to above flag: the address of the node is taken and may
  95. possibly escape the block in which this node is declared (e.g. a
  96. local variable is passed as var parameter to another procedure)
  97. }
  98. ra_addr_taken,
  99. { variable is accessed in a different scope }
  100. ra_different_scope);
  101. tregableinfoflags = set of tregableinfoflag;
  102. const
  103. tok2nodes=27;
  104. tok2node:array[1..tok2nodes] of ttok2noderec=(
  105. (tok:_PLUS ;nod:addn;inr:in_none;op_overloading_supported:true;minargs:1;maxargs:2), { binary overloading supported }
  106. (tok:_MINUS ;nod:subn;inr:in_none;op_overloading_supported:true;minargs:1;maxargs:2), { binary and unary overloading supported }
  107. (tok:_STAR ;nod:muln;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  108. (tok:_SLASH ;nod:slashn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  109. (tok:_EQ ;nod:equaln;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  110. (tok:_GT ;nod:gtn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  111. (tok:_LT ;nod:ltn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  112. (tok:_GTE ;nod:gten;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  113. (tok:_LTE ;nod:lten;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  114. (tok:_SYMDIF ;nod:symdifn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  115. (tok:_STARSTAR ;nod:starstarn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  116. (tok:_OP_AS ;nod:asn;inr:in_none;op_overloading_supported:false;minargs:0;maxargs:0), { binary overloading NOT supported }
  117. (tok:_OP_IN ;nod:inn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  118. (tok:_OP_IS ;nod:isn;inr:in_none;op_overloading_supported:false;minargs:0;maxargs:0), { binary overloading NOT supported }
  119. (tok:_OP_OR ;nod:orn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  120. (tok:_OP_AND ;nod:andn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  121. (tok:_OP_DIV ;nod:divn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  122. (tok:_OP_NOT ;nod:notn;inr:in_none;op_overloading_supported:true;minargs:1;maxargs:1), { unary overloading supported }
  123. (tok:_OP_MOD ;nod:modn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  124. (tok:_OP_SHL ;nod:shln;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  125. (tok:_OP_SHR ;nod:shrn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  126. (tok:_OP_XOR ;nod:xorn;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  127. (tok:_ASSIGNMENT ;nod:assignn;inr:in_none;op_overloading_supported:true;minargs:1;maxargs:1), { unary overloading supported }
  128. (tok:_OP_EXPLICIT;nod:assignn;inr:in_none;op_overloading_supported:true;minargs:1;maxargs:1), { unary overloading supported }
  129. (tok:_NE ;nod:unequaln;inr:in_none;op_overloading_supported:true;minargs:2;maxargs:2), { binary overloading supported }
  130. (tok:_OP_INC ;nod:inlinen;inr:in_inc_x;op_overloading_supported:true;minargs:1;maxargs:1), { unary overloading supported }
  131. (tok:_OP_DEC ;nod:inlinen;inr:in_dec_x;op_overloading_supported:true;minargs:1;maxargs:1) { unary overloading supported }
  132. );
  133. tok2ops=4;
  134. tok2op: array[1..tok2ops] of ttok2oprec=(
  135. (tok:_OP_INITIALIZE; managementoperator: mop_initialize),
  136. (tok:_OP_FINALIZE ; managementoperator: mop_finalize),
  137. (tok:_OP_ADDREF ; managementoperator: mop_addref),
  138. (tok:_OP_COPY ; managementoperator: mop_copy)
  139. );
  140. function node2opstr(nt:tnodetype):string;
  141. function token2managementoperator(optoken:ttoken):tmanagementoperator;
  142. { check operator args and result type }
  143. type
  144. toverload_check_flag = (
  145. ocf_check_non_overloadable, { also check operators that are (currently) considered as
  146. not overloadable (e.g. the "+" operator for dynamic arrays
  147. if modeswitch arrayoperators is active) }
  148. ocf_check_only { only check whether the operator is overloaded, but don't
  149. modify the passed in node (return true if the operator is
  150. overloaded, false otherwise) }
  151. );
  152. toverload_check_flags = set of toverload_check_flag;
  153. function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
  154. function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
  155. function isunaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
  156. function isbinaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
  157. { Register Allocation }
  158. procedure make_not_regable(p : tnode; how: tregableinfoflags);
  159. { procvar handling }
  160. function is_proc2procvar_load(p:tnode;out realprocdef:tprocdef):boolean;
  161. { returns whether a node represents a load of the function result node via
  162. the function name (so it could also be a recursive call to the function
  163. in case there or no parameters, or the function could be passed as
  164. procvar }
  165. function is_ambiguous_funcret_load(p: tnode; out owningprocdef: tprocdef): boolean;
  166. procedure test_local_to_procvar(from_def:tprocvardef;to_def:tdef);
  167. { sets varsym varstate field correctly }
  168. type
  169. tvarstateflag = (vsf_must_be_valid,vsf_use_hints,vsf_use_hint_for_string_result);
  170. tvarstateflags = set of tvarstateflag;
  171. procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
  172. { sets the callunique flag, if the node is a vecn, }
  173. { takes care of type casts etc. }
  174. procedure set_unique(p : tnode);
  175. function valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
  176. function valid_for_formal_constref(p : tnode; report_errors: boolean) : boolean;
  177. function valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
  178. function valid_for_var(p:tnode; report_errors: boolean):boolean;
  179. function valid_for_assignment(p:tnode; report_errors: boolean):boolean;
  180. function valid_for_loopvar(p:tnode; report_errors: boolean):boolean;
  181. function valid_for_addr(p : tnode; report_errors: boolean) : boolean;
  182. function allowenumop(nt:tnodetype):boolean;
  183. procedure check_ranges(const location: tfileposinfo; source: tnode; destdef: tdef);
  184. { returns whether the def may be used in the Default() intrinsic; static
  185. arrays, records and objects are checked recursively }
  186. function is_valid_for_default(def:tdef):boolean;
  187. procedure UninitializedVariableMessage(pos : tfileposinfo;warning,local,managed : boolean;name : TMsgStr);
  188. implementation
  189. uses
  190. systems,constexp,globals,
  191. cutils,verbose,
  192. symtable,symutil,
  193. defutil,defcmp,
  194. nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,procinfo,
  195. pgenutil
  196. ;
  197. type
  198. TValidAssign=(Valid_Property,Valid_Void,Valid_Const,Valid_Addr,Valid_Packed,Valid_Range);
  199. TValidAssigns=set of TValidAssign;
  200. { keep these two in sync! }
  201. const
  202. non_commutative_op_tokens=[_OP_SHL,_OP_SHR,_OP_DIV,_OP_MOD,_STARSTAR,_SLASH,_MINUS];
  203. non_commutative_op_nodes=[shln,shrn,divn,modn,starstarn,slashn,subn];
  204. function node2opstr(nt:tnodetype):string;
  205. var
  206. i : integer;
  207. begin
  208. result:='<unknown>';
  209. for i:=1 to tok2nodes do
  210. if tok2node[i].nod=nt then
  211. begin
  212. result:=tokeninfo^[tok2node[i].tok].str;
  213. break;
  214. end;
  215. end;
  216. function token2managementoperator(optoken:ttoken):tmanagementoperator;
  217. var
  218. i : integer;
  219. begin
  220. result:=mop_none;
  221. for i:=1 to tok2ops do
  222. if tok2op[i].tok=optoken then
  223. begin
  224. result:=tok2op[i].managementoperator;
  225. break;
  226. end;
  227. end;
  228. function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
  229. function internal_check(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype;var allowed:boolean):boolean;
  230. const
  231. identity_operators=[equaln,unequaln];
  232. order_theoretic_operators=identity_operators+[ltn,lten,gtn,gten];
  233. arithmetic_operators=[addn,subn,muln,divn,modn];
  234. rational_operators=[addn,subn,muln,slashn];
  235. numerical_operators=arithmetic_operators+[slashn];
  236. pointer_arithmetic_operators=[addn,subn];
  237. logical_operators=[andn,orn,xorn];
  238. bit_manipulation_operators=logical_operators+[shln,shrn];
  239. set_set_operators=identity_operators+[addn,subn,muln,symdifn]+
  240. order_theoretic_operators;
  241. element_set_operators=[inn];
  242. string_comparison_operators=order_theoretic_operators;
  243. string_manipulation_operators=[addn];
  244. string_operators =
  245. string_comparison_operators+string_manipulation_operators;
  246. begin
  247. internal_check:=true;
  248. { Reject the cases permitted by the default interpretation (DI). }
  249. case ld.typ of
  250. formaldef,
  251. recorddef,
  252. variantdef :
  253. begin
  254. allowed:=true;
  255. end;
  256. enumdef:
  257. begin
  258. allowed:=not (
  259. (
  260. is_set(rd) and
  261. (treetyp in element_set_operators)
  262. ) or
  263. (
  264. is_enum(rd) and
  265. (treetyp in (order_theoretic_operators+[addn, subn]))
  266. ) or
  267. (
  268. { for enum definitions, see webtbs/tw22860.pp }
  269. is_integer(rd) and
  270. (treetyp in (order_theoretic_operators+bit_manipulation_operators+arithmetic_operators))
  271. )
  272. );
  273. end;
  274. setdef:
  275. begin
  276. allowed:=not (
  277. (
  278. is_set(rd) and
  279. (treetyp in (set_set_operators+identity_operators))
  280. ) or
  281. (
  282. { This clause is a hack but it’s due to a hack somewhere
  283. else---while set + element is not permitted by DI, it
  284. seems to be used when a set is constructed inline }
  285. (rd.typ in [enumdef,orddef]) and
  286. (treetyp=addn)
  287. )
  288. );
  289. end;
  290. orddef, floatdef:
  291. begin
  292. allowed:=not (
  293. (
  294. (rd.typ in [orddef,floatdef]) and
  295. (treetyp in order_theoretic_operators)
  296. ) or
  297. (
  298. (m_mac in current_settings.modeswitches) and
  299. is_stringlike(rd) and
  300. (ld.typ=orddef) and
  301. (treetyp in string_comparison_operators)) or
  302. { c.f. $(source)\tests\tmacpas5.pp }
  303. (
  304. (rd.typ=setdef) and
  305. (ld.typ=orddef) and
  306. (treetyp in element_set_operators)
  307. )
  308. { This clause may be too restrictive---not all types under
  309. orddef have a corresponding set type; despite this the
  310. restriction should be very unlikely to become
  311. a practical obstacle, and can be relaxed by simply
  312. adding an extra check on TOrdDef(rd).ordtype }
  313. );
  314. { Note that Currency can be under either orddef or floatdef;
  315. when it’s under floatdef, is_currency() implies is_float();
  316. when it’s under orddef, is_currency() does NOT imply
  317. is_integer(). }
  318. if allowed then
  319. begin
  320. if is_anychar(ld) then
  321. allowed:=not (
  322. is_stringlike(rd) and
  323. (treetyp in string_operators)
  324. )
  325. else if is_boolean(ld) then
  326. allowed:=not (
  327. is_boolean(rd) and
  328. (treetyp in logical_operators)
  329. )
  330. else if is_integer(ld) or
  331. (
  332. (ld.typ=orddef) and
  333. is_currency(ld)
  334. { Here ld is Currency but behaves like an integer }
  335. ) then
  336. allowed:=not (
  337. (
  338. (
  339. is_integer(rd) or
  340. (
  341. (rd.typ=orddef) and
  342. is_currency(rd)
  343. )
  344. ) and
  345. (treetyp in (bit_manipulation_operators+numerical_operators))
  346. ) or
  347. (
  348. is_fpu(rd) and
  349. (treetyp in rational_operators)
  350. ) or
  351. (
  352. { When an integer type is used as the first operand in
  353. pointer arithmetic, DI doesn’t accept minus as the
  354. operator (Currency can’t be used in pointer
  355. arithmetic even if it’s under orddef) }
  356. is_integer(ld) and
  357. (rd.typ=pointerdef) and
  358. (treetyp in pointer_arithmetic_operators-[subn])
  359. )
  360. )
  361. else { is_fpu(ld) = True }
  362. allowed:=not (
  363. (
  364. is_fpu(rd) or
  365. is_integer(rd) or
  366. is_currency(rd)
  367. ) and
  368. (treetyp in rational_operators)
  369. );
  370. end;
  371. end;
  372. procvardef :
  373. begin
  374. if (rd.typ in [pointerdef,procdef,procvardef]) then
  375. begin
  376. allowed:=false;
  377. exit;
  378. end;
  379. allowed:=true;
  380. end;
  381. pointerdef :
  382. begin
  383. { DI permits pointer arithmetic for pointer + pointer, pointer -
  384. integer, pointer - pointer, but not for pointer + pointer.
  385. The last case is only valid in DI when both sides are
  386. stringlike. }
  387. if is_stringlike(ld) then
  388. if is_stringlike(rd) then
  389. { DI in this case permits string operations and pointer
  390. arithmetic. }
  391. allowed:=not (treetyp in (string_operators+pointer_arithmetic_operators))
  392. else if rd.typ = pointerdef then
  393. { DI in this case permits minus for pointer arithmetic and
  394. order-theoretic operators for pointer comparison. }
  395. allowed:=not (
  396. treetyp in (
  397. pointer_arithmetic_operators-[addn]+
  398. order_theoretic_operators
  399. )
  400. )
  401. else if is_integer(rd) then
  402. { DI in this case permits pointer arithmetic. }
  403. allowed:=not (treetyp in pointer_arithmetic_operators)
  404. else
  405. allowed:=true
  406. else
  407. allowed:=not (
  408. (
  409. is_integer(rd) and
  410. (treetyp in pointer_arithmetic_operators)
  411. ) or
  412. (
  413. (rd.typ=pointerdef) and
  414. (
  415. treetyp in (
  416. pointer_arithmetic_operators-[addn]+
  417. order_theoretic_operators
  418. )
  419. )
  420. ) or
  421. (
  422. (lt=niln) and
  423. (rd.typ in [procvardef,procdef,classrefdef]) and
  424. (treetyp in identity_operators)
  425. ) or
  426. (
  427. is_implicit_pointer_object_type(rd) and
  428. (treetyp in identity_operators)
  429. )
  430. );
  431. end;
  432. arraydef :
  433. begin
  434. { not vector/mmx }
  435. if ((cs_mmx in current_settings.localswitches) and
  436. is_mmx_able_array(ld)) or
  437. ((cs_support_vectors in current_settings.globalswitches) and
  438. is_vector(ld)) then
  439. begin
  440. allowed:=false;
  441. exit;
  442. end;
  443. if is_stringlike(ld) and
  444. (
  445. (
  446. (
  447. is_stringlike(rd) or
  448. (rt = niln)
  449. ) and
  450. (treetyp in string_operators)
  451. ) or
  452. (
  453. is_integer(rd) and
  454. (treetyp in pointer_arithmetic_operators)
  455. ) or
  456. (
  457. (
  458. is_pchar(rd) or
  459. is_pwidechar(rd)) and
  460. (treetyp in pointer_arithmetic_operators) and
  461. (tpointerdef(rd).pointeddef=tarraydef(ld).elementdef
  462. )
  463. )
  464. ) then
  465. begin
  466. allowed:=false;
  467. exit;
  468. end;
  469. { dynamic array compare with niln }
  470. if is_dynamic_array(ld) and
  471. (treetyp in identity_operators) then
  472. if is_dynamic_array(rd) or
  473. (rt=niln) then
  474. begin
  475. allowed:=false;
  476. exit;
  477. end;
  478. { <dyn. array> + <dyn. array> is handled by the compiler }
  479. if (m_array_operators in current_settings.modeswitches) and
  480. (treetyp=addn) and
  481. (is_dynamic_array(ld) or is_dynamic_array(rd)) then
  482. begin
  483. allowed:=false;
  484. exit;
  485. end;
  486. allowed:=true;
  487. end;
  488. objectdef :
  489. begin
  490. { <> and = are defined for implicit pointer object types }
  491. allowed:=not (
  492. is_implicit_pointer_object_type(ld) and
  493. (
  494. (
  495. is_implicit_pointer_object_type(rd) or
  496. (rd.typ=pointerdef) or
  497. (rt=niln) or
  498. ((ld=java_jlstring) and
  499. is_stringlike(rd))
  500. )
  501. ) and
  502. (treetyp in identity_operators)
  503. );
  504. end;
  505. stringdef :
  506. begin
  507. allowed:=not (
  508. is_stringlike(rd) and
  509. (treetyp in string_operators)
  510. );
  511. end;
  512. else
  513. internal_check:=false;
  514. end;
  515. end;
  516. begin
  517. { power ** is always possible }
  518. result:=treetyp=starstarn;
  519. if not result then
  520. begin
  521. if not internal_check(treetyp,ld,lt,rd,rt,result) and
  522. not (treetyp in non_commutative_op_nodes) then
  523. internal_check(treetyp,rd,rt,ld,lt,result)
  524. end;
  525. end;
  526. function isunaryoperatoroverloadable(treetyp:tnodetype;inlinenumber:tinlinenumber;ld:tdef) : boolean;
  527. begin
  528. result:=false;
  529. case treetyp of
  530. subn,
  531. addn,
  532. unaryminusn,
  533. unaryplusn,
  534. inlinen:
  535. begin
  536. { only Inc, Dec inline functions are supported for now, so skip check inlinenumber }
  537. if (ld.typ in [orddef,enumdef,floatdef]) then
  538. exit;
  539. {$ifdef SUPPORT_MMX}
  540. if (cs_mmx in current_settings.localswitches) and
  541. is_mmx_able_array(ld) then
  542. exit;
  543. {$endif SUPPORT_MMX}
  544. result:=true;
  545. end;
  546. notn :
  547. begin
  548. if ld.typ = orddef then exit;
  549. {$ifdef SUPPORT_MMX}
  550. if (cs_mmx in current_settings.localswitches) and
  551. is_mmx_able_array(ld) then
  552. exit;
  553. {$endif SUPPORT_MMX}
  554. result:=true;
  555. end;
  556. else
  557. ;
  558. end;
  559. end;
  560. function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
  561. var
  562. ld,rd : tdef;
  563. i : longint;
  564. eq : tequaltype;
  565. conv : tconverttype;
  566. cdo : tcompare_defs_options;
  567. pd : tprocdef;
  568. oldcount,
  569. count: longint;
  570. parasym : tparavarsym;
  571. begin
  572. result:=false;
  573. count := pf.parast.SymList.count;
  574. oldcount:=count;
  575. while count > 0 do
  576. begin
  577. parasym:=tparavarsym(pf.parast.SymList[count-1]);
  578. if parasym.typ<>paravarsym then
  579. begin
  580. dec(count);
  581. end
  582. else if is_boolean(parasym.vardef) then
  583. begin
  584. if parasym.name='RANGECHECK' then
  585. begin
  586. Include(parasym.varoptions, vo_is_hidden_para);
  587. Include(parasym.varoptions, vo_is_range_check);
  588. Dec(count);
  589. end
  590. else if parasym.name='OVERFLOWCHECK' then
  591. begin
  592. Include(parasym.varoptions, vo_is_hidden_para);
  593. Include(parasym.varoptions, vo_is_overflow_check);
  594. Dec(count);
  595. end
  596. else
  597. break;
  598. end
  599. else
  600. break;
  601. end;
  602. if count<>oldcount then
  603. pf.calcparas;
  604. case count of
  605. 1 : begin
  606. ld:=tparavarsym(pf.parast.SymList[0]).vardef;
  607. { assignment is a special case }
  608. if optoken in [_ASSIGNMENT,_OP_EXPLICIT] then
  609. begin
  610. cdo:=[];
  611. if optoken=_OP_EXPLICIT then
  612. include(cdo,cdo_explicit);
  613. eq:=compare_defs_ext(ld,pf.returndef,nothingn,conv,pd,cdo);
  614. result:=
  615. (eq=te_exact) or
  616. (
  617. (eq=te_incompatible) and
  618. { don't allow overloading assigning to custom shortstring
  619. types, because we also don't want to differentiate based
  620. on different shortstring types (e.g.,
  621. "operator :=(const v: variant) res: shorstring" also
  622. has to work for assigning a variant to a string[80])
  623. }
  624. (not is_shortstring(pf.returndef) or
  625. (tstringdef(pf.returndef).len=255))
  626. );
  627. end
  628. else
  629. { enumerator is a special case too }
  630. if optoken=_OP_ENUMERATOR then
  631. begin
  632. result:=
  633. is_class_or_interface_or_object(pf.returndef) or
  634. is_record(pf.returndef);
  635. if result then
  636. begin
  637. if not assigned(tabstractrecorddef(pf.returndef).search_enumerator_move) then
  638. begin
  639. Message1(sym_e_no_enumerator_move, pf.returndef.typename);
  640. result:=false;
  641. end;
  642. if not assigned(tabstractrecorddef(pf.returndef).search_enumerator_current) then
  643. begin
  644. Message1(sym_e_no_enumerator_current,pf.returndef.typename);
  645. result:=false;
  646. end;
  647. end;
  648. end
  649. else
  650. begin
  651. for i:=1 to tok2nodes do
  652. if tok2node[i].tok=optoken then
  653. begin
  654. result:=
  655. tok2node[i].op_overloading_supported and
  656. (tok2node[i].minargs<=1) and
  657. (tok2node[i].maxargs>=1) and
  658. isunaryoperatoroverloadable(tok2node[i].nod,tok2node[i].inr,ld);
  659. break;
  660. end;
  661. { Inc, Dec operators are valid if only result type is the same as argument type }
  662. if result and (optoken in [_OP_INC,_OP_DEC]) then
  663. result:=pf.returndef=ld;
  664. end;
  665. end;
  666. 2 : begin
  667. for i:=1 to tok2nodes do
  668. if tok2node[i].tok=optoken then
  669. begin
  670. ld:=tparavarsym(pf.parast.SymList[0]).vardef;
  671. rd:=tparavarsym(pf.parast.SymList[1]).vardef;
  672. result:=
  673. tok2node[i].op_overloading_supported and
  674. (tok2node[i].minargs<=2) and
  675. (tok2node[i].maxargs>=2) and
  676. isbinaryoperatoroverloadable(tok2node[i].nod,ld,nothingn,rd,nothingn);
  677. break;
  678. end;
  679. end;
  680. end;
  681. end;
  682. function isunaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
  683. var
  684. ld : tdef;
  685. optoken : ttoken;
  686. operpd : tprocdef;
  687. ppn : tcallparanode;
  688. candidates : tcallcandidates;
  689. cand_cnt : integer;
  690. inlinenumber: tinlinenumber;
  691. begin
  692. result:=false;
  693. operpd:=nil;
  694. { load easier access variables }
  695. ld:=tunarynode(t).left.resultdef;
  696. { if we are dealing with inline function then get the function }
  697. if t.nodetype=inlinen then
  698. inlinenumber:=tinlinenode(t).inlinenumber
  699. else
  700. inlinenumber:=in_none;
  701. if not (ocf_check_non_overloadable in ocf) and not isunaryoperatoroverloadable(t.nodetype,inlinenumber,ld) then
  702. exit;
  703. { operator overload is possible }
  704. result:=not (ocf_check_only in ocf);
  705. optoken:=NOTOKEN;
  706. case t.nodetype of
  707. notn:
  708. optoken:=_OP_NOT;
  709. unaryminusn:
  710. optoken:=_MINUS;
  711. unaryplusn:
  712. optoken:=_PLUS;
  713. inlinen:
  714. case inlinenumber of
  715. in_inc_x:
  716. optoken:=_OP_INC;
  717. in_dec_x:
  718. optoken:=_OP_DEC;
  719. else
  720. ;
  721. end;
  722. else
  723. ;
  724. end;
  725. if (optoken=NOTOKEN) then
  726. begin
  727. if not (ocf_check_only in ocf) then
  728. begin
  729. CGMessage(parser_e_operator_not_overloaded);
  730. t:=cnothingnode.create;
  731. end;
  732. exit;
  733. end;
  734. { generate parameter nodes }
  735. { for inline nodes just copy existent callparanode }
  736. if (t.nodetype=inlinen) and (tinlinenode(t).left.nodetype=callparan) then
  737. ppn:=tcallparanode(tinlinenode(t).left.getcopy)
  738. else
  739. begin
  740. ppn:=ccallparanode.create(tunarynode(t).left.getcopy,nil);
  741. ppn.get_paratype;
  742. end;
  743. candidates:=tcallcandidates.create_operator(optoken,ppn);
  744. { stop when there are no operators found }
  745. if candidates.count=0 then
  746. begin
  747. candidates.free;
  748. ppn.free;
  749. if not (ocf_check_only in ocf) then
  750. begin
  751. CGMessage2(parser_e_operator_not_overloaded_2,ld.typename,arraytokeninfo[optoken].str);
  752. t:=cnothingnode.create;
  753. end;
  754. exit;
  755. end;
  756. { Retrieve information about the candidates }
  757. candidates.get_information;
  758. {$ifdef EXTDEBUG}
  759. { Display info when multiple candidates are found }
  760. candidates.dump_info(V_Debug);
  761. {$endif EXTDEBUG}
  762. cand_cnt:=candidates.choose_best(tabstractprocdef(operpd),false);
  763. { exit when no overloads are found }
  764. if cand_cnt=0 then
  765. begin
  766. candidates.free;
  767. ppn.free;
  768. if not (ocf_check_only in ocf) then
  769. begin
  770. CGMessage2(parser_e_operator_not_overloaded_2,ld.typename,arraytokeninfo[optoken].str);
  771. t:=cnothingnode.create;
  772. end;
  773. exit;
  774. end;
  775. { Multiple candidates left? }
  776. if (cand_cnt>1) and not (ocf_check_only in ocf) then
  777. begin
  778. CGMessage(type_e_cant_choose_overload_function);
  779. {$ifdef EXTDEBUG}
  780. candidates.dump_info(V_Hint);
  781. {$else EXTDEBUG}
  782. candidates.list(false);
  783. {$endif EXTDEBUG}
  784. { we'll just use the first candidate to make the
  785. call }
  786. end;
  787. candidates.free;
  788. if ocf_check_only in ocf then
  789. begin
  790. ppn.free;
  791. result:=true;
  792. exit;
  793. end;
  794. addsymref(operpd.procsym,operpd);
  795. { the nil as symtable signs firstcalln that this is
  796. an overloaded operator }
  797. t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
  798. { we already know the procdef to use, so it can
  799. skip the overload choosing in callnode.pass_typecheck }
  800. tcallnode(t).procdefinition:=operpd;
  801. end;
  802. function isbinaryoverloaded(var t : tnode;ocf:toverload_check_flags) : boolean;
  803. var
  804. rd,ld : tdef;
  805. optoken : ttoken;
  806. operpd : tprocdef;
  807. ht : tnode;
  808. ppn : tcallparanode;
  809. cand_cnt : integer;
  810. function search_operator(optoken:ttoken;generror:boolean): integer;
  811. var
  812. candidates : tcallcandidates;
  813. begin
  814. { generate parameter nodes }
  815. ppn:=ccallparanode.create(tbinarynode(t).right.getcopy,ccallparanode.create(tbinarynode(t).left.getcopy,nil));
  816. ppn.get_paratype;
  817. candidates:=tcallcandidates.create_operator(optoken,ppn);
  818. { for commutative operators we can swap arguments and try again }
  819. if (candidates.count=0) and
  820. not(optoken in non_commutative_op_tokens) then
  821. begin
  822. candidates.free;
  823. reverseparameters(ppn);
  824. { reverse compare operators }
  825. case optoken of
  826. _LT:
  827. optoken:=_GTE;
  828. _GT:
  829. optoken:=_LTE;
  830. _LTE:
  831. optoken:=_GT;
  832. _GTE:
  833. optoken:=_LT;
  834. else
  835. ;
  836. end;
  837. candidates:=tcallcandidates.create_operator(optoken,ppn);
  838. end;
  839. { stop when there are no operators found }
  840. result:=candidates.count;
  841. if (result=0) and generror then
  842. begin
  843. CGMessage(parser_e_operator_not_overloaded);
  844. candidates.free;
  845. ppn.free;
  846. ppn:=nil;
  847. exit;
  848. end;
  849. if (result>0) then
  850. begin
  851. { Retrieve information about the candidates }
  852. candidates.get_information;
  853. {$ifdef EXTDEBUG}
  854. { Display info when multiple candidates are found }
  855. candidates.dump_info(V_Debug);
  856. {$endif EXTDEBUG}
  857. result:=candidates.choose_best(tabstractprocdef(operpd),false);
  858. end;
  859. { exit when no overloads are found }
  860. if (result=0) and generror then
  861. begin
  862. CGMessage3(parser_e_operator_not_overloaded_3,ld.typename,arraytokeninfo[optoken].str,rd.typename);
  863. candidates.free;
  864. ppn.free;
  865. ppn:=nil;
  866. exit;
  867. end;
  868. { Multiple candidates left? }
  869. if result>1 then
  870. begin
  871. CGMessage(type_e_cant_choose_overload_function);
  872. {$ifdef EXTDEBUG}
  873. candidates.dump_info(V_Hint);
  874. {$else EXTDEBUG}
  875. candidates.list(false);
  876. {$endif EXTDEBUG}
  877. { we'll just use the first candidate to make the
  878. call }
  879. end;
  880. candidates.free;
  881. end;
  882. begin
  883. isbinaryoverloaded:=false;
  884. operpd:=nil;
  885. ppn:=nil;
  886. { load easier access variables }
  887. ld:=tbinarynode(t).left.resultdef;
  888. rd:=tbinarynode(t).right.resultdef;
  889. if not (ocf_check_non_overloadable in ocf) and
  890. not isbinaryoperatoroverloadable(t.nodetype,ld,tbinarynode(t).left.nodetype,rd,tbinarynode(t).right.nodetype) then
  891. exit;
  892. { operator overload is possible }
  893. { if we only check for the existance of the overload, then we assume that
  894. it is not overloaded }
  895. result:=not (ocf_check_only in ocf);
  896. case t.nodetype of
  897. equaln:
  898. optoken:=_EQ;
  899. unequaln:
  900. optoken:=_NE;
  901. addn:
  902. optoken:=_PLUS;
  903. subn:
  904. optoken:=_MINUS;
  905. muln:
  906. optoken:=_STAR;
  907. starstarn:
  908. optoken:=_STARSTAR;
  909. slashn:
  910. optoken:=_SLASH;
  911. ltn:
  912. optoken:=_LT;
  913. gtn:
  914. optoken:=_GT;
  915. lten:
  916. optoken:=_LTE;
  917. gten:
  918. optoken:=_GTE;
  919. symdifn :
  920. optoken:=_SYMDIF;
  921. modn :
  922. optoken:=_OP_MOD;
  923. orn :
  924. optoken:=_OP_OR;
  925. xorn :
  926. optoken:=_OP_XOR;
  927. andn :
  928. optoken:=_OP_AND;
  929. divn :
  930. optoken:=_OP_DIV;
  931. shln :
  932. optoken:=_OP_SHL;
  933. shrn :
  934. optoken:=_OP_SHR;
  935. inn :
  936. optoken:=_OP_IN;
  937. else
  938. begin
  939. if not (ocf_check_only in ocf) then
  940. begin
  941. CGMessage(parser_e_operator_not_overloaded);
  942. t:=cnothingnode.create;
  943. end;
  944. exit;
  945. end;
  946. end;
  947. cand_cnt:=search_operator(optoken,(optoken<>_NE) and not (ocf_check_only in ocf));
  948. { no operator found for "<>" then search for "=" operator }
  949. if (cand_cnt=0) and (optoken=_NE) and not (ocf_check_only in ocf) then
  950. begin
  951. ppn.free;
  952. ppn:=nil;
  953. operpd:=nil;
  954. optoken:=_EQ;
  955. cand_cnt:=search_operator(optoken,true);
  956. end;
  957. if (cand_cnt=0) then
  958. begin
  959. ppn.free;
  960. if not (ocf_check_only in ocf) then
  961. t:=cnothingnode.create;
  962. exit;
  963. end;
  964. if ocf_check_only in ocf then
  965. begin
  966. ppn.free;
  967. result:=true;
  968. exit;
  969. end;
  970. addsymref(operpd.procsym,operpd);
  971. { the nil as symtable signs firstcalln that this is
  972. an overloaded operator }
  973. ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[],nil);
  974. { we already know the procdef to use, so it can
  975. skip the overload choosing in callnode.pass_typecheck }
  976. tcallnode(ht).procdefinition:=operpd;
  977. { if we found "=" operator for "<>" expression then use it
  978. together with "not" }
  979. if (t.nodetype=unequaln) and (optoken=_EQ) then
  980. ht:=cnotnode.create(ht);
  981. t:=ht;
  982. end;
  983. {****************************************************************************
  984. Register Calculation
  985. ****************************************************************************}
  986. { marks an lvalue as "unregable" }
  987. procedure make_not_regable_intern(p : tnode; how: tregableinfoflags; records_only: boolean);
  988. begin
  989. if ra_addr_taken in how then
  990. include(p.flags,nf_address_taken);
  991. repeat
  992. case p.nodetype of
  993. subscriptn:
  994. begin
  995. records_only:=true;
  996. p:=tsubscriptnode(p).left;
  997. end;
  998. vecn:
  999. begin
  1000. { if there's an implicit dereference, we can stop (just like
  1001. when there is an actual derefn) }
  1002. if ((tvecnode(p).left.resultdef.typ=arraydef) and
  1003. not is_special_array(tvecnode(p).left.resultdef)) or
  1004. ((tvecnode(p).left.resultdef.typ=stringdef) and
  1005. (tstringdef(tvecnode(p).left.resultdef).stringtype in [st_shortstring,st_longstring])) then
  1006. p:=tvecnode(p).left
  1007. else
  1008. break;
  1009. end;
  1010. typeconvn :
  1011. begin
  1012. { implicit dereference -> stop }
  1013. if (ttypeconvnode(p).convtype=tc_pointer_2_array) then
  1014. break;
  1015. if (ttypeconvnode(p).resultdef.typ=recorddef) then
  1016. records_only:=false;
  1017. p:=ttypeconvnode(p).left;
  1018. end;
  1019. loadn :
  1020. begin
  1021. if (tloadnode(p).symtableentry.typ in [staticvarsym,localvarsym,paravarsym]) then
  1022. begin
  1023. if (ra_addr_taken in how) then
  1024. tabstractvarsym(tloadnode(p).symtableentry).addr_taken:=true;
  1025. if (ra_different_scope in how) then
  1026. tabstractvarsym(tloadnode(p).symtableentry).different_scope:=true;
  1027. if (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
  1028. ((not records_only) or
  1029. (tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then
  1030. if (tloadnode(p).symtableentry.typ = paravarsym) and
  1031. (ra_addr_regable in how) then
  1032. tabstractvarsym(tloadnode(p).symtableentry).varregable:=vr_addr
  1033. else
  1034. tabstractvarsym(tloadnode(p).symtableentry).varregable:=vr_none;
  1035. end;
  1036. break;
  1037. end;
  1038. temprefn :
  1039. begin
  1040. if (ra_addr_taken in how) then
  1041. ttemprefnode(p).includetempflag(ti_addr_taken);
  1042. if (ti_may_be_in_reg in ttemprefnode(p).tempflags) and
  1043. ((not records_only) or
  1044. (ttemprefnode(p).tempinfo^.typedef.typ = recorddef)) then
  1045. ttemprefnode(p).excludetempflag(ti_may_be_in_reg);
  1046. break;
  1047. end;
  1048. else
  1049. break;
  1050. end;
  1051. until false;
  1052. end;
  1053. procedure make_not_regable(p : tnode; how: tregableinfoflags);
  1054. begin
  1055. make_not_regable_intern(p,how,false);
  1056. end;
  1057. {****************************************************************************
  1058. Subroutine Handling
  1059. ****************************************************************************}
  1060. function is_proc2procvar_load(p:tnode;out realprocdef:tprocdef):boolean;
  1061. begin
  1062. result:=false;
  1063. { remove voidpointer typecast for tp procvars }
  1064. if ((m_tp_procvar in current_settings.modeswitches) or
  1065. (m_mac_procvar in current_settings.modeswitches)) and
  1066. (p.nodetype=typeconvn) and
  1067. is_voidpointer(p.resultdef) then
  1068. p:=tunarynode(p).left;
  1069. result:=(p.nodetype=typeconvn) and
  1070. (ttypeconvnode(p).convtype=tc_proc_2_procvar);
  1071. if result then
  1072. realprocdef:=tprocdef(ttypeconvnode(p).left.resultdef);
  1073. end;
  1074. function is_ambiguous_funcret_load(p: tnode; out owningprocdef: tprocdef): boolean;
  1075. begin
  1076. result:=false;
  1077. { the funcret is an absolutevarsym, which gets converted into a type
  1078. conversion node of the loadnode of the actual function result. Its
  1079. resulttype is obviously the same as that of the real function result }
  1080. if (p.nodetype=typeconvn) and
  1081. (p.resultdef=ttypeconvnode(p).left.resultdef) then
  1082. p:=ttypeconvnode(p).left;
  1083. if (p.nodetype=loadn) and
  1084. (tloadnode(p).symtableentry.typ in [absolutevarsym,localvarsym,paravarsym]) and
  1085. ([vo_is_funcret,vo_is_result] * tabstractvarsym(tloadnode(p).symtableentry).varoptions = [vo_is_funcret]) then
  1086. begin
  1087. owningprocdef:=tprocdef(tloadnode(p).symtableentry.owner.defowner);
  1088. result:=true;
  1089. end;
  1090. end;
  1091. { local routines can't be assigned to procvars }
  1092. procedure test_local_to_procvar(from_def:tprocvardef;to_def:tdef);
  1093. begin
  1094. if not(m_nested_procvars in current_settings.modeswitches) and
  1095. (from_def.parast.symtablelevel>normal_function_level) and
  1096. (to_def.typ=procvardef) then
  1097. CGMessage(type_e_cannot_local_proc_to_procvar);
  1098. end;
  1099. procedure UninitializedVariableMessage(pos : tfileposinfo;warning,local,managed : boolean;name : TMsgStr);
  1100. const
  1101. msg : array[false..true,false..true,false..true] of dword = (
  1102. (
  1103. (sym_h_uninitialized_variable,sym_h_uninitialized_managed_variable),
  1104. (sym_h_uninitialized_local_variable,sym_h_uninitialized_managed_local_variable)
  1105. ),
  1106. (
  1107. (sym_w_uninitialized_variable,sym_w_uninitialized_managed_variable),
  1108. (sym_w_uninitialized_local_variable,sym_w_uninitialized_managed_local_variable)
  1109. )
  1110. );
  1111. begin
  1112. CGMessagePos1(pos,msg[warning,local,managed],name);
  1113. end;
  1114. procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
  1115. const
  1116. vstrans: array[tvarstate,tvarstate] of tvarstate = (
  1117. { vs_none -> ... }
  1118. (vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
  1119. { vs_declared -> ... }
  1120. (vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
  1121. { vs_initialised -> ... }
  1122. (vs_none,vs_initialised,vs_initialised,vs_read,vs_read,vs_read,vs_written,vs_readwritten),
  1123. { vs_read -> ... }
  1124. (vs_none,vs_read,vs_read,vs_read,vs_read,vs_read,vs_readwritten,vs_readwritten),
  1125. { vs_read_not_warned -> ... }
  1126. (vs_none,vs_read_not_warned,vs_read,vs_read,vs_read_not_warned,vs_read_not_warned,vs_readwritten,vs_readwritten),
  1127. { vs_referred_not_inited }
  1128. (vs_none,vs_referred_not_inited,vs_read,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
  1129. { vs_written -> ... }
  1130. (vs_none,vs_written,vs_written,vs_readwritten,vs_readwritten,vs_written,vs_written,vs_readwritten),
  1131. { vs_readwritten -> ... }
  1132. (vs_none,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten));
  1133. var
  1134. hsym : tabstractvarsym;
  1135. begin
  1136. { make sure we can still warn about uninitialised use after high(v), @v etc }
  1137. if (newstate = vs_read) and
  1138. not(vsf_must_be_valid in varstateflags) then
  1139. newstate := vs_referred_not_inited;
  1140. while assigned(p) do
  1141. begin
  1142. case p.nodetype of
  1143. derefn:
  1144. begin
  1145. if (tderefnode(p).left.nodetype=temprefn) and
  1146. assigned(ttemprefnode(tderefnode(p).left).tempinfo^.withnode) then
  1147. p:=ttemprefnode(tderefnode(p).left).tempinfo^.withnode
  1148. else
  1149. break;
  1150. end;
  1151. typeconvn :
  1152. begin
  1153. case ttypeconvnode(p).convtype of
  1154. tc_cchar_2_pchar,
  1155. tc_cstring_2_pchar,
  1156. tc_array_2_pointer :
  1157. exclude(varstateflags,vsf_must_be_valid);
  1158. tc_pchar_2_string,
  1159. tc_pointer_2_array :
  1160. begin
  1161. include(varstateflags,vsf_must_be_valid);
  1162. { when a pointer is used for array access, the
  1163. pointer itself is read and never written }
  1164. newstate := vs_read;
  1165. end;
  1166. else
  1167. ;
  1168. end;
  1169. p:=tunarynode(p).left;
  1170. end;
  1171. subscriptn :
  1172. begin
  1173. if is_implicit_pointer_object_type(tunarynode(p).left.resultdef) then
  1174. newstate := vs_read;
  1175. p:=tunarynode(p).left;
  1176. end;
  1177. vecn:
  1178. begin
  1179. set_varstate(tbinarynode(p).right,vs_read,[vsf_must_be_valid]);
  1180. { dyn. arrays and dyn. strings are read }
  1181. if is_implicit_array_pointer(tunarynode(p).left.resultdef) then
  1182. newstate:=vs_read;
  1183. if (newstate in [vs_read,vs_readwritten]) or
  1184. not(tunarynode(p).left.resultdef.typ in [stringdef,arraydef]) then
  1185. include(varstateflags,vsf_must_be_valid)
  1186. else if (newstate = vs_written) then
  1187. exclude(varstateflags,vsf_must_be_valid);
  1188. p:=tunarynode(p).left;
  1189. end;
  1190. { do not parse calln }
  1191. calln :
  1192. break;
  1193. loadn :
  1194. begin
  1195. { the methodpointer/framepointer is read }
  1196. if assigned(tunarynode(p).left) then
  1197. set_varstate(tunarynode(p).left,vs_read,[vsf_must_be_valid]);
  1198. if (tloadnode(p).symtableentry.typ in [localvarsym,paravarsym,staticvarsym]) then
  1199. begin
  1200. hsym:=tabstractvarsym(tloadnode(p).symtableentry);
  1201. { this check requires proper data flow analysis... }
  1202. (* if (hsym.varspez=vs_final) and
  1203. (hsym.varstate in [vs_written,vs_readwritten]) and
  1204. (newstate in [vs_written,vs_readwritten]) then
  1205. CGMessagePos1(p.fileinfo,sym_e_final_write_once); *)
  1206. if (vsf_must_be_valid in varstateflags) and
  1207. (hsym.varstate in [vs_declared,vs_read_not_warned,vs_referred_not_inited]) then
  1208. begin
  1209. { Give warning/note for uninitialized locals }
  1210. if assigned(hsym.owner) and
  1211. not(vo_is_external in hsym.varoptions) and
  1212. (hsym.owner.symtabletype in [parasymtable,localsymtable,staticsymtable]) and
  1213. ((hsym.owner=current_procinfo.procdef.localst) or
  1214. (hsym.owner=current_procinfo.procdef.parast)) then
  1215. begin
  1216. if vsf_use_hints in varstateflags then
  1217. include(tloadnode(p).loadnodeflags,loadnf_only_uninitialized_hint);
  1218. if not(cs_opt_nodedfa in current_settings.optimizerswitches) then
  1219. begin
  1220. if (vo_is_funcret in hsym.varoptions) then
  1221. begin
  1222. { An uninitialized function Result of a managed type needs special handling.
  1223. When passing it as a var parameter a warning need to be emitted, since a user
  1224. may expect Result to be empty (nil) by default as it happens with local vars
  1225. of a managed type. But this is not true for Result and may lead to serious issues.
  1226. The only exception is SetLength(Result, ?) for a string Result. A user always
  1227. expects undefined contents of the string after calling SetLength(). In such
  1228. case a hint need to be emitted.
  1229. }
  1230. if is_managed_type(hsym.vardef) then
  1231. if not ( is_string(hsym.vardef) and (vsf_use_hint_for_string_result in varstateflags) ) then
  1232. exclude(varstateflags,vsf_use_hints);
  1233. if vsf_use_hints in varstateflags then
  1234. begin
  1235. if is_managed_type(hsym.vardef) then
  1236. CGMessagePos(p.fileinfo,sym_h_managed_function_result_uninitialized)
  1237. else
  1238. CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized);
  1239. end
  1240. else
  1241. begin
  1242. if is_managed_type(hsym.vardef) then
  1243. CGMessagePos(p.fileinfo,sym_w_managed_function_result_uninitialized)
  1244. else
  1245. CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized);
  1246. end;
  1247. end
  1248. else
  1249. begin
  1250. UninitializedVariableMessage(p.fileinfo,
  1251. { on the JVM, an uninitialized var-parameter
  1252. is just as fatal as a nil pointer dereference }
  1253. not((vsf_use_hints in varstateflags) and not(target_info.system in systems_jvm)),
  1254. tloadnode(p).symtable.symtabletype=localsymtable,
  1255. is_managed_type(tloadnode(p).resultdef),
  1256. hsym.realname);
  1257. end;
  1258. end;
  1259. end
  1260. else if (newstate = vs_read) then
  1261. newstate := vs_read_not_warned;
  1262. end;
  1263. hsym.varstate := vstrans[hsym.varstate,newstate];
  1264. end;
  1265. case newstate of
  1266. vs_written:
  1267. include(tloadnode(p).flags,nf_write);
  1268. vs_readwritten:
  1269. if not(nf_write in tloadnode(p).flags) then
  1270. include(tloadnode(p).flags,nf_modify);
  1271. else
  1272. ;
  1273. end;
  1274. break;
  1275. end;
  1276. addrn:
  1277. break;
  1278. callparan :
  1279. internalerror(200310081);
  1280. else
  1281. break;
  1282. end;{case }
  1283. end;
  1284. end;
  1285. procedure set_unique(p : tnode);
  1286. begin
  1287. while assigned(p) do
  1288. begin
  1289. case p.nodetype of
  1290. vecn:
  1291. begin
  1292. include(p.flags,nf_callunique);
  1293. break;
  1294. end;
  1295. typeconvn,
  1296. subscriptn,
  1297. derefn:
  1298. p:=tunarynode(p).left;
  1299. else
  1300. break;
  1301. end;
  1302. end;
  1303. end;
  1304. function valid_for_assign(p:tnode;opts:TValidAssigns; report_errors: boolean):boolean;
  1305. var
  1306. typeconvs: tfpobjectlist;
  1307. hp2,
  1308. hp : tnode;
  1309. gotstring,
  1310. gotsubscript,
  1311. gotrecord,
  1312. gotvec,
  1313. gottypeconv : boolean;
  1314. fromdef,
  1315. todef : tdef;
  1316. errmsg,
  1317. temp : longint;
  1318. function constaccessok(vs: tabstractvarsym): boolean;
  1319. begin
  1320. result:=false;
  1321. { allow p^:= constructions with p is const parameter }
  1322. if (Valid_Const in opts) or
  1323. ((hp.nodetype=loadn) and
  1324. (loadnf_isinternal_ignoreconst in tloadnode(hp).loadnodeflags)) then
  1325. result:=true
  1326. { final (class) fields can only be initialised in the (class) constructors of
  1327. class in which they have been declared (not in descendent constructors) }
  1328. else if vs.varspez=vs_final then
  1329. begin
  1330. if (current_procinfo.procdef.owner=vs.owner) then
  1331. if vs.typ=staticvarsym then
  1332. result:=current_procinfo.procdef.proctypeoption=potype_class_constructor
  1333. else
  1334. result:=current_procinfo.procdef.proctypeoption=potype_constructor;
  1335. if not result and
  1336. report_errors then
  1337. CGMessagePos(hp.fileinfo,type_e_invalid_final_assignment);
  1338. end
  1339. else
  1340. if report_errors then
  1341. CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
  1342. end;
  1343. procedure mayberesettypeconvs;
  1344. var
  1345. i: longint;
  1346. begin
  1347. if assigned(typeconvs) then
  1348. begin
  1349. if not report_errors and
  1350. not result then
  1351. for i:=0 to typeconvs.Count-1 do
  1352. ttypeconvnode(typeconvs[i]).assignment_side:=false;
  1353. typeconvs.free;
  1354. end;
  1355. end;
  1356. begin
  1357. if valid_const in opts then
  1358. errmsg:=type_e_variable_id_expected
  1359. else if valid_property in opts then
  1360. errmsg:=type_e_argument_cant_be_assigned
  1361. else
  1362. errmsg:=type_e_no_addr_of_constant;
  1363. result:=false;
  1364. gotsubscript:=false;
  1365. gotvec:=false;
  1366. gotrecord:=false;
  1367. gotstring:=false;
  1368. gottypeconv:=false;
  1369. hp:=p;
  1370. if not(valid_void in opts) and
  1371. is_void(hp.resultdef) then
  1372. begin
  1373. if report_errors then
  1374. CGMessagePos(hp.fileinfo,errmsg);
  1375. exit;
  1376. end;
  1377. typeconvs:=nil;
  1378. while assigned(hp) do
  1379. begin
  1380. { property allowed? calln has a property check itself }
  1381. if (nf_isproperty in hp.flags) then
  1382. begin
  1383. { check return type }
  1384. case hp.resultdef.typ of
  1385. recorddef :
  1386. gotrecord:=true;
  1387. stringdef :
  1388. gotstring:=true;
  1389. else
  1390. ;
  1391. end;
  1392. if (valid_property in opts) then
  1393. begin
  1394. { don't allow writing to calls that will create
  1395. temps like calls that return a structure and we
  1396. are assigning to a member }
  1397. if (valid_const in opts) or
  1398. (
  1399. { allowing assignments to typecasted properties
  1400. a) is Delphi-incompatible
  1401. b) causes problems in case the getter is a function
  1402. (because then the result of the getter is
  1403. typecasted to this type, and then we "assign" to
  1404. this typecasted function result) -> always
  1405. disallow, since property accessors should be
  1406. transparantly changeable to functions at all
  1407. times
  1408. }
  1409. not(gottypeconv) and
  1410. not(gotsubscript and gotrecord) and
  1411. not(gotstring and gotvec) and
  1412. not(nf_no_lvalue in hp.flags)
  1413. ) then
  1414. result:=true
  1415. else
  1416. if report_errors then
  1417. CGMessagePos(hp.fileinfo,errmsg);
  1418. end
  1419. else
  1420. begin
  1421. { 1. if it returns a pointer and we've found a deref,
  1422. 2. if it returns a class and a subscription or with is found
  1423. 3. if the address is needed of a field (subscriptn, vecn) }
  1424. if (gotstring and gotvec) or
  1425. (
  1426. (Valid_Addr in opts) and
  1427. (hp.nodetype in [subscriptn,vecn])
  1428. ) then
  1429. result:=true
  1430. else
  1431. if report_errors then
  1432. CGMessagePos(hp.fileinfo,errmsg);
  1433. end;
  1434. mayberesettypeconvs;
  1435. exit;
  1436. end;
  1437. case hp.nodetype of
  1438. temprefn :
  1439. begin
  1440. valid_for_assign := not(ti_readonly in ttemprefnode(hp).tempflags);
  1441. mayberesettypeconvs;
  1442. exit;
  1443. end;
  1444. derefn :
  1445. begin
  1446. { dereference -> always valid }
  1447. valid_for_assign:=true;
  1448. mayberesettypeconvs;
  1449. exit;
  1450. end;
  1451. typeconvn :
  1452. begin
  1453. gottypeconv:=true;
  1454. { typecast sizes must match, exceptions:
  1455. - implicit typecast made by absolute
  1456. - from formaldef
  1457. - from void
  1458. - from/to open array
  1459. - typecast from pointer to array }
  1460. fromdef:=ttypeconvnode(hp).left.resultdef;
  1461. todef:=hp.resultdef;
  1462. { typeconversions on the assignment side must keep
  1463. left.location the same }
  1464. if not((target_info.system in systems_jvm) and
  1465. (gotsubscript or gotvec)) then
  1466. begin
  1467. ttypeconvnode(hp).assignment_side:=true;
  1468. if not assigned(typeconvs) then
  1469. typeconvs:=tfpobjectlist.create(false);
  1470. typeconvs.add(hp);
  1471. end;
  1472. { in managed VMs, you cannot typecast formaldef when assigning
  1473. to it, see http://hallvards.blogspot.com/2007/10/dn4dp24-net-vs-win32-untyped-parameters.html }
  1474. if (target_info.system in systems_managed_vm) and
  1475. (fromdef.typ=formaldef) then
  1476. begin
  1477. if report_errors then
  1478. CGMessagePos(hp.fileinfo,type_e_no_managed_formal_assign_typecast);
  1479. mayberesettypeconvs;
  1480. exit;
  1481. end
  1482. else if not((nf_absolute in ttypeconvnode(hp).flags) or
  1483. ttypeconvnode(hp).target_specific_general_typeconv or
  1484. ((nf_explicit in hp.flags) and
  1485. ttypeconvnode(hp).target_specific_explicit_typeconv) or
  1486. (fromdef.typ=formaldef) or
  1487. is_void(fromdef) or
  1488. is_open_array(fromdef) or
  1489. is_open_array(todef) or
  1490. ((fromdef.typ=pointerdef) and (todef.typ=arraydef)) or
  1491. (def_is_related(fromdef,todef))) then
  1492. begin
  1493. if (fromdef.size<>todef.size) then
  1494. begin
  1495. { in TP it is allowed to typecast to smaller types. But the variable can't
  1496. be in a register }
  1497. if (m_tp7 in current_settings.modeswitches) or
  1498. (todef.size<fromdef.size) then
  1499. make_not_regable(hp,[ra_addr_regable])
  1500. else
  1501. if report_errors then
  1502. CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
  1503. end
  1504. {$ifdef llvm}
  1505. { we can never typecast a non-memory value on the assignment
  1506. side in llvm }
  1507. else
  1508. make_not_regable(hp,[ra_addr_regable])
  1509. {$endif llvm}
  1510. end;
  1511. { don't allow assignments to typeconvs that need special code }
  1512. if not(gotsubscript or gotvec) and
  1513. not(ttypeconvnode(hp).assign_allowed) then
  1514. begin
  1515. if report_errors then
  1516. CGMessagePos(hp.fileinfo,errmsg);
  1517. mayberesettypeconvs;
  1518. exit;
  1519. end;
  1520. case hp.resultdef.typ of
  1521. arraydef :
  1522. begin
  1523. { pointer -> array conversion is done then we need to see it
  1524. as a deref, because a ^ is then not required anymore }
  1525. if ttypeconvnode(hp).convtype=tc_pointer_2_array then
  1526. begin
  1527. valid_for_assign:=true;
  1528. mayberesettypeconvs;
  1529. exit
  1530. end;
  1531. end;
  1532. else
  1533. ;
  1534. end;
  1535. hp:=ttypeconvnode(hp).left;
  1536. end;
  1537. vecn :
  1538. begin
  1539. if (tvecnode(hp).right.nodetype=rangen) and
  1540. not(valid_range in opts) then
  1541. begin
  1542. if report_errors then
  1543. CGMessagePos(tvecnode(hp).right.fileinfo,parser_e_illegal_expression);
  1544. mayberesettypeconvs;
  1545. exit;
  1546. end;
  1547. if { only check for first (= outermost) vec node }
  1548. not gotvec and
  1549. not(valid_packed in opts) and
  1550. (tvecnode(hp).left.resultdef.typ = arraydef) and
  1551. (ado_IsBitPacked in tarraydef(tvecnode(hp).left.resultdef).arrayoptions) and
  1552. ((tarraydef(tvecnode(hp).left.resultdef).elepackedbitsize mod 8 <> 0) or
  1553. (is_ordinal(tarraydef(tvecnode(hp).left.resultdef).elementdef) and
  1554. not ispowerof2(tarraydef(tvecnode(hp).left.resultdef).elepackedbitsize div 8,temp))) then
  1555. begin
  1556. if report_errors then
  1557. if (valid_property in opts) then
  1558. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_loop)
  1559. else
  1560. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_var_addr);
  1561. mayberesettypeconvs;
  1562. exit;
  1563. end;
  1564. gotvec:=true;
  1565. { accesses to dyn. arrays override read only access in delphi
  1566. -- now also in FPC, because the elements of a dynamic array
  1567. returned by a function can also be changed, or you can
  1568. assign the dynamic array to a variable and then change
  1569. its elements anyway }
  1570. if is_dynamic_array(tunarynode(hp).left.resultdef) then
  1571. begin
  1572. result:=true;
  1573. mayberesettypeconvs;
  1574. exit;
  1575. end;
  1576. hp:=tunarynode(hp).left;
  1577. end;
  1578. asn :
  1579. begin
  1580. { asn can't be assigned directly, it returns the value in a register instead
  1581. of reference. }
  1582. if not(gotsubscript or gotvec) then
  1583. begin
  1584. if report_errors then
  1585. CGMessagePos(hp.fileinfo,errmsg);
  1586. mayberesettypeconvs;
  1587. exit;
  1588. end;
  1589. hp:=tunarynode(hp).left;
  1590. end;
  1591. subscriptn :
  1592. begin
  1593. { only check first (= outermost) subscriptn }
  1594. if not gotsubscript and
  1595. not(valid_packed in opts) and
  1596. is_packed_record_or_object(tsubscriptnode(hp).left.resultdef) and
  1597. ((tsubscriptnode(hp).vs.fieldoffset mod 8 <> 0) or
  1598. (is_ordinal(tsubscriptnode(hp).resultdef) and
  1599. not ispowerof2(tsubscriptnode(hp).resultdef.packedbitsize div 8,temp))) then
  1600. begin
  1601. if report_errors then
  1602. if (valid_property in opts) then
  1603. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_loop)
  1604. else
  1605. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_var_addr);
  1606. mayberesettypeconvs;
  1607. exit;
  1608. end;
  1609. { check for final fields }
  1610. if (tsubscriptnode(hp).vs.varspez=vs_final) and
  1611. not constaccessok(tsubscriptnode(hp).vs) then
  1612. begin
  1613. mayberesettypeconvs;
  1614. exit;
  1615. end;
  1616. { if we assign something to a field of a record that is not
  1617. regable, then then the record can't be kept in a regvar,
  1618. because we will force the record into memory for this
  1619. subscript operation (to a temp location, so the assignment
  1620. will happen to the temp and be lost) }
  1621. if not gotsubscript and
  1622. not gotvec and
  1623. not tstoreddef(hp.resultdef).is_intregable then
  1624. make_not_regable(hp,[ra_addr_regable]);
  1625. gotsubscript:=true;
  1626. { loop counter? }
  1627. if not(Valid_Const in opts) and
  1628. (vo_is_loop_counter in tsubscriptnode(hp).vs.varoptions) then
  1629. begin
  1630. if report_errors then
  1631. CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname);
  1632. mayberesettypeconvs;
  1633. exit;
  1634. end;
  1635. { implicit pointer object types result in dereferencing }
  1636. hp:=tsubscriptnode(hp).left;
  1637. if is_implicit_pointer_object_type(hp.resultdef) or
  1638. (hp.resultdef.typ=classrefdef) then
  1639. begin
  1640. valid_for_assign:=true;
  1641. mayberesettypeconvs;
  1642. exit
  1643. end;
  1644. end;
  1645. muln,
  1646. divn,
  1647. andn,
  1648. xorn,
  1649. orn,
  1650. notn,
  1651. subn,
  1652. addn :
  1653. begin
  1654. { Temp strings are stored in memory, for compatibility with
  1655. delphi only }
  1656. if (m_delphi in current_settings.modeswitches) and
  1657. ((valid_addr in opts) or
  1658. (valid_const in opts)) and
  1659. (hp.resultdef.typ=stringdef) then
  1660. result:=true
  1661. else
  1662. if report_errors then
  1663. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1664. mayberesettypeconvs;
  1665. exit;
  1666. end;
  1667. niln,
  1668. pointerconstn :
  1669. begin
  1670. if report_errors then
  1671. CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
  1672. mayberesettypeconvs;
  1673. exit;
  1674. end;
  1675. ordconstn,
  1676. realconstn :
  1677. begin
  1678. { these constants will be passed by value }
  1679. if report_errors then
  1680. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1681. mayberesettypeconvs;
  1682. exit;
  1683. end;
  1684. arrayconstructorn,
  1685. setconstn,
  1686. stringconstn,
  1687. guidconstn :
  1688. begin
  1689. { these constants will be passed by reference }
  1690. if valid_const in opts then
  1691. result:=true
  1692. else
  1693. if report_errors then
  1694. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1695. mayberesettypeconvs;
  1696. exit;
  1697. end;
  1698. addrn :
  1699. begin
  1700. if report_errors then
  1701. CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
  1702. mayberesettypeconvs;
  1703. exit;
  1704. end;
  1705. blockn,
  1706. calln :
  1707. begin
  1708. if (hp.nodetype=calln) or
  1709. (nf_no_lvalue in hp.flags) then
  1710. begin
  1711. { Temp strings are stored in memory, for compatibility with
  1712. delphi only }
  1713. if (m_delphi in current_settings.modeswitches) and
  1714. (valid_addr in opts) and
  1715. (hp.resultdef.typ=stringdef) then
  1716. result:=true
  1717. else
  1718. if ([valid_const,valid_addr] * opts = [valid_const]) then
  1719. result:=true
  1720. else
  1721. if report_errors then
  1722. CGMessagePos(hp.fileinfo,errmsg);
  1723. mayberesettypeconvs;
  1724. exit;
  1725. end
  1726. else
  1727. begin
  1728. hp2:=tblocknode(hp).statements;
  1729. if assigned(hp2) then
  1730. begin
  1731. if hp2.nodetype<>statementn then
  1732. internalerror(2006110801);
  1733. while assigned(tstatementnode(hp2).next) do
  1734. hp2:=tstatementnode(hp2).next;
  1735. hp:=tstatementnode(hp2).statement;
  1736. end
  1737. else
  1738. begin
  1739. if report_errors then
  1740. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1741. mayberesettypeconvs;
  1742. exit;
  1743. end;
  1744. end;
  1745. end;
  1746. inlinen :
  1747. begin
  1748. if ((valid_const in opts) and
  1749. (tinlinenode(hp).inlinenumber in [in_typeof_x])) or
  1750. (tinlinenode(hp).inlinenumber in [in_unaligned_x,in_aligned_x]) then
  1751. result:=true
  1752. else
  1753. if report_errors then
  1754. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1755. mayberesettypeconvs;
  1756. exit;
  1757. end;
  1758. nothingn :
  1759. begin
  1760. { generics can generate nothing nodes, just allow everything }
  1761. if df_generic in current_procinfo.procdef.defoptions then
  1762. result:=true
  1763. else if report_errors then
  1764. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1765. mayberesettypeconvs;
  1766. exit;
  1767. end;
  1768. loadn :
  1769. begin
  1770. case tloadnode(hp).symtableentry.typ of
  1771. absolutevarsym,
  1772. staticvarsym,
  1773. localvarsym,
  1774. paravarsym :
  1775. begin
  1776. { loop counter? }
  1777. if not(Valid_Const in opts) and
  1778. (vo_is_loop_counter in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
  1779. begin
  1780. if report_errors then
  1781. CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname);
  1782. mayberesettypeconvs;
  1783. exit;
  1784. end;
  1785. { read-only variable? }
  1786. if (tabstractvarsym(tloadnode(hp).symtableentry).varspez in [vs_const,vs_constref,vs_final]) then
  1787. begin
  1788. result:=constaccessok(tabstractvarsym(tloadnode(hp).symtableentry));
  1789. mayberesettypeconvs;
  1790. exit;
  1791. end;
  1792. result:=true;
  1793. mayberesettypeconvs;
  1794. exit;
  1795. end;
  1796. procsym :
  1797. begin
  1798. if (Valid_Const in opts) then
  1799. result:=true
  1800. else
  1801. if report_errors then
  1802. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1803. mayberesettypeconvs;
  1804. exit;
  1805. end;
  1806. labelsym :
  1807. begin
  1808. if (Valid_Addr in opts) then
  1809. result:=true
  1810. else
  1811. if report_errors then
  1812. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1813. mayberesettypeconvs;
  1814. exit;
  1815. end;
  1816. constsym:
  1817. begin
  1818. if (tconstsym(tloadnode(hp).symtableentry).consttyp=constresourcestring) and
  1819. (valid_addr in opts) then
  1820. result:=true
  1821. else
  1822. if report_errors then
  1823. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1824. mayberesettypeconvs;
  1825. exit;
  1826. end;
  1827. else
  1828. begin
  1829. if report_errors then
  1830. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1831. mayberesettypeconvs;
  1832. exit;
  1833. end;
  1834. end;
  1835. end;
  1836. else
  1837. begin
  1838. if report_errors then
  1839. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1840. mayberesettypeconvs;
  1841. exit;
  1842. end;
  1843. end;
  1844. end;
  1845. mayberesettypeconvs;
  1846. end;
  1847. function valid_for_var(p:tnode; report_errors: boolean):boolean;
  1848. begin
  1849. valid_for_var:=valid_for_assign(p,[valid_range],report_errors);
  1850. end;
  1851. function valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
  1852. begin
  1853. valid_for_formal_var:=valid_for_assign(p,[valid_void,valid_range],report_errors);
  1854. end;
  1855. function valid_for_formal_constref(p : tnode; report_errors: boolean) : boolean;
  1856. begin
  1857. valid_for_formal_constref:=(p.resultdef.typ=formaldef) or
  1858. valid_for_assign(p,[valid_void,valid_range],report_errors);
  1859. end;
  1860. function valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
  1861. begin
  1862. valid_for_formal_const:=(p.resultdef.typ=formaldef) or
  1863. valid_for_assign(p,[valid_void,valid_const,valid_property,valid_range],report_errors);
  1864. end;
  1865. function valid_for_assignment(p:tnode; report_errors: boolean):boolean;
  1866. begin
  1867. valid_for_assignment:=valid_for_assign(p,[valid_property,valid_packed],report_errors);
  1868. end;
  1869. function valid_for_loopvar(p:tnode; report_errors: boolean):boolean;
  1870. begin
  1871. valid_for_loopvar:=valid_for_assign(p,[valid_property],report_errors);
  1872. end;
  1873. function valid_for_addr(p : tnode; report_errors: boolean) : boolean;
  1874. begin
  1875. result:=valid_for_assign(p,[valid_const,valid_addr,valid_void],report_errors);
  1876. end;
  1877. procedure var_para_allowed(var eq:tequaltype;def_from,def_to:Tdef; fromnode: tnode);
  1878. begin
  1879. { Note: eq must be already valid, it will only be updated! }
  1880. case def_to.typ of
  1881. formaldef :
  1882. begin
  1883. { all types can be passed to a formaldef,
  1884. but it is not the prefered way }
  1885. if not is_constnode(fromnode) then
  1886. eq:=te_convert_l6
  1887. else
  1888. eq:=te_incompatible;
  1889. end;
  1890. orddef :
  1891. begin
  1892. { allows conversion from word to integer and
  1893. byte to shortint, but only for TP7 compatibility }
  1894. if (m_tp7 in current_settings.modeswitches) and
  1895. (def_from.typ=orddef) and
  1896. (def_from.size=def_to.size) then
  1897. eq:=te_convert_l1;
  1898. end;
  1899. arraydef :
  1900. begin
  1901. if is_open_array(def_to) then
  1902. begin
  1903. if is_dynamic_array(def_from) and
  1904. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  1905. eq:=te_convert_l2
  1906. else
  1907. if equal_defs(def_from,tarraydef(def_to).elementdef) then
  1908. eq:=te_convert_l3;
  1909. end;
  1910. end;
  1911. pointerdef :
  1912. begin
  1913. { an implicit pointer conversion is allowed }
  1914. if (def_from.typ=pointerdef) then
  1915. eq:=te_convert_l1;
  1916. end;
  1917. stringdef :
  1918. begin
  1919. { all shortstrings are allowed, size is not important }
  1920. if is_shortstring(def_from) and
  1921. is_shortstring(def_to) then
  1922. eq:=te_equal;
  1923. end;
  1924. objectdef :
  1925. begin
  1926. { child objects can be also passed }
  1927. { in non-delphi mode, otherwise }
  1928. { they must match exactly, except }
  1929. { if they are objects }
  1930. if (def_from.typ=objectdef) and
  1931. (
  1932. (tobjectdef(def_from).objecttype=odt_object) and
  1933. (tobjectdef(def_to).objecttype=odt_object)
  1934. ) and
  1935. (def_is_related(tobjectdef(def_from),tobjectdef(def_to))) then
  1936. eq:=te_convert_l1;
  1937. end;
  1938. filedef :
  1939. begin
  1940. { an implicit file conversion is also allowed }
  1941. { from a typed file to an untyped one }
  1942. if (def_from.typ=filedef) and
  1943. (tfiledef(def_from).filetyp = ft_typed) and
  1944. (tfiledef(def_to).filetyp = ft_untyped) then
  1945. eq:=te_convert_l1;
  1946. end;
  1947. else
  1948. ;
  1949. end;
  1950. end;
  1951. procedure para_allowed(var eq:tequaltype;p:tcallparanode;def_to:tdef);
  1952. var
  1953. acn: tarrayconstructornode;
  1954. realprocdef: tprocdef;
  1955. tmpeq: tequaltype;
  1956. begin
  1957. { Note: eq must be already valid, it will only be updated! }
  1958. case def_to.typ of
  1959. stringdef :
  1960. begin
  1961. { to support ansi/long/wide strings in a proper way }
  1962. { string and string[10] are assumed as equal }
  1963. { when searching the correct overloaded procedure }
  1964. if (p.resultdef.typ=stringdef) and
  1965. (tstringdef(def_to).stringtype=tstringdef(p.resultdef).stringtype) and
  1966. (tstringdef(def_to).encoding=tstringdef(p.resultdef).encoding) then
  1967. eq:=te_equal
  1968. end;
  1969. formaldef,
  1970. setdef :
  1971. begin
  1972. { set can also be a not yet converted array constructor }
  1973. if (p.resultdef.typ=arraydef) and
  1974. is_array_constructor(p.resultdef) and
  1975. not is_variant_array(p.resultdef) then
  1976. eq:=te_equal;
  1977. end;
  1978. procvardef :
  1979. begin
  1980. tmpeq:=te_incompatible;
  1981. { in tp/macpas mode proc -> procvar is allowed }
  1982. if ((m_tp_procvar in current_settings.modeswitches) or
  1983. (m_mac_procvar in current_settings.modeswitches)) and
  1984. (p.left.nodetype=calln) then
  1985. tmpeq:=proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def_to),false);
  1986. if (tmpeq=te_incompatible) and
  1987. (m_nested_procvars in current_settings.modeswitches) and
  1988. is_proc2procvar_load(p.left,realprocdef) then
  1989. tmpeq:=proc_to_procvar_equal(realprocdef,tprocvardef(def_to),false);
  1990. if (tmpeq=te_incompatible) and
  1991. (m_mac in current_settings.modeswitches) and
  1992. is_ambiguous_funcret_load(p.left,realprocdef) then
  1993. tmpeq:=proc_to_procvar_equal(realprocdef,tprocvardef(def_to),false);
  1994. if tmpeq<>te_incompatible then
  1995. eq:=tmpeq;
  1996. end;
  1997. arraydef :
  1998. begin
  1999. { an arrayconstructor of proccalls may have to be converted to
  2000. an array of procvars }
  2001. if ((m_tp_procvar in current_settings.modeswitches) or
  2002. (m_mac_procvar in current_settings.modeswitches)) and
  2003. (tarraydef(def_to).elementdef.typ=procvardef) and
  2004. is_array_constructor(p.resultdef) and
  2005. not is_variant_array(p.resultdef) then
  2006. begin
  2007. acn:=tarrayconstructornode(p.left);
  2008. if assigned(acn.left) then
  2009. begin
  2010. eq:=te_exact;
  2011. while assigned(acn) and
  2012. (eq<>te_incompatible) do
  2013. begin
  2014. if (acn.left.nodetype=calln) then
  2015. tmpeq:=proc_to_procvar_equal(tprocdef(tcallnode(acn.left).procdefinition),tprocvardef(tarraydef(def_to).elementdef),false)
  2016. else
  2017. tmpeq:=compare_defs(acn.left.resultdef,tarraydef(def_to).elementdef,acn.left.nodetype);
  2018. if tmpeq<eq then
  2019. eq:=tmpeq;
  2020. acn:=tarrayconstructornode(acn.right);
  2021. end;
  2022. end
  2023. end;
  2024. end;
  2025. else
  2026. ;
  2027. end;
  2028. end;
  2029. function allowenumop(nt:tnodetype):boolean;
  2030. begin
  2031. result:=(nt in [equaln,unequaln,ltn,lten,gtn,gten]) or
  2032. ((cs_allow_enum_calc in current_settings.localswitches) and
  2033. (nt in [addn,subn]));
  2034. end;
  2035. {****************************************************************************
  2036. TCallCandidates
  2037. ****************************************************************************}
  2038. constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
  2039. begin
  2040. if not assigned(sym) then
  2041. internalerror(200411015);
  2042. FOperator:=NOTOKEN;
  2043. FProcsym:=sym;
  2044. FProcsymtable:=st;
  2045. FParanode:=ppn;
  2046. FIgnoredCandidateProcs:=tfpobjectlist.create(false);
  2047. create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited,spezcontext);
  2048. end;
  2049. constructor tcallcandidates.create_operator(op:ttoken;ppn:tnode);
  2050. begin
  2051. FOperator:=op;
  2052. FProcsym:=nil;
  2053. FProcsymtable:=nil;
  2054. FParanode:=ppn;
  2055. FIgnoredCandidateProcs:=tfpobjectlist.create(false);
  2056. create_candidate_list(false,false,false,false,false,false,nil);
  2057. end;
  2058. destructor tcallcandidates.destroy;
  2059. var
  2060. hpnext,
  2061. hp : pcandidate;
  2062. psym : tprocsym;
  2063. i : longint;
  2064. begin
  2065. FIgnoredCandidateProcs.free;
  2066. hp:=FCandidateProcs;
  2067. while assigned(hp) do
  2068. begin
  2069. hpnext:=hp^.next;
  2070. { free those procdef specializations that are not owned (thus were discarded) }
  2071. if hp^.data.is_specialization and not hp^.data.is_registered then
  2072. begin
  2073. { also remove the procdef from its symbol's procdeflist }
  2074. psym:=tprocsym(hp^.data.procsym);
  2075. for i:=0 to psym.procdeflist.count-1 do
  2076. begin
  2077. if psym.procdeflist[i]=hp^.data then
  2078. begin
  2079. psym.procdeflist.delete(i);
  2080. break;
  2081. end;
  2082. end;
  2083. hp^.data.free;
  2084. end;
  2085. dispose(hp);
  2086. hp:=hpnext;
  2087. end;
  2088. end;
  2089. procedure tcallcandidates.collect_overloads_in_struct(structdef:tabstractrecorddef;ProcdefOverloadList:TFPObjectList;searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
  2090. var
  2091. changedhierarchy : boolean;
  2092. function processprocsym(srsym:tprocsym; out foundanything: boolean):boolean;
  2093. var
  2094. j : integer;
  2095. pd : tprocdef;
  2096. begin
  2097. { add all definitions }
  2098. result:=false;
  2099. foundanything:=false;
  2100. for j:=0 to srsym.ProcdefList.Count-1 do
  2101. begin
  2102. pd:=tprocdef(srsym.ProcdefList[j]);
  2103. if not maybe_specialize(pd,spezcontext) then
  2104. continue;
  2105. if (po_ignore_for_overload_resolution in pd.procoptions) then
  2106. begin
  2107. FIgnoredCandidateProcs.add(pd);
  2108. continue;
  2109. end;
  2110. { in case of anonymous inherited, only match procdefs identical
  2111. to the current one (apart from hidden parameters), rather than
  2112. anything compatible to the parameters -- except in case of
  2113. the presence of a messagestr/int, in which case those have to
  2114. match exactly }
  2115. if anoninherited then
  2116. if po_msgint in current_procinfo.procdef.procoptions then
  2117. begin
  2118. if not(po_msgint in pd.procoptions) or
  2119. (pd.messageinf.i<>current_procinfo.procdef.messageinf.i) then
  2120. continue
  2121. end
  2122. else if po_msgstr in current_procinfo.procdef.procoptions then
  2123. begin
  2124. if not(po_msgstr in pd.procoptions) or
  2125. (pd.messageinf.str^<>current_procinfo.procdef.messageinf.str^) then
  2126. continue
  2127. end
  2128. else if (compare_paras(current_procinfo.procdef.paras,pd.paras,cp_all,[cpo_ignorehidden])<te_equal) then
  2129. continue;
  2130. foundanything:=true;
  2131. { Store first procsym found }
  2132. if not assigned(FProcsym) then
  2133. FProcsym:=tprocsym(srsym);
  2134. if po_overload in pd.procoptions then
  2135. result:=true;
  2136. { if the hierarchy had been changed we need to check for duplicates }
  2137. if not changedhierarchy or (ProcdefOverloadList.IndexOf(pd)<0) then
  2138. ProcdefOverloadList.Add(pd);
  2139. end;
  2140. end;
  2141. function processhelper(hashedid:THashedIDString;helperdef:tobjectdef):boolean;
  2142. var
  2143. srsym : tsym;
  2144. hasoverload,foundanything : boolean;
  2145. begin
  2146. result:=false;
  2147. srsym:=nil;
  2148. hasoverload:=false;
  2149. while assigned(helperdef) do
  2150. begin
  2151. srsym:=tsym(helperdef.symtable.FindWithHash(hashedid));
  2152. if assigned(srsym) and
  2153. { Delphi allows hiding a property by a procedure with the same name }
  2154. (srsym.typ=procsym) then
  2155. begin
  2156. hasoverload:=processprocsym(tprocsym(srsym),foundanything);
  2157. { when there is no explicit overload we stop searching }
  2158. if foundanything and
  2159. not hasoverload then
  2160. break;
  2161. end;
  2162. helperdef:=helperdef.childof;
  2163. end;
  2164. if not hasoverload and assigned(srsym) then
  2165. exit(true);
  2166. end;
  2167. var
  2168. srsym : tsym;
  2169. hashedid : THashedIDString;
  2170. hasoverload,
  2171. foundanything : boolean;
  2172. extendeddef : tabstractrecorddef;
  2173. helperdef : tobjectdef;
  2174. helperlist : TFPObjectList;
  2175. i : integer;
  2176. begin
  2177. if FOperator=NOTOKEN then
  2178. hashedid.id:=FProcsym.name
  2179. else
  2180. hashedid.id:=overloaded_names[FOperator];
  2181. hasoverload:=false;
  2182. extendeddef:=nil;
  2183. changedhierarchy:=false;
  2184. while assigned(structdef) do
  2185. begin
  2186. { first search in helpers for this type }
  2187. if ((structdef.typ=recorddef) or
  2188. (
  2189. (structdef.typ=objectdef) and
  2190. (tobjectdef(structdef).objecttype in objecttypes_with_helpers)
  2191. )
  2192. )
  2193. and searchhelpers then
  2194. begin
  2195. if m_multi_helpers in current_settings.modeswitches then
  2196. begin
  2197. helperlist:=get_objectpascal_helpers(structdef);
  2198. if assigned(helperlist) and (helperlist.count>0) then
  2199. begin
  2200. i:=helperlist.count-1;
  2201. repeat
  2202. helperdef:=tobjectdef(helperlist[i]);
  2203. if (helperdef.owner.symtabletype in [staticsymtable,globalsymtable]) or
  2204. is_visible_for_object(helperdef.typesym,helperdef) then
  2205. if processhelper(hashedid,helperdef) then
  2206. exit;
  2207. dec(i);
  2208. until (i<0);
  2209. end;
  2210. end
  2211. else if search_last_objectpascal_helper(structdef,nil,helperdef) and processhelper(hashedid,helperdef) then
  2212. exit;
  2213. end;
  2214. { now search in the type itself }
  2215. srsym:=tsym(structdef.symtable.FindWithHash(hashedid));
  2216. if assigned(srsym) and
  2217. { Delphi allows hiding a property by a procedure with the same name }
  2218. (srsym.typ=procsym) then
  2219. begin
  2220. hasoverload:=processprocsym(tprocsym(srsym),foundanything);
  2221. { when there is no explicit overload we stop searching }
  2222. if foundanything and
  2223. not hasoverload then
  2224. break;
  2225. end;
  2226. if is_objectpascal_helper(structdef) and
  2227. (
  2228. (tobjectdef(structdef).extendeddef.typ=recorddef) or
  2229. (
  2230. (tobjectdef(structdef).extendeddef.typ=objectdef) and
  2231. (tobjectdef(tobjectdef(structdef).extendeddef).objecttype in objecttypes_with_helpers)
  2232. )
  2233. ) then
  2234. begin
  2235. { remember the first extendeddef of the hierarchy }
  2236. if not assigned(extendeddef) then
  2237. extendeddef:=tabstractrecorddef(tobjectdef(structdef).extendeddef);
  2238. { search methods in the extended type as well }
  2239. srsym:=tprocsym(tabstractrecorddef(tobjectdef(structdef).extendeddef).symtable.FindWithHash(hashedid));
  2240. if assigned(srsym) and
  2241. { Delphi allows hiding a property by a procedure with the same name }
  2242. (srsym.typ=procsym) then
  2243. begin
  2244. hasoverload:=processprocsym(tprocsym(srsym),foundanything);
  2245. { when there is no explicit overload we stop searching }
  2246. if foundanything and
  2247. not hasoverload then
  2248. break;
  2249. end;
  2250. end;
  2251. { next parent }
  2252. if (structdef.typ=objectdef) then
  2253. structdef:=tobjectdef(structdef).childof
  2254. else
  2255. structdef:=nil;
  2256. { switch over to the extended def's hierarchy }
  2257. if not assigned(structdef) and assigned(extendeddef) then
  2258. begin
  2259. structdef:=extendeddef;
  2260. extendeddef:=nil;
  2261. changedhierarchy:=true;
  2262. end;
  2263. end;
  2264. end;
  2265. procedure tcallcandidates.collect_overloads_in_units(ProcdefOverloadList:TFPObjectList; objcidcall,explicitunit: boolean;spezcontext:tspecializationcontext);
  2266. var
  2267. j : integer;
  2268. pd : tprocdef;
  2269. srsymtable : TSymtable;
  2270. srsym : tsym;
  2271. checkstack : psymtablestackitem;
  2272. hashedid : THashedIDString;
  2273. hasoverload : boolean;
  2274. begin
  2275. { we search all overloaded operator definitions in the symtablestack. The found
  2276. entries are only added to the procs list and not the procsym, because
  2277. the list can change in every situation }
  2278. if FOperator=NOTOKEN then
  2279. begin
  2280. if not objcidcall then
  2281. hashedid.id:=FProcsym.name
  2282. else
  2283. hashedid.id:=class_helper_prefix+FProcsym.name;
  2284. end
  2285. else
  2286. hashedid.id:=overloaded_names[FOperator];
  2287. checkstack:=symtablestack.stack;
  2288. if assigned(FProcsymtable) then
  2289. begin
  2290. while assigned(checkstack) and
  2291. (checkstack^.symtable<>FProcsymtable) do
  2292. checkstack:=checkstack^.next;
  2293. end;
  2294. while assigned(checkstack) do
  2295. begin
  2296. srsymtable:=checkstack^.symtable;
  2297. { if the unit in which the routine has to be searched has been
  2298. specified explicitly, stop searching after its symtable(s) have
  2299. been checked (can be both the static and the global symtable
  2300. in case it's the current unit itself) }
  2301. if explicitunit and
  2302. (FProcsymtable.symtabletype in [globalsymtable,staticsymtable]) and
  2303. (srsymtable.moduleid<>FProcsymtable.moduleid) then
  2304. break;
  2305. if (srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable]) and
  2306. (
  2307. (FOperator=NOTOKEN) or
  2308. (sto_has_operator in srsymtable.tableoptions)
  2309. )
  2310. then
  2311. begin
  2312. srsym:=tsym(srsymtable.FindWithHash(hashedid));
  2313. if assigned(srsym) and
  2314. (srsym.typ=procsym) then
  2315. begin
  2316. { add all definitions }
  2317. hasoverload:=false;
  2318. for j:=0 to tprocsym(srsym).ProcdefList.Count-1 do
  2319. begin
  2320. pd:=tprocdef(tprocsym(srsym).ProcdefList[j]);
  2321. if not maybe_specialize(pd,spezcontext) then
  2322. continue;
  2323. if (po_ignore_for_overload_resolution in pd.procoptions) then
  2324. begin
  2325. FIgnoredCandidateProcs.add(pd);
  2326. continue;
  2327. end;
  2328. { Store first procsym found }
  2329. if not assigned(FProcsym) then
  2330. FProcsym:=tprocsym(srsym);
  2331. if po_overload in pd.procoptions then
  2332. hasoverload:=true;
  2333. ProcdefOverloadList.Add(pd);
  2334. end;
  2335. { when there is no explicit overload we stop searching,
  2336. except for Objective-C methods called via id }
  2337. if not hasoverload and
  2338. not objcidcall then
  2339. break;
  2340. end;
  2341. end;
  2342. checkstack:=checkstack^.next
  2343. end;
  2344. end;
  2345. procedure tcallcandidates.create_candidate_list(ignorevisibility,allowdefaultparas,objcidcall,explicitunit,searchhelpers,anoninherited:boolean;spezcontext:tspecializationcontext);
  2346. var
  2347. j : integer;
  2348. pd : tprocdef;
  2349. hp : pcandidate;
  2350. pt : tcallparanode;
  2351. found,
  2352. added : boolean;
  2353. st : TSymtable;
  2354. contextstructdef : tabstractrecorddef;
  2355. ProcdefOverloadList : TFPObjectList;
  2356. cpoptions : tcompare_paras_options;
  2357. begin
  2358. FCandidateProcs:=nil;
  2359. { Find all available overloads for this procsym }
  2360. ProcdefOverloadList:=TFPObjectList.Create(false);
  2361. if not objcidcall and
  2362. (FOperator=NOTOKEN) and
  2363. (FProcsym.owner.symtabletype in [objectsymtable,recordsymtable]) then
  2364. collect_overloads_in_struct(tabstractrecorddef(FProcsym.owner.defowner),ProcdefOverloadList,searchhelpers,anoninherited,spezcontext)
  2365. else
  2366. if (FOperator<>NOTOKEN) then
  2367. begin
  2368. { check operands and if they contain records then search in records,
  2369. then search in unit }
  2370. pt:=tcallparanode(FParaNode);
  2371. while assigned(pt) do
  2372. begin
  2373. if (pt.resultdef.typ=recorddef) and
  2374. (sto_has_operator in tabstractrecorddef(pt.resultdef).symtable.tableoptions) then
  2375. collect_overloads_in_struct(tabstractrecorddef(pt.resultdef),ProcdefOverloadList,searchhelpers,anoninherited,spezcontext);
  2376. pt:=tcallparanode(pt.right);
  2377. end;
  2378. collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit,spezcontext);
  2379. end
  2380. else
  2381. collect_overloads_in_units(ProcdefOverloadList,objcidcall,explicitunit,spezcontext);
  2382. { determine length of parameter list.
  2383. for operators also enable the variant-operators if
  2384. a variant parameter is passed }
  2385. FParalength:=0;
  2386. FAllowVariant:=(FOperator=NOTOKEN);
  2387. pt:=tcallparanode(FParaNode);
  2388. while assigned(pt) do
  2389. begin
  2390. if (pt.resultdef.typ=variantdef) then
  2391. FAllowVariant:=true;
  2392. inc(FParalength);
  2393. pt:=tcallparanode(pt.right);
  2394. end;
  2395. { when the class passed is defined in this unit we
  2396. need to use the scope of that class. This is a trick
  2397. that can be used to access protected members in other
  2398. units. At least kylix supports it this way (PFV) }
  2399. if assigned(FProcSymtable) and
  2400. (
  2401. (FProcSymtable.symtabletype in [ObjectSymtable,recordsymtable]) or
  2402. ((FProcSymtable.symtabletype=withsymtable) and
  2403. (FProcSymtable.defowner.typ in [objectdef,recorddef]))
  2404. ) and
  2405. (FProcSymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable,objectsymtable,recordsymtable]) and
  2406. FProcSymtable.defowner.owner.iscurrentunit then
  2407. contextstructdef:=tabstractrecorddef(FProcSymtable.defowner)
  2408. else
  2409. contextstructdef:=current_structdef;
  2410. { symtable is needed later to calculate the distance }
  2411. if assigned(FProcsym) then
  2412. st:=FProcsym.Owner
  2413. else
  2414. st:=nil;
  2415. { Process all found overloads }
  2416. for j:=0 to ProcdefOverloadList.Count-1 do
  2417. begin
  2418. pd:=tprocdef(ProcdefOverloadList[j]);
  2419. added:=false;
  2420. { only when the # of parameter are supported by the procedure and
  2421. it is visible }
  2422. {$ifdef DISABLE_FAST_OVERLOAD_PATCH}
  2423. if (FParalength>=pd.minparacount) and
  2424. {$else}
  2425. if (pd.seenmarker<>pointer(self)) and (FParalength>=pd.minparacount) and
  2426. {$endif}
  2427. (
  2428. (
  2429. allowdefaultparas and
  2430. (
  2431. (FParalength<=pd.maxparacount) or
  2432. (po_varargs in pd.procoptions)
  2433. )
  2434. ) or
  2435. (
  2436. not allowdefaultparas and
  2437. (FParalength=pd.maxparacount)
  2438. )
  2439. ) and
  2440. (
  2441. ignorevisibility or
  2442. (
  2443. pd.is_specialization and not assigned(pd.owner) and
  2444. (
  2445. not (pd.genericdef.owner.symtabletype in [objectsymtable,recordsymtable]) or
  2446. is_visible_for_object(tprocdef(pd.genericdef),contextstructdef)
  2447. )
  2448. ) or
  2449. (
  2450. assigned(pd.owner) and
  2451. (
  2452. not (pd.owner.symtabletype in [objectsymtable,recordsymtable]) or
  2453. is_visible_for_object(pd,contextstructdef)
  2454. )
  2455. )
  2456. ) then
  2457. begin
  2458. { don't add duplicates, only compare visible parameters for the user }
  2459. cpoptions:=[cpo_ignorehidden];
  2460. if (po_compilerproc in pd.procoptions) then
  2461. cpoptions:=cpoptions+[cpo_compilerproc];
  2462. if (po_rtlproc in pd.procoptions) then
  2463. cpoptions:=cpoptions+[cpo_rtlproc];
  2464. found:=false;
  2465. hp:=FCandidateProcs;
  2466. {$ifdef DISABLE_FAST_OVERLOAD_PATCH}
  2467. while assigned(hp) do
  2468. begin
  2469. if (compare_paras(hp^.data.paras,pd.paras,cp_value_equal_const,cpoptions)>=te_equal) and
  2470. (not(po_objc in pd.procoptions) or
  2471. (pd.messageinf.str^=hp^.data.messageinf.str^)) then
  2472. begin
  2473. found:=true;
  2474. break;
  2475. end;
  2476. hp:=hp^.next;
  2477. end;
  2478. {$endif}
  2479. if not found then
  2480. begin
  2481. proc_add(st,pd,objcidcall);
  2482. added:=true;
  2483. {$ifndef DISABLE_FAST_OVERLOAD_PATCH}
  2484. pd.seenmarker:=self;
  2485. {$endif}
  2486. end;
  2487. end;
  2488. { we need to remove all specializations that were not used from their
  2489. procsyms as no code must be generated for them (if they are used
  2490. later on they'll be added like the ones that were used now) }
  2491. if not added and assigned(spezcontext) and not pd.is_registered then
  2492. begin
  2493. if tprocsym(pd.procsym).procdeflist.extract(pd)<>pd then
  2494. internalerror(20150828);
  2495. pd.free;
  2496. end;
  2497. end;
  2498. {$ifndef DISABLE_FAST_OVERLOAD_PATCH}
  2499. {cleanup modified duplicate pd markers}
  2500. hp := FCandidateProcs;
  2501. while assigned(hp) do begin
  2502. hp^.data.seenmarker := nil;
  2503. hp := hp^.next;
  2504. end;
  2505. {$endif}
  2506. calc_distance(st,objcidcall);
  2507. ProcdefOverloadList.Free;
  2508. end;
  2509. procedure tcallcandidates.calc_distance(st_root: tsymtable; objcidcall: boolean);
  2510. var
  2511. pd:tprocdef;
  2512. candidate:pcandidate;
  2513. st: tsymtable;
  2514. begin
  2515. { Give a small penalty for overloaded methods not defined in the
  2516. current class/unit }
  2517. st:=nil;
  2518. if objcidcall or
  2519. not assigned(st_root) or
  2520. not assigned(st_root.defowner) or
  2521. (st_root.defowner.typ<>objectdef) then
  2522. st:=st_root
  2523. else
  2524. repeat
  2525. { In case of a method, st_root is the symtable of the first found
  2526. procsym with the called method's name, but this procsym may not
  2527. contain any of the overloads that match the used parameters (which
  2528. are the procdefs that have been collected as candidates) -> walk
  2529. up the class hierarchy and look for the first class that actually
  2530. defines at least one of the candidate procdefs.
  2531. The reason is that we will penalise methods in other classes/
  2532. symtables, so if we pick a symtable that does not contain any of
  2533. the candidates, this won't help with picking the best/
  2534. most-inner-scoped one (since all of them will be penalised) }
  2535. candidate:=FCandidateProcs;
  2536. { the current class contains one of the candidates? }
  2537. while assigned(candidate) do
  2538. begin
  2539. pd:=candidate^.data;
  2540. if pd.owner=st_root then
  2541. begin
  2542. { yes -> choose this class }
  2543. st:=st_root;
  2544. break;
  2545. end;
  2546. candidate:=candidate^.next;
  2547. end;
  2548. { None found -> go to parent class }
  2549. if not assigned(st) then
  2550. begin
  2551. if not assigned(st_root.defowner) then
  2552. internalerror(201605301);
  2553. { no more parent class -> take current class as root anyway
  2554. (could maybe happen in case of a class helper?) }
  2555. if not assigned(tobjectdef(st_root.defowner).childof) then
  2556. begin
  2557. st:=st_root;
  2558. break;
  2559. end;
  2560. st_root:=tobjectdef(st_root.defowner).childof.symtable;
  2561. end;
  2562. until assigned(st);
  2563. candidate:=FCandidateProcs;
  2564. { when calling Objective-C methods via id.method, then the found
  2565. procsym will be inside an arbitrary ObjectSymtable, and we don't
  2566. want to give the methods of that particular objcclass precedence
  2567. over other methods, so instead check against the symtable in
  2568. which this objcclass is defined }
  2569. if objcidcall then
  2570. st:=st.defowner.owner;
  2571. while assigned(candidate) do
  2572. begin
  2573. pd:=candidate^.data;
  2574. if st<>pd.owner then
  2575. candidate^.ordinal_distance:=candidate^.ordinal_distance+1.0;
  2576. candidate:=candidate^.next;
  2577. end;
  2578. end;
  2579. function tcallcandidates.proc_add(st:tsymtable;pd:tprocdef;objcidcall: boolean):pcandidate;
  2580. var
  2581. defaultparacnt : integer;
  2582. begin
  2583. { generate new candidate entry }
  2584. new(result);
  2585. fillchar(result^,sizeof(tcandidate),0);
  2586. result^.data:=pd;
  2587. result^.next:=FCandidateProcs;
  2588. FCandidateProcs:=result;
  2589. inc(FProccnt);
  2590. { Find last parameter, skip all default parameters
  2591. that are not passed. Ignore this skipping for varargs }
  2592. result^.firstparaidx:=pd.paras.count-1;
  2593. if not(po_varargs in pd.procoptions) then
  2594. begin
  2595. { ignore hidden parameters }
  2596. while (result^.firstparaidx>=0) and (vo_is_hidden_para in tparavarsym(pd.paras[result^.firstparaidx]).varoptions) do
  2597. dec(result^.firstparaidx);
  2598. defaultparacnt:=pd.maxparacount-FParalength;
  2599. if defaultparacnt>0 then
  2600. begin
  2601. if defaultparacnt>result^.firstparaidx+1 then
  2602. internalerror(200401141);
  2603. dec(result^.firstparaidx,defaultparacnt);
  2604. end;
  2605. end;
  2606. end;
  2607. function tcallcandidates.maybe_specialize(var pd:tprocdef;spezcontext:tspecializationcontext):boolean;
  2608. var
  2609. def : tdef;
  2610. begin
  2611. result:=false;
  2612. if assigned(spezcontext) then
  2613. begin
  2614. if not (df_generic in pd.defoptions) then
  2615. internalerror(2015060301);
  2616. { check whether the given parameters are compatible
  2617. to the def's constraints }
  2618. if not check_generic_constraints(pd,spezcontext.paramlist,spezcontext.poslist) then
  2619. exit;
  2620. def:=generate_specialization_phase2(spezcontext,pd,false,'');
  2621. case def.typ of
  2622. errordef:
  2623. { do nothing }
  2624. ;
  2625. procdef:
  2626. pd:=tprocdef(def);
  2627. else
  2628. internalerror(2015070303);
  2629. end;
  2630. end;
  2631. result:=true;
  2632. end;
  2633. procedure tcallcandidates.list(all:boolean);
  2634. var
  2635. hp : pcandidate;
  2636. begin
  2637. hp:=FCandidateProcs;
  2638. while assigned(hp) do
  2639. begin
  2640. if all or
  2641. (not hp^.invalid) then
  2642. MessagePos1(hp^.data.fileinfo,sym_h_param_list,hp^.data.fullprocname(false));
  2643. hp:=hp^.next;
  2644. end;
  2645. end;
  2646. {$ifdef EXTDEBUG}
  2647. procedure tcallcandidates.dump_info(lvl:longint);
  2648. function ParaTreeStr(p:tcallparanode):string;
  2649. begin
  2650. result:='';
  2651. while assigned(p) do
  2652. begin
  2653. if result<>'' then
  2654. result:=','+result;
  2655. result:=p.resultdef.typename+result;
  2656. p:=tcallparanode(p.right);
  2657. end;
  2658. end;
  2659. var
  2660. hp : pcandidate;
  2661. i : integer;
  2662. currpara : tparavarsym;
  2663. begin
  2664. if not CheckVerbosity(lvl) then
  2665. exit;
  2666. Comment(lvl+V_LineInfo,'Overloaded callnode: '+FProcsym.name+'('+ParaTreeStr(tcallparanode(FParaNode))+')');
  2667. hp:=FCandidateProcs;
  2668. while assigned(hp) do
  2669. begin
  2670. Comment(lvl,' '+hp^.data.fullprocname(false));
  2671. if (hp^.invalid) then
  2672. Comment(lvl,' invalid')
  2673. else
  2674. begin
  2675. Comment(lvl,' ex: '+tostr(hp^.exact_count)+
  2676. ' eq: '+tostr(hp^.equal_count)+
  2677. ' l1: '+tostr(hp^.cl1_count)+
  2678. ' l2: '+tostr(hp^.cl2_count)+
  2679. ' l3: '+tostr(hp^.cl3_count)+
  2680. ' l4: '+tostr(hp^.cl4_count)+
  2681. ' l5: '+tostr(hp^.cl5_count)+
  2682. ' l6: '+tostr(hp^.cl6_count)+
  2683. ' oper: '+tostr(hp^.coper_count)+
  2684. ' ord: '+realtostr(hp^.ordinal_distance));
  2685. { Print parameters in left-right order }
  2686. for i:=0 to hp^.data.paras.count-1 do
  2687. begin
  2688. currpara:=tparavarsym(hp^.data.paras[i]);
  2689. if not(vo_is_hidden_para in currpara.varoptions) then
  2690. Comment(lvl,' - '+currpara.vardef.typename+' : '+EqualTypeName[currpara.eqval]);
  2691. end;
  2692. end;
  2693. hp:=hp^.next;
  2694. end;
  2695. end;
  2696. {$endif EXTDEBUG}
  2697. procedure tcallcandidates.get_information;
  2698. var
  2699. hp : pcandidate;
  2700. currpara : tparavarsym;
  2701. paraidx : integer;
  2702. currparanr : byte;
  2703. rfh,rth : double;
  2704. obj_from,
  2705. obj_to : tobjectdef;
  2706. def_from,
  2707. def_to : tdef;
  2708. currpt,
  2709. pt : tcallparanode;
  2710. eq,
  2711. mineq : tequaltype;
  2712. convtype : tconverttype;
  2713. pdtemp,
  2714. pdoper : tprocdef;
  2715. releasecurrpt : boolean;
  2716. cdoptions : tcompare_defs_options;
  2717. n : tnode;
  2718. {$push}
  2719. {$r-}
  2720. {$q-}
  2721. const
  2722. inf=1.0/0.0;
  2723. {$pop}
  2724. begin
  2725. cdoptions:=[cdo_check_operator];
  2726. if FAllowVariant then
  2727. include(cdoptions,cdo_allow_variant);
  2728. { process all procs }
  2729. hp:=FCandidateProcs;
  2730. while assigned(hp) do
  2731. begin
  2732. { We compare parameters in reverse order (right to left),
  2733. the firstpara is already pointing to the last parameter
  2734. were we need to start comparing }
  2735. currparanr:=FParalength;
  2736. paraidx:=hp^.firstparaidx;
  2737. while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(hp^.data.paras[paraidx]).varoptions) do
  2738. dec(paraidx);
  2739. pt:=tcallparanode(FParaNode);
  2740. while assigned(pt) and (paraidx>=0) do
  2741. begin
  2742. currpara:=tparavarsym(hp^.data.paras[paraidx]);
  2743. { currpt can be changed from loadn to calln when a procvar
  2744. is passed. This is to prevent that the change is permanent }
  2745. currpt:=pt;
  2746. releasecurrpt:=false;
  2747. { retrieve current parameter definitions to compares }
  2748. eq:=te_incompatible;
  2749. def_from:=currpt.resultdef;
  2750. def_to:=currpara.vardef;
  2751. if not(assigned(def_from)) then
  2752. internalerror(200212091);
  2753. if not(
  2754. assigned(def_to) or
  2755. ((po_varargs in hp^.data.procoptions) and
  2756. (currparanr>hp^.data.minparacount))
  2757. ) then
  2758. internalerror(200212092);
  2759. { Convert tp procvars when not expecting a procvar }
  2760. if (currpt.left.resultdef.typ=procvardef) and
  2761. not(def_to.typ in [procvardef,formaldef]) and
  2762. { Only convert to call when there is no overload or the return type
  2763. is equal to the expected type. }
  2764. (
  2765. (count=1) or
  2766. equal_defs(tprocvardef(currpt.left.resultdef).returndef,def_to)
  2767. ) and
  2768. { and if it doesn't require any parameters }
  2769. (tprocvardef(currpt.left.resultdef).minparacount=0) then
  2770. begin
  2771. releasecurrpt:=true;
  2772. currpt:=tcallparanode(pt.getcopy);
  2773. if maybe_call_procvar(currpt.left,true) then
  2774. begin
  2775. currpt.resultdef:=currpt.left.resultdef;
  2776. def_from:=currpt.left.resultdef;
  2777. end;
  2778. end;
  2779. { If we expect a procvar and the left is loadnode that
  2780. returns a procdef we need to find the correct overloaded
  2781. procdef that matches the expected procvar. The loadnode
  2782. temporary returned the first procdef (PFV) }
  2783. if (def_to.typ=procvardef) and
  2784. (currpt.left.nodetype=loadn) and
  2785. (currpt.left.resultdef.typ=procdef) then
  2786. begin
  2787. pdtemp:=tprocsym(Tloadnode(currpt.left).symtableentry).Find_procdef_byprocvardef(Tprocvardef(def_to));
  2788. if assigned(pdtemp) then
  2789. begin
  2790. tloadnode(currpt.left).setprocdef(pdtemp);
  2791. currpt.resultdef:=currpt.left.resultdef;
  2792. def_from:=currpt.left.resultdef;
  2793. end;
  2794. end;
  2795. { varargs are always equal, but not exact }
  2796. if (po_varargs in hp^.data.procoptions) and
  2797. (currparanr>hp^.data.minparacount) and
  2798. not is_array_of_const(def_from) and
  2799. not is_array_constructor(def_from) then
  2800. eq:=te_equal
  2801. else
  2802. { same definition -> exact }
  2803. if (def_from=def_to) then
  2804. eq:=te_exact
  2805. else
  2806. { for value and const parameters check if a integer is constant or
  2807. included in other integer -> equal and calc ordinal_distance }
  2808. if not(currpara.varspez in [vs_var,vs_out]) and
  2809. is_integer(def_from) and
  2810. is_integer(def_to) and
  2811. is_in_limit(def_from,def_to) then
  2812. begin
  2813. eq:=te_equal;
  2814. hp^.ordinal_distance:=hp^.ordinal_distance+
  2815. abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
  2816. rth:=bestreal(torddef(def_to).high);
  2817. rfh:=bestreal(torddef(def_from).high);
  2818. hp^.ordinal_distance:=hp^.ordinal_distance+abs(rth-rfh);
  2819. { Give wrong sign a small penalty, this is need to get a diffrence
  2820. from word->[longword,longint] }
  2821. if is_signed(def_from)<>is_signed(def_to) then
  2822. {$push}
  2823. {$r-}
  2824. {$q-}
  2825. hp^.ordinal_distance:=nextafter(hp^.ordinal_distance,inf);
  2826. {$pop}
  2827. end
  2828. else
  2829. { for value and const parameters check precision of real, give
  2830. penalty for loosing of precision. var and out parameters must match exactly }
  2831. if not(currpara.varspez in [vs_var,vs_out]) and
  2832. is_real_or_cextended(def_from) and
  2833. is_real_or_cextended(def_to) then
  2834. begin
  2835. eq:=te_equal;
  2836. if is_extended(def_to) then
  2837. rth:=4
  2838. else
  2839. if is_double (def_to) then
  2840. rth:=2
  2841. else
  2842. rth:=1;
  2843. if is_extended(def_from) then
  2844. rfh:=4
  2845. else
  2846. if is_double (def_from) then
  2847. rfh:=2
  2848. else
  2849. rfh:=1;
  2850. { penalty for shrinking of precision }
  2851. if rth<rfh then
  2852. rfh:=(rfh-rth)*16
  2853. else
  2854. rfh:=rth-rfh;
  2855. hp^.ordinal_distance:=hp^.ordinal_distance+rfh;
  2856. end
  2857. else
  2858. { related object parameters also need to determine the distance between the current
  2859. object and the object we are comparing with. var and out parameters must match exactly }
  2860. if not(currpara.varspez in [vs_var,vs_out]) and
  2861. (def_from.typ=objectdef) and
  2862. (def_to.typ=objectdef) and
  2863. (tobjectdef(def_from).objecttype=tobjectdef(def_to).objecttype) and
  2864. def_is_related(tobjectdef(def_from),tobjectdef(def_to)) then
  2865. begin
  2866. eq:=te_convert_l1;
  2867. { resolve anonymous external class definitions }
  2868. obj_from:=find_real_class_definition(tobjectdef(def_from),false);
  2869. obj_to:=find_real_class_definition(tobjectdef(def_to),false);
  2870. while assigned(obj_from) do
  2871. begin
  2872. if obj_from=obj_to then
  2873. break;
  2874. hp^.ordinal_distance:=hp^.ordinal_distance+1;
  2875. obj_from:=obj_from.childof;
  2876. end;
  2877. end
  2878. { compare_defs_ext compares sets and array constructors very poorly because
  2879. it has too little information. So we do explicitly a detailed comparisation,
  2880. see also bug #11288 (FK)
  2881. }
  2882. else if (def_to.typ=setdef) and is_array_constructor(currpt.left.resultdef) then
  2883. begin
  2884. n:=currpt.left.getcopy;
  2885. arrayconstructor_to_set(n);
  2886. eq:=compare_defs_ext(n.resultdef,def_to,n.nodetype,convtype,pdoper,cdoptions);
  2887. n.free;
  2888. end
  2889. else if is_open_array(def_to) and
  2890. is_class_or_interface_or_dispinterface_or_objc_or_java(tarraydef(def_to).elementdef) and
  2891. is_array_constructor(currpt.left.resultdef) and
  2892. assigned(tarrayconstructornode(currpt.left).left) then
  2893. begin
  2894. { ensure that [nil] can be converted to "array of tobject",
  2895. because if we just try to convert "array of pointer" to
  2896. "array of tobject", we get type conversion errors in
  2897. non-Delphi modes }
  2898. n:=currpt.left;
  2899. mineq:=te_exact;
  2900. repeat
  2901. if tarrayconstructornode(n).left.nodetype=arrayconstructorrangen then
  2902. eq:=te_incompatible
  2903. else
  2904. eq:=compare_defs_ext(tarrayconstructornode(n).left.resultdef,tarraydef(def_to).elementdef,tarrayconstructornode(n).left.nodetype,convtype,pdoper,cdoptions);
  2905. if eq<mineq then
  2906. mineq:=eq;
  2907. if eq=te_incompatible then
  2908. break;
  2909. n:=tarrayconstructornode(n).right;
  2910. until not assigned(n);
  2911. eq:=mineq;
  2912. end
  2913. else
  2914. { generic type comparision }
  2915. begin
  2916. if (hp^.data.procoptions*[po_rtlproc,po_compilerproc]=[]) and
  2917. is_ansistring(def_from) and
  2918. is_ansistring(def_to) and
  2919. (tstringdef(def_from).encoding<>tstringdef(def_to).encoding) and
  2920. (currpara.varspez in [vs_var,vs_out]) then
  2921. eq:=te_convert_l1 // don't allow to pass different ansistring types to each-other
  2922. else
  2923. eq:=compare_defs_ext(def_from,def_to,currpt.left.nodetype,convtype,pdoper,cdoptions);
  2924. { when the types are not equal we need to check
  2925. some special case for parameter passing }
  2926. if (eq<te_equal) then
  2927. begin
  2928. if currpara.varspez in [vs_var,vs_out] then
  2929. begin
  2930. { para requires an equal type so the previous found
  2931. match was not good enough, reset to incompatible }
  2932. eq:=te_incompatible;
  2933. { var_para_allowed will return te_equal and te_convert_l1 to
  2934. make a difference for best matching }
  2935. var_para_allowed(eq,currpt.resultdef,currpara.vardef,currpt.left)
  2936. end
  2937. else
  2938. para_allowed(eq,currpt,def_to);
  2939. end;
  2940. end;
  2941. { univ parameters match if the size matches (don't override the
  2942. comparison result if it was ok, since a match based on the
  2943. "univ" character is the lowest possible match) }
  2944. if (eq=te_incompatible) and
  2945. currpara.univpara and
  2946. is_valid_univ_para_type(def_from) and
  2947. (def_from.size=def_to.size) then
  2948. eq:=te_convert_l5;
  2949. { when a procvar was changed to a call an exact match is
  2950. downgraded to equal. This way an overload call with the
  2951. procvar is choosen. See tb0471 (PFV) }
  2952. if (pt<>currpt) and (eq=te_exact) then
  2953. eq:=te_equal;
  2954. { increase correct counter }
  2955. case eq of
  2956. te_exact :
  2957. inc(hp^.exact_count);
  2958. te_equal :
  2959. inc(hp^.equal_count);
  2960. te_convert_l1 :
  2961. inc(hp^.cl1_count);
  2962. te_convert_l2 :
  2963. inc(hp^.cl2_count);
  2964. te_convert_l3 :
  2965. inc(hp^.cl3_count);
  2966. te_convert_l4 :
  2967. inc(hp^.cl4_count);
  2968. te_convert_l5 :
  2969. inc(hp^.cl5_count);
  2970. te_convert_l6 :
  2971. inc(hp^.cl6_count);
  2972. te_convert_operator :
  2973. inc(hp^.coper_count);
  2974. te_incompatible :
  2975. hp^.invalid:=true;
  2976. end;
  2977. { stop checking when an incompatible parameter is found }
  2978. if hp^.invalid then
  2979. begin
  2980. { store the current parameter info for
  2981. a nice error message when no procedure is found }
  2982. hp^.wrongparaidx:=paraidx;
  2983. hp^.wrongparanr:=currparanr;
  2984. break;
  2985. end;
  2986. {$ifdef EXTDEBUG}
  2987. { store equal in node tree for dump }
  2988. currpara.eqval:=eq;
  2989. {$endif EXTDEBUG}
  2990. { maybe release temp currpt }
  2991. if releasecurrpt then
  2992. currpt.free;
  2993. { next parameter in the call tree }
  2994. pt:=tcallparanode(pt.right);
  2995. { next parameter for definition, only goto next para
  2996. if we're out of the varargs }
  2997. if not(po_varargs in hp^.data.procoptions) or
  2998. (currparanr<=hp^.data.maxparacount) then
  2999. begin
  3000. { Ignore vs_hidden parameters }
  3001. repeat
  3002. dec(paraidx);
  3003. until (paraidx<0) or not(vo_is_hidden_para in tparavarsym(hp^.data.paras[paraidx]).varoptions);
  3004. end;
  3005. dec(currparanr);
  3006. end;
  3007. if not(hp^.invalid) and
  3008. (assigned(pt) or (paraidx>=0) or (currparanr<>0)) then
  3009. internalerror(200212141);
  3010. { next candidate }
  3011. hp:=hp^.next;
  3012. end;
  3013. end;
  3014. function get_variantequaltype(def: tdef): tvariantequaltype;
  3015. const
  3016. variantorddef_cl: array[tordtype] of tvariantequaltype =
  3017. (tve_incompatible,tve_byte,tve_word,tve_cardinal,tve_chari64,tve_incompatible,
  3018. tve_shortint,tve_smallint,tve_longint,tve_chari64,tve_incompatible,
  3019. tve_boolformal,tve_boolformal,tve_boolformal,tve_boolformal,tve_boolformal,
  3020. tve_boolformal,tve_boolformal,tve_boolformal,tve_boolformal,
  3021. tve_chari64,tve_chari64,tve_dblcurrency,tve_incompatible);
  3022. { TODO: fixme for 128 bit floats }
  3023. variantfloatdef_cl: array[tfloattype] of tvariantequaltype =
  3024. (tve_single,tve_dblcurrency,tve_extended,tve_extended,
  3025. tve_dblcurrency,tve_dblcurrency,tve_extended);
  3026. variantstringdef_cl: array[tstringtype] of tvariantequaltype =
  3027. (tve_sstring,tve_astring,tve_astring,tve_wstring,tve_ustring);
  3028. begin
  3029. case def.typ of
  3030. orddef:
  3031. begin
  3032. result:=variantorddef_cl[torddef(def).ordtype];
  3033. end;
  3034. floatdef:
  3035. begin
  3036. result:=variantfloatdef_cl[tfloatdef(def).floattype];
  3037. end;
  3038. stringdef:
  3039. begin
  3040. result:=variantstringdef_cl[tstringdef(def).stringtype];
  3041. end;
  3042. formaldef:
  3043. begin
  3044. result:=tve_boolformal;
  3045. end;
  3046. else
  3047. begin
  3048. result:=tve_incompatible;
  3049. end;
  3050. end
  3051. end;
  3052. function is_better_candidate(currpd,bestpd:pcandidate):integer;
  3053. var
  3054. res : integer;
  3055. begin
  3056. {
  3057. Return values:
  3058. > 0 when currpd is better than bestpd
  3059. < 0 when bestpd is better than currpd
  3060. = 0 when both are equal
  3061. To choose the best candidate we use the following order:
  3062. - Incompatible flag
  3063. - (Smaller) Number of convert operator parameters.
  3064. - (Smaller) Number of convertlevel 2 parameters.
  3065. - (Smaller) Number of convertlevel 1 parameters.
  3066. - (Bigger) Number of exact parameters.
  3067. - (Smaller) Number of equal parameters.
  3068. - (Smaller) Total of ordinal distance. For example, the distance of a word
  3069. to a byte is 65535-255=65280.
  3070. }
  3071. if bestpd^.invalid then
  3072. begin
  3073. if currpd^.invalid then
  3074. res:=0
  3075. else
  3076. res:=1;
  3077. end
  3078. else
  3079. if currpd^.invalid then
  3080. res:=-1
  3081. else
  3082. begin
  3083. { less operator parameters? }
  3084. res:=(bestpd^.coper_count-currpd^.coper_count);
  3085. if (res=0) then
  3086. begin
  3087. { less cl6 parameters? }
  3088. res:=(bestpd^.cl6_count-currpd^.cl6_count);
  3089. if (res=0) then
  3090. begin
  3091. { less cl5 parameters? }
  3092. res:=(bestpd^.cl5_count-currpd^.cl5_count);
  3093. if (res=0) then
  3094. begin
  3095. { less cl4 parameters? }
  3096. res:=(bestpd^.cl4_count-currpd^.cl4_count);
  3097. if (res=0) then
  3098. begin
  3099. { less cl3 parameters? }
  3100. res:=(bestpd^.cl3_count-currpd^.cl3_count);
  3101. if (res=0) then
  3102. begin
  3103. { less cl2 parameters? }
  3104. res:=(bestpd^.cl2_count-currpd^.cl2_count);
  3105. if (res=0) then
  3106. begin
  3107. { less cl1 parameters? }
  3108. res:=(bestpd^.cl1_count-currpd^.cl1_count);
  3109. if (res=0) then
  3110. begin
  3111. { more exact parameters? }
  3112. res:=(currpd^.exact_count-bestpd^.exact_count);
  3113. if (res=0) then
  3114. begin
  3115. { less equal parameters? }
  3116. res:=(bestpd^.equal_count-currpd^.equal_count);
  3117. if (res=0) then
  3118. begin
  3119. { smaller ordinal distance? }
  3120. if (currpd^.ordinal_distance<bestpd^.ordinal_distance) then
  3121. res:=1
  3122. else
  3123. if (currpd^.ordinal_distance>bestpd^.ordinal_distance) then
  3124. res:=-1
  3125. else
  3126. res:=0;
  3127. end;
  3128. end;
  3129. end;
  3130. end;
  3131. end;
  3132. end;
  3133. end;
  3134. end;
  3135. end;
  3136. end;
  3137. is_better_candidate:=res;
  3138. end;
  3139. { Delphi precedence rules extracted from test programs. Only valid if passing
  3140. a variant parameter to overloaded procedures expecting exactly one parameter.
  3141. single > (char, currency, int64, shortstring, ansistring, widestring, unicodestring, extended, double)
  3142. double/currency > (char, int64, shortstring, ansistring, widestring, unicodestring, extended)
  3143. extended > (char, int64, shortstring, ansistring, widestring, unicodestring)
  3144. longint/cardinal > (int64, shortstring, ansistring, widestring, unicodestring, extended, double, single, char, currency)
  3145. smallint > (longint, int64, shortstring, ansistring, widestring, unicodestring, extended, double single, char, currency);
  3146. word > (longint, cardinal, int64, shortstring, ansistring, widestring, unicodestring, extended, double single, char, currency);
  3147. shortint > (longint, smallint, int64, shortstring, ansistring, widestring, unicodestring, extended, double, single, char, currency)
  3148. byte > (longint, cardinal, word, smallint, int64, shortstring, ansistring, widestring, unicodestring, extended, double, single, char, currency);
  3149. boolean/formal > (char, int64, shortstring, ansistring, widestring, unicodestring)
  3150. widestring > (char, int64, shortstring, ansistring, unicodestring)
  3151. unicodestring > (char, int64, shortstring, ansistring)
  3152. ansistring > (char, int64, shortstring)
  3153. shortstring > (char, int64)
  3154. Relations not mentioned mean that they conflict: no decision possible }
  3155. function is_better_candidate_single_variant(currpd,bestpd:pcandidate):integer;
  3156. function calculate_relation(const currvcl, bestvcl, testvcl:
  3157. tvariantequaltype; const conflictvcls: tvariantequaltypes):integer;
  3158. begin
  3159. { if (bestvcl=conflictvcl) or
  3160. (currvcl=conflictvcl) then
  3161. result:=0
  3162. else if (bestvcl=testvcl) then
  3163. result:=-1
  3164. else result:=1 }
  3165. result:=1-2*ord(bestvcl=testvcl)+
  3166. ord(currvcl in conflictvcls)-ord(bestvcl in conflictvcls);
  3167. end;
  3168. function getfirstrealparaidx(pd: pcandidate): integer;
  3169. begin
  3170. { can be different for currpd and bestpd in case of overloaded }
  3171. { functions, e.g. lowercase():char and lowercase():shortstring }
  3172. { (depending on the calling convention and parameter order) }
  3173. result:=pd^.firstparaidx;
  3174. while (result>=0) and (vo_is_hidden_para in tparavarsym(pd^.data.paras[result]).varoptions) do
  3175. dec(result);
  3176. if (vo_is_hidden_para in tparavarsym(pd^.data.paras[result]).varoptions) then
  3177. internalerror(2006122803);
  3178. end;
  3179. var
  3180. currpara, bestpara: tparavarsym;
  3181. currvcl, bestvcl: tvariantequaltype;
  3182. begin
  3183. {
  3184. Return values:
  3185. > 0 when currpd is better than bestpd
  3186. < 0 when bestpd is better than currpd
  3187. = 0 when both are equal
  3188. }
  3189. currpara:=tparavarsym(currpd^.data.paras[getfirstrealparaidx(currpd)]);
  3190. bestpara:=tparavarsym(bestpd^.data.paras[getfirstrealparaidx(bestpd)]);
  3191. { if one of the parameters is a regular variant, fall back to the }
  3192. { default algorithm }
  3193. if (currpara.vardef.typ = variantdef) or
  3194. (bestpara.vardef.typ = variantdef) then
  3195. begin
  3196. result:=is_better_candidate(currpd,bestpd);
  3197. exit;
  3198. end;
  3199. currvcl:=get_variantequaltype(currpara.vardef);
  3200. bestvcl:=get_variantequaltype(bestpara.vardef);
  3201. { sanity check }
  3202. result:=-5;
  3203. { if both are the same, there is a conflict }
  3204. if (currvcl=bestvcl) then
  3205. result:=0
  3206. { if one of the two cannot be used as variant, the other is better }
  3207. else if (bestvcl=tve_incompatible) then
  3208. result:=1
  3209. else if (currvcl=tve_incompatible) then
  3210. result:=-1
  3211. { boolean and formal are better than chari64str, but conflict with }
  3212. { everything else }
  3213. else if (currvcl=tve_boolformal) or
  3214. (bestvcl=tve_boolformal) then
  3215. if (currvcl=tve_boolformal) then
  3216. result:=ord(bestvcl in [tve_chari64,tve_sstring,tve_astring,tve_wstring,tve_ustring])
  3217. else
  3218. result:=-ord(currvcl in [tve_chari64,tve_sstring,tve_astring,tve_wstring,tve_ustring])
  3219. { byte is better than everything else (we assume both aren't byte, }
  3220. { since there's only one parameter and that one can't be the same) }
  3221. else if (currvcl=tve_byte) or
  3222. (bestvcl=tve_byte) then
  3223. result:=calculate_relation(currvcl,bestvcl,tve_byte,[tve_shortint])
  3224. { shortint conflicts with word and cardinal, but is better than }
  3225. { everything else but byte (which has already been handled) }
  3226. else if (currvcl=tve_shortint) or
  3227. (bestvcl=tve_shortint) then
  3228. result:=calculate_relation(currvcl,bestvcl,tve_shortint,[tve_word, tve_cardinal])
  3229. { word conflicts with smallint, but is better than everything else }
  3230. { but shortint and byte (which has already been handled) }
  3231. else if (currvcl=tve_word) or
  3232. (bestvcl=tve_word) then
  3233. result:=calculate_relation(currvcl,bestvcl,tve_word,[tve_smallint])
  3234. { smallint conflicts with cardinal, but is better than everything }
  3235. { which has not yet been tested }
  3236. else if (currvcl=tve_smallint) or
  3237. (bestvcl=tve_smallint) then
  3238. result:=calculate_relation(currvcl,bestvcl,tve_smallint,[tve_cardinal])
  3239. { cardinal conflicts with each longint and is better than everything }
  3240. { which has not yet been tested }
  3241. else if (currvcl=tve_cardinal) or
  3242. (bestvcl=tve_cardinal) then
  3243. result:=calculate_relation(currvcl,bestvcl,tve_cardinal,[tve_longint])
  3244. { longint is better than everything which has not yet been tested }
  3245. else if (currvcl=tve_longint) or
  3246. (bestvcl=tve_longint) then
  3247. { if bestvcl=tve_longint then
  3248. result:=-1
  3249. else
  3250. result:=1 }
  3251. result:=1-2*ord(bestvcl=tve_longint)
  3252. { single is better than everything left }
  3253. else if (currvcl=tve_single) or
  3254. (bestvcl=tve_single) then
  3255. result:=1-2*ord(bestvcl=tve_single)
  3256. { double/comp/currency are better than everything left, and conflict }
  3257. { with each other (but that's already tested) }
  3258. else if (currvcl=tve_dblcurrency) or
  3259. (bestvcl=tve_dblcurrency) then
  3260. result:=1-2*ord(bestvcl=tve_dblcurrency)
  3261. { extended is better than everything left }
  3262. else if (currvcl=tve_extended) or
  3263. (bestvcl=tve_extended) then
  3264. result:=1-2*ord(bestvcl=tve_extended)
  3265. { widestring is better than everything left }
  3266. else if (currvcl=tve_wstring) or
  3267. (bestvcl=tve_wstring) then
  3268. result:=1-2*ord(bestvcl=tve_wstring)
  3269. { unicodestring is better than everything left }
  3270. else if (currvcl=tve_ustring) or
  3271. (bestvcl=tve_ustring) then
  3272. result:=1-2*ord(bestvcl=tve_ustring)
  3273. { ansistring is better than everything left }
  3274. else if (currvcl=tve_astring) or
  3275. (bestvcl=tve_astring) then
  3276. result:=1-2*ord(bestvcl=tve_astring)
  3277. { shortstring is better than everything left }
  3278. else if (currvcl=tve_sstring) or
  3279. (bestvcl=tve_sstring) then
  3280. result:=1-2*ord(bestvcl=tve_sstring);
  3281. { all possibilities should have been checked now }
  3282. if (result=-5) then
  3283. internalerror(2006122805);
  3284. end;
  3285. {$ifdef DISABLE_FAST_OVERLOAD_PATCH}
  3286. function tcallcandidates.choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
  3287. var
  3288. pd: tprocdef;
  3289. besthpstart,
  3290. hp : pcandidate;
  3291. cntpd,
  3292. res : integer;
  3293. begin
  3294. {
  3295. Returns the number of candidates left and the
  3296. first candidate is returned in pdbest
  3297. }
  3298. { Setup the first procdef as best, only count it as a result
  3299. when it is valid }
  3300. bestpd:=FCandidateProcs^.data;
  3301. if FCandidateProcs^.invalid then
  3302. cntpd:=0
  3303. else
  3304. cntpd:=1;
  3305. if assigned(FCandidateProcs^.next) then
  3306. begin
  3307. besthpstart:=FCandidateProcs;
  3308. hp:=FCandidateProcs^.next;
  3309. while assigned(hp) do
  3310. begin
  3311. if not singlevariant then
  3312. res:=is_better_candidate(hp,besthpstart)
  3313. else
  3314. res:=is_better_candidate_single_variant(hp,besthpstart);
  3315. if (res>0) then
  3316. begin
  3317. { hp is better, flag all procs to be incompatible }
  3318. while (besthpstart<>hp) do
  3319. begin
  3320. besthpstart^.invalid:=true;
  3321. besthpstart:=besthpstart^.next;
  3322. end;
  3323. { besthpstart is already set to hp }
  3324. bestpd:=besthpstart^.data;
  3325. cntpd:=1;
  3326. end
  3327. else
  3328. if (res<0) then
  3329. begin
  3330. { besthpstart is better, flag current hp to be incompatible }
  3331. hp^.invalid:=true;
  3332. end
  3333. else
  3334. begin
  3335. { res=0, both are valid }
  3336. if not hp^.invalid then
  3337. inc(cntpd);
  3338. end;
  3339. hp:=hp^.next;
  3340. end;
  3341. end;
  3342. { if we've found one, check the procdefs ignored for overload choosing
  3343. to see whether they contain one from a child class with the same
  3344. parameters (so the overload choosing was not influenced by their
  3345. presence, but now that we've decided which overloaded version to call,
  3346. make sure we call the version closest in terms of visibility }
  3347. if cntpd=1 then
  3348. begin
  3349. for res:=0 to FIgnoredCandidateProcs.count-1 do
  3350. begin
  3351. pd:=tprocdef(FIgnoredCandidateProcs[res]);
  3352. { stop searching when we start comparing methods of parent of
  3353. the struct in which the current best method was found }
  3354. if assigned(pd.struct) and
  3355. (pd.struct<>tprocdef(bestpd).struct) and
  3356. def_is_related(tprocdef(bestpd).struct,pd.struct) then
  3357. break;
  3358. if (pd.proctypeoption=bestpd.proctypeoption) and
  3359. ((pd.procoptions*[po_classmethod,po_methodpointer])=(bestpd.procoptions*[po_classmethod,po_methodpointer])) and
  3360. (compare_paras(pd.paras,bestpd.paras,cp_all,[cpo_ignorehidden,cpo_ignoreuniv,cpo_openequalisexact])=te_exact) then
  3361. begin
  3362. { first one encountered is closest in terms of visibility }
  3363. bestpd:=pd;
  3364. break;
  3365. end;
  3366. end;
  3367. end;
  3368. result:=cntpd;
  3369. end;
  3370. {$else}
  3371. function compare_by_old_sortout_check(pd,bestpd:pcandidate):integer;
  3372. var cpoptions : tcompare_paras_options;
  3373. begin
  3374. { don't add duplicates, only compare visible parameters for the user }
  3375. cpoptions:=[cpo_ignorehidden];
  3376. if (po_compilerproc in bestpd^.data.procoptions) then
  3377. cpoptions:=cpoptions+[cpo_compilerproc];
  3378. if (po_rtlproc in bestpd^.data.procoptions) then
  3379. cpoptions:=cpoptions+[cpo_rtlproc];
  3380. compare_by_old_sortout_check := 0; // can't decide, bestpd probably wasn't sorted out in unpatched
  3381. if (compare_paras(pd^.data.paras,bestpd^.data.paras,cp_value_equal_const,cpoptions)>=te_equal) and
  3382. (not(po_objc in bestpd^.data.procoptions) or (bestpd^.data.messageinf.str^=pd^.data.messageinf.str^)) then
  3383. compare_by_old_sortout_check := 1; // bestpd was sorted out before patch
  3384. end;
  3385. function decide_restart(pd,bestpd:pcandidate) : boolean;
  3386. begin
  3387. decide_restart := false;
  3388. if assigned(bestpd) then
  3389. begin
  3390. { don't restart if bestpd is marked invalid already }
  3391. if not bestpd^.invalid then
  3392. decide_restart := compare_by_old_sortout_check(pd,bestpd)<>0;
  3393. end;
  3394. end;
  3395. procedure save_validity(c : pcandidate);
  3396. begin
  3397. while assigned(c) do
  3398. begin
  3399. c^.saved_validity := c^.invalid;
  3400. c := c^.next;
  3401. end;
  3402. end;
  3403. procedure restore_validity(c : pcandidate);
  3404. begin
  3405. while assigned(c) do begin
  3406. c^.invalid := c^.saved_validity;
  3407. c := c^.next;
  3408. end;
  3409. end;
  3410. function tcallcandidates.choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
  3411. var
  3412. pd: tprocdef;
  3413. besthpstart,
  3414. hp,hp2 : pcandidate;
  3415. cntpd,
  3416. res : integer;
  3417. restart : boolean;
  3418. begin
  3419. res:=0;
  3420. {
  3421. Returns the number of candidates left and the
  3422. first candidate is returned in pdbest
  3423. }
  3424. if not(assigned(FCandidateProcs)) then
  3425. begin
  3426. choose_best := 0;
  3427. exit;
  3428. end;
  3429. bestpd:=FCandidateProcs^.data;
  3430. if FCandidateProcs^.invalid then
  3431. cntpd:=0
  3432. else
  3433. cntpd:=1;
  3434. if assigned(FCandidateProcs^.next) then
  3435. begin
  3436. save_validity(FCandidateProcs);
  3437. restart := false;
  3438. { keep restarting, until there wasn't a sorted-out besthpstart }
  3439. repeat
  3440. besthpstart:=FCandidateProcs;
  3441. bestpd:=FCandidateProcs^.data;
  3442. if restart then
  3443. begin
  3444. restore_validity(FCandidateProcs);
  3445. restart := false;
  3446. end;
  3447. { Setup the first procdef as best, only count it as a result
  3448. when it is valid }
  3449. if besthpstart^.invalid then
  3450. cntpd:=0
  3451. else
  3452. cntpd:=1;
  3453. hp:=FCandidateProcs^.next;
  3454. while assigned(hp) and not(restart) do
  3455. begin
  3456. restart := decide_restart(hp,besthpstart);
  3457. if not restart then
  3458. begin
  3459. if besthpstart^.invalid then res := 1
  3460. else if hp^.invalid then res := -1
  3461. else if not singlevariant then
  3462. res:=is_better_candidate(hp,besthpstart)
  3463. else
  3464. res:=is_better_candidate_single_variant(hp,besthpstart);
  3465. end;
  3466. if restart then
  3467. begin
  3468. { mark the sorted out invalid globally }
  3469. besthpstart^.saved_validity := true;
  3470. end
  3471. else if (res>0) then
  3472. begin
  3473. { hp is better, flag all procs to be incompatible }
  3474. while (besthpstart<>hp) do
  3475. begin
  3476. besthpstart^.invalid:=true;
  3477. besthpstart:=besthpstart^.next;
  3478. end;
  3479. { besthpstart is already set to hp }
  3480. bestpd:=besthpstart^.data;
  3481. if besthpstart^.invalid then
  3482. cntpd:=0
  3483. else
  3484. cntpd:=1;
  3485. end
  3486. else if (res<0) then
  3487. begin
  3488. { besthpstart is better, flag current hp to be incompatible }
  3489. hp^.invalid:=true;
  3490. end
  3491. else
  3492. begin
  3493. { res=0, both are valid }
  3494. if not hp^.invalid then
  3495. inc(cntpd);
  3496. end;
  3497. hp:=hp^.next;
  3498. end;
  3499. until not(restart);
  3500. end;
  3501. { check the alternate choices if they would have been sorted out before patch... }
  3502. { note we have procadded the candidates, so order is reversed procadd order here.
  3503. this was also used above: each sorted-out always has an "outsorter" counterpart
  3504. deeper down the next chain
  3505. }
  3506. { for the intial implementation, let's first do some more consistency checking}
  3507. res := 0;
  3508. hp := FCandidateProcs;
  3509. while assigned(hp) do
  3510. begin
  3511. if not(hp^.invalid) then
  3512. inc(res);
  3513. hp := hp^.next;
  3514. end;
  3515. if (res<>cntpd) then
  3516. internalerror(202002161);
  3517. { check all valid choices for sortout }
  3518. cntpd := 0;
  3519. hp := FCandidateProcs;
  3520. while assigned(hp) do
  3521. begin
  3522. if not(hp^.invalid) then
  3523. begin
  3524. hp2 := hp^.next;
  3525. while assigned(hp2) do begin
  3526. if compare_by_old_sortout_check(hp2,hp)<>0 then
  3527. begin
  3528. hp^.invalid := true;
  3529. hp2 := nil;
  3530. end
  3531. else
  3532. hp2:=hp2^.next;
  3533. end;
  3534. if not(hp^.invalid) then
  3535. begin
  3536. inc(cntpd);
  3537. { check for the impossible event bestpd had become invalid}
  3538. if (cntpd=1) and (hp^.data<>bestpd) then
  3539. internalerror(202002162);
  3540. end;
  3541. end;
  3542. hp := hp^.next;
  3543. end;
  3544. { if we've found one, check the procdefs ignored for overload choosing
  3545. to see whether they contain one from a child class with the same
  3546. parameters (so the overload choosing was not influenced by their
  3547. presence, but now that we've decided which overloaded version to call,
  3548. make sure we call the version closest in terms of visibility }
  3549. if cntpd=1 then
  3550. begin
  3551. for res:=0 to FIgnoredCandidateProcs.count-1 do
  3552. begin
  3553. pd:=tprocdef(FIgnoredCandidateProcs[res]);
  3554. { stop searching when we start comparing methods of parent of
  3555. the struct in which the current best method was found }
  3556. if assigned(pd.struct) and
  3557. (pd.struct<>tprocdef(bestpd).struct) and
  3558. def_is_related(tprocdef(bestpd).struct,pd.struct) then
  3559. break;
  3560. if (pd.proctypeoption=bestpd.proctypeoption) and
  3561. ((pd.procoptions*[po_classmethod,po_methodpointer])=(bestpd.procoptions*[po_classmethod,po_methodpointer])) and
  3562. (compare_paras(pd.paras,bestpd.paras,cp_all,[cpo_ignorehidden,cpo_ignoreuniv,cpo_openequalisexact])=te_exact) then
  3563. begin
  3564. { first one encountered is closest in terms of visibility }
  3565. bestpd:=pd;
  3566. break;
  3567. end;
  3568. end;
  3569. end;
  3570. result:=cntpd;
  3571. end;
  3572. {$endif}
  3573. procedure tcallcandidates.find_wrong_para;
  3574. var
  3575. currparanr : smallint;
  3576. hp : pcandidate;
  3577. pt : tcallparanode;
  3578. wrongpara : tparavarsym;
  3579. begin
  3580. { Only process the first overloaded procdef }
  3581. hp:=FCandidateProcs;
  3582. { Find callparanode corresponding to the argument }
  3583. pt:=tcallparanode(FParanode);
  3584. currparanr:=FParalength;
  3585. while assigned(pt) and
  3586. (currparanr>hp^.wrongparanr) do
  3587. begin
  3588. pt:=tcallparanode(pt.right);
  3589. dec(currparanr);
  3590. end;
  3591. if (currparanr<>hp^.wrongparanr) or
  3592. not assigned(pt) then
  3593. internalerror(200212094);
  3594. { Show error message, when it was a var or out parameter
  3595. guess that it is a missing typeconv }
  3596. wrongpara:=tparavarsym(hp^.data.paras[hp^.wrongparaidx]);
  3597. if wrongpara.varspez in [vs_var,vs_out] then
  3598. begin
  3599. { Maybe passing the correct type but passing a const to var parameter }
  3600. if (compare_defs(pt.resultdef,wrongpara.vardef,pt.nodetype)<>te_incompatible) and
  3601. not valid_for_var(pt.left,true) then
  3602. CGMessagePos(pt.left.fileinfo,type_e_variable_id_expected)
  3603. else
  3604. CGMessagePos3(pt.left.fileinfo,parser_e_call_by_ref_without_typeconv,tostr(hp^.wrongparanr),
  3605. FullTypeName(pt.left.resultdef,wrongpara.vardef),
  3606. FullTypeName(wrongpara.vardef,pt.left.resultdef))
  3607. end
  3608. else
  3609. CGMessagePos3(pt.left.fileinfo,type_e_wrong_parameter_type,tostr(hp^.wrongparanr),
  3610. FullTypeName(pt.left.resultdef,wrongpara.vardef),
  3611. FullTypeName(wrongpara.vardef,pt.left.resultdef));
  3612. end;
  3613. procedure check_ranges(const location: tfileposinfo; source: tnode; destdef: tdef);
  3614. begin
  3615. if not(cs_check_ordinal_size in current_settings.localswitches) then
  3616. exit;
  3617. { check if the assignment may cause a range check error }
  3618. { if its not explicit, and only if the values are }
  3619. { ordinals, enumdef and floatdef }
  3620. if assigned(destdef) and
  3621. (destdef.typ in [enumdef,orddef,floatdef]) and
  3622. not is_boolean(destdef) and
  3623. assigned(source.resultdef) and
  3624. (source.resultdef.typ in [enumdef,orddef,floatdef]) and
  3625. not is_boolean(source.resultdef) and
  3626. not is_constrealnode(source) and
  3627. { constants are handled via regular range checking }
  3628. (source.nodetype<>ordconstn) then
  3629. begin
  3630. if ((destdef.size < source.resultdef.size) and
  3631. { s80real and sc80real have a different size but the same precision }
  3632. not((destdef.typ=floatdef) and
  3633. (source.resultdef.typ=floatdef) and
  3634. (tfloatdef(source.resultdef).floattype in [s80real,sc80real]) and
  3635. (tfloatdef(destdef).floattype in [s80real,sc80real]))) or
  3636. ((destdef.typ<>floatdef) and
  3637. (source.resultdef.typ<>floatdef) and
  3638. not is_in_limit(source.resultdef,destdef)) then
  3639. begin
  3640. if (cs_check_range in current_settings.localswitches) then
  3641. MessagePos(location,type_w_smaller_possible_range_check)
  3642. else
  3643. MessagePos(location,type_h_smaller_possible_range_check);
  3644. end;
  3645. end;
  3646. end;
  3647. function is_valid_for_default(def:tdef):boolean;
  3648. function is_valid_record_or_object(def:tabstractrecorddef):boolean;
  3649. var
  3650. sym : tsym;
  3651. i : longint;
  3652. begin
  3653. for i:=0 to def.symtable.symlist.count-1 do
  3654. begin
  3655. sym:=tsym(def.symtable.symlist[i]);
  3656. if not is_normal_fieldvarsym(sym) then
  3657. continue;
  3658. if not is_valid_for_default(tfieldvarsym(sym).vardef) then
  3659. begin
  3660. result:=false;
  3661. exit;
  3662. end;
  3663. end;
  3664. result:=true;
  3665. end;
  3666. begin
  3667. case def.typ of
  3668. recorddef:
  3669. result:=is_valid_record_or_object(tabstractrecorddef(def));
  3670. objectdef:
  3671. if is_implicit_pointer_object_type(def) then
  3672. result:=true
  3673. else
  3674. if is_object(def) then
  3675. result:=is_valid_record_or_object(tabstractrecorddef(def))
  3676. else
  3677. result:=false;
  3678. arraydef:
  3679. if not (ado_isdynamicarray in tarraydef(def).arrayoptions) then
  3680. result:=is_valid_for_default(tarraydef(def).elementdef)
  3681. else
  3682. result:=true;
  3683. formaldef,
  3684. abstractdef,
  3685. filedef:
  3686. result:=false;
  3687. else
  3688. result:=true;
  3689. end;
  3690. end;
  3691. end.