htypechk.pas 138 KB

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