htypechk.pas 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592
  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. tokens,cpuinfo,
  22. node,globtype,
  23. symconst,symtype,symdef,symsym,symbase;
  24. type
  25. Ttok2nodeRec=record
  26. tok : ttoken;
  27. nod : tnodetype;
  28. op_overloading_supported : boolean;
  29. end;
  30. pcandidate = ^tcandidate;
  31. tcandidate = record
  32. next : pcandidate;
  33. data : tprocdef;
  34. wrongparaidx,
  35. firstparaidx : integer;
  36. exact_count,
  37. equal_count,
  38. cl1_count,
  39. cl2_count,
  40. cl3_count,
  41. cl4_count,
  42. coper_count : integer; { should be signed }
  43. ordinal_distance : double;
  44. invalid : boolean;
  45. wrongparanr : byte;
  46. end;
  47. tcallcandidates = class
  48. private
  49. FProcSym : tprocsym;
  50. FProcs : pcandidate;
  51. FProcVisibleCnt,
  52. FProcCnt : integer;
  53. FParaNode : tnode;
  54. FParaLength : smallint;
  55. FAllowVariant : boolean;
  56. function proc_add(ps:tprocsym;pd:tprocdef):pcandidate;
  57. public
  58. constructor create(sym:tprocsym;st:TSymtable;ppn:tnode;isprop,ignorevis : boolean);
  59. constructor create_operator(op:ttoken;ppn:tnode);
  60. destructor destroy;override;
  61. procedure list(all:boolean);
  62. {$ifdef EXTDEBUG}
  63. procedure dump_info(lvl:longint);
  64. {$endif EXTDEBUG}
  65. procedure get_information;
  66. function choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
  67. procedure find_wrong_para;
  68. property Count:integer read FProcCnt;
  69. property VisibleCount:integer read FProcVisibleCnt;
  70. end;
  71. type
  72. tregableinfoflag = (
  73. // can be put in a register if it's the address of a var/out/const parameter
  74. ra_addr_regable,
  75. // orthogonal to above flag: the address of the node is taken and may
  76. // possibly escape the block in which this node is declared (e.g. a
  77. // local variable is passed as var parameter to another procedure)
  78. ra_addr_taken);
  79. tregableinfoflags = set of tregableinfoflag;
  80. const
  81. tok2nodes=24;
  82. tok2node:array[1..tok2nodes] of ttok2noderec=(
  83. (tok:_PLUS ;nod:addn;op_overloading_supported:true), { binary overloading supported }
  84. (tok:_MINUS ;nod:subn;op_overloading_supported:true), { binary and unary overloading supported }
  85. (tok:_STAR ;nod:muln;op_overloading_supported:true), { binary overloading supported }
  86. (tok:_SLASH ;nod:slashn;op_overloading_supported:true), { binary overloading supported }
  87. (tok:_EQUAL ;nod:equaln;op_overloading_supported:true), { binary overloading supported }
  88. (tok:_GT ;nod:gtn;op_overloading_supported:true), { binary overloading supported }
  89. (tok:_LT ;nod:ltn;op_overloading_supported:true), { binary overloading supported }
  90. (tok:_GTE ;nod:gten;op_overloading_supported:true), { binary overloading supported }
  91. (tok:_LTE ;nod:lten;op_overloading_supported:true), { binary overloading supported }
  92. (tok:_SYMDIF ;nod:symdifn;op_overloading_supported:true), { binary overloading supported }
  93. (tok:_STARSTAR;nod:starstarn;op_overloading_supported:true), { binary overloading supported }
  94. (tok:_OP_AS ;nod:asn;op_overloading_supported:false), { binary overloading NOT supported }
  95. (tok:_OP_IN ;nod:inn;op_overloading_supported:false), { binary overloading NOT supported }
  96. (tok:_OP_IS ;nod:isn;op_overloading_supported:false), { binary overloading NOT supported }
  97. (tok:_OP_OR ;nod:orn;op_overloading_supported:true), { binary overloading supported }
  98. (tok:_OP_AND ;nod:andn;op_overloading_supported:true), { binary overloading supported }
  99. (tok:_OP_DIV ;nod:divn;op_overloading_supported:true), { binary overloading supported }
  100. (tok:_OP_NOT ;nod:notn;op_overloading_supported:true), { unary overloading supported }
  101. (tok:_OP_MOD ;nod:modn;op_overloading_supported:true), { binary overloading supported }
  102. (tok:_OP_SHL ;nod:shln;op_overloading_supported:true), { binary overloading supported }
  103. (tok:_OP_SHR ;nod:shrn;op_overloading_supported:true), { binary overloading supported }
  104. (tok:_OP_XOR ;nod:xorn;op_overloading_supported:true), { binary overloading supported }
  105. (tok:_ASSIGNMENT;nod:assignn;op_overloading_supported:true), { unary overloading supported }
  106. (tok:_UNEQUAL ;nod:unequaln;op_overloading_supported:false) { binary overloading NOT supported overload = instead }
  107. );
  108. const
  109. allow_array_constructor : boolean = false;
  110. function node2opstr(nt:tnodetype):string;
  111. { check operator args and result type }
  112. function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
  113. function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
  114. function isunaryoverloaded(var t : tnode) : boolean;
  115. function isbinaryoverloaded(var t : tnode) : boolean;
  116. { Register Allocation }
  117. procedure make_not_regable(p : tnode; how: tregableinfoflags);
  118. { procvar handling }
  119. function is_procvar_load(p:tnode):boolean;
  120. procedure test_local_to_procvar(from_def:tprocvardef;to_def:tdef);
  121. { sets varsym varstate field correctly }
  122. type
  123. tvarstateflag = (vsf_must_be_valid,vsf_use_hints);
  124. tvarstateflags = set of tvarstateflag;
  125. procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
  126. { sets the callunique flag, if the node is a vecn, }
  127. { takes care of type casts etc. }
  128. procedure set_unique(p : tnode);
  129. function valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
  130. function valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
  131. function valid_for_var(p:tnode; report_errors: boolean):boolean;
  132. function valid_for_assignment(p:tnode; report_errors: boolean):boolean;
  133. function valid_for_loopvar(p:tnode; report_errors: boolean):boolean;
  134. function valid_for_addr(p : tnode; report_errors: boolean) : boolean;
  135. function allowenumop(nt:tnodetype):boolean;
  136. procedure check_hints(const srsym: tsym; const symoptions: tsymoptions);
  137. procedure check_ranges(const location: tfileposinfo; source: tnode; destdef: tdef);
  138. implementation
  139. uses
  140. sysutils,
  141. systems,constexp,globals,
  142. cutils,cclasses,verbose,
  143. symtable,
  144. defutil,defcmp,
  145. nbas,ncnv,nld,nmem,ncal,nmat,ninl,nutils,ncon,
  146. cgbase,procinfo
  147. ;
  148. type
  149. TValidAssign=(Valid_Property,Valid_Void,Valid_Const,Valid_Addr,Valid_Packed);
  150. TValidAssigns=set of TValidAssign;
  151. function node2opstr(nt:tnodetype):string;
  152. var
  153. i : integer;
  154. begin
  155. result:='<unknown>';
  156. for i:=1 to tok2nodes do
  157. if tok2node[i].nod=nt then
  158. begin
  159. result:=tokeninfo^[tok2node[i].tok].str;
  160. break;
  161. end;
  162. end;
  163. function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
  164. function internal_check(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype;var allowed:boolean):boolean;
  165. begin
  166. internal_check:=true;
  167. case ld.typ of
  168. formaldef,
  169. recorddef,
  170. variantdef :
  171. begin
  172. allowed:=true;
  173. end;
  174. procvardef :
  175. begin
  176. if (rd.typ in [pointerdef,procdef,procvardef]) then
  177. begin
  178. allowed:=false;
  179. exit;
  180. end;
  181. allowed:=true;
  182. end;
  183. pointerdef :
  184. begin
  185. if ((rd.typ in [orddef,enumdef,pointerdef,classrefdef,procvardef]) or
  186. is_class_or_interface(rd)) then
  187. begin
  188. allowed:=false;
  189. exit;
  190. end;
  191. { don't allow pchar+string }
  192. if (is_pchar(ld) or is_pwidechar(ld)) and
  193. ((rd.typ=stringdef) or
  194. is_pchar(rd) or
  195. is_pwidechar(rd) or
  196. is_chararray(rd) or
  197. is_widechararray(rd)) then
  198. begin
  199. allowed:=false;
  200. exit;
  201. end;
  202. allowed:=true;
  203. end;
  204. arraydef :
  205. begin
  206. { not vector/mmx }
  207. if ((cs_mmx in current_settings.localswitches) and
  208. is_mmx_able_array(ld)) or
  209. ((cs_support_vectors in current_settings.globalswitches) and
  210. is_vector(ld)) then
  211. begin
  212. allowed:=false;
  213. exit;
  214. end;
  215. { not chararray+[(wide)char,(wide)string,(wide)chararray] }
  216. if (is_chararray(ld) or is_widechararray(ld) or
  217. is_open_chararray(ld) or is_open_widechararray(ld))
  218. and
  219. ((rd.typ in [stringdef,orddef,enumdef]) or
  220. is_pchar(rd) or
  221. is_pwidechar(rd) or
  222. is_chararray(rd) or
  223. is_widechararray(rd) or
  224. is_open_chararray(rd) or
  225. is_open_widechararray(rd) or
  226. (rt=niln)) then
  227. begin
  228. allowed:=false;
  229. exit;
  230. end;
  231. { dynamic array compare with niln }
  232. if ((is_dynamic_array(ld) and
  233. (rt=niln)) or
  234. (is_dynamic_array(ld) and is_dynamic_array(rd)))
  235. and
  236. (treetyp in [equaln,unequaln]) then
  237. begin
  238. allowed:=false;
  239. exit;
  240. end;
  241. allowed:=true;
  242. end;
  243. objectdef :
  244. begin
  245. { <> and = are defined for classes }
  246. if (treetyp in [equaln,unequaln]) and
  247. is_class_or_interface(ld) then
  248. begin
  249. allowed:=false;
  250. exit;
  251. end;
  252. allowed:=true;
  253. end;
  254. stringdef :
  255. begin
  256. if (rd.typ in [orddef,enumdef,stringdef]) or
  257. is_pchar(rd) or
  258. is_pwidechar(rd) or
  259. is_chararray(rd) or
  260. is_widechararray(rd) or
  261. is_open_chararray(rd) or
  262. is_open_widechararray(rd) then
  263. begin
  264. allowed:=false;
  265. exit;
  266. end;
  267. allowed:=true;
  268. end;
  269. else
  270. internal_check:=false;
  271. end;
  272. end;
  273. var
  274. allowed : boolean;
  275. begin
  276. { power ** is always possible }
  277. if (treetyp=starstarn) then
  278. begin
  279. isbinaryoperatoroverloadable:=true;
  280. exit;
  281. end;
  282. { order of arguments does not matter so we have to check also
  283. the reversed order }
  284. allowed:=false;
  285. if not internal_check(treetyp,ld,lt,rd,rt,allowed) then
  286. internal_check(treetyp,rd,rt,ld,lt,allowed);
  287. isbinaryoperatoroverloadable:=allowed;
  288. end;
  289. function isunaryoperatoroverloadable(treetyp : tnodetype;ld : tdef) : boolean;
  290. begin
  291. result:=false;
  292. case treetyp of
  293. subn,
  294. unaryminusn :
  295. begin
  296. if (ld.typ in [orddef,enumdef,floatdef]) then
  297. exit;
  298. {$ifdef SUPPORT_MMX}
  299. if (cs_mmx in current_settings.localswitches) and
  300. is_mmx_able_array(ld) then
  301. exit;
  302. {$endif SUPPORT_MMX}
  303. result:=true;
  304. end;
  305. notn :
  306. begin
  307. if (ld.typ in [orddef,enumdef,floatdef]) then
  308. exit;
  309. {$ifdef SUPPORT_MMX}
  310. if (cs_mmx in current_settings.localswitches) and
  311. is_mmx_able_array(ld) then
  312. exit;
  313. {$endif SUPPORT_MMX}
  314. result:=true;
  315. end;
  316. end;
  317. end;
  318. function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
  319. var
  320. ld,rd : tdef;
  321. i : longint;
  322. eq : tequaltype;
  323. conv : tconverttype;
  324. pd : tprocdef;
  325. oldcount,
  326. count: longint;
  327. parasym : tparavarsym;
  328. begin
  329. result:=false;
  330. count := pf.parast.SymList.count;
  331. oldcount:=count;
  332. while count > 0 do
  333. begin
  334. parasym:=tparavarsym(pf.parast.SymList[count-1]);
  335. if is_boolean(parasym.vardef) then
  336. begin
  337. if parasym.name='RANGECHECK' then
  338. begin
  339. Include(parasym.varoptions, vo_is_hidden_para);
  340. Include(parasym.varoptions, vo_is_range_check);
  341. Dec(count);
  342. end
  343. else if parasym.name='OVERFLOWCHECK' then
  344. begin
  345. Include(parasym.varoptions, vo_is_hidden_para);
  346. Include(parasym.varoptions, vo_is_overflow_check);
  347. Dec(count);
  348. end
  349. else
  350. break;
  351. end
  352. else
  353. break;
  354. end;
  355. if count<>oldcount then
  356. pf.calcparas;
  357. case count of
  358. 1 : begin
  359. ld:=tparavarsym(pf.parast.SymList[0]).vardef;
  360. { assignment is a special case }
  361. if optoken=_ASSIGNMENT then
  362. begin
  363. eq:=compare_defs_ext(ld,pf.returndef,nothingn,conv,pd,[cdo_explicit]);
  364. result:=(eq=te_incompatible);
  365. end
  366. else
  367. begin
  368. for i:=1 to tok2nodes do
  369. if tok2node[i].tok=optoken then
  370. begin
  371. result:=
  372. tok2node[i].op_overloading_supported and
  373. isunaryoperatoroverloadable(tok2node[i].nod,ld);
  374. break;
  375. end;
  376. end;
  377. end;
  378. 2 : begin
  379. for i:=1 to tok2nodes do
  380. if tok2node[i].tok=optoken then
  381. begin
  382. ld:=tparavarsym(pf.parast.SymList[0]).vardef;
  383. rd:=tparavarsym(pf.parast.SymList[1]).vardef;
  384. result:=
  385. tok2node[i].op_overloading_supported and
  386. isbinaryoperatoroverloadable(tok2node[i].nod,ld,nothingn,rd,nothingn);
  387. break;
  388. end;
  389. end;
  390. end;
  391. end;
  392. function isunaryoverloaded(var t : tnode) : boolean;
  393. var
  394. ld : tdef;
  395. optoken : ttoken;
  396. operpd : tprocdef;
  397. ppn : tcallparanode;
  398. candidates : tcallcandidates;
  399. cand_cnt : integer;
  400. begin
  401. result:=false;
  402. operpd:=nil;
  403. { load easier access variables }
  404. ld:=tunarynode(t).left.resultdef;
  405. if not isunaryoperatoroverloadable(t.nodetype,ld) then
  406. exit;
  407. { operator overload is possible }
  408. result:=true;
  409. case t.nodetype of
  410. notn:
  411. optoken:=_OP_NOT;
  412. unaryminusn:
  413. optoken:=_MINUS;
  414. else
  415. begin
  416. CGMessage(parser_e_operator_not_overloaded);
  417. t:=cnothingnode.create;
  418. exit;
  419. end;
  420. end;
  421. { generate parameter nodes }
  422. ppn:=ccallparanode.create(tunarynode(t).left.getcopy,nil);
  423. ppn.get_paratype;
  424. candidates:=tcallcandidates.create_operator(optoken,ppn);
  425. { stop when there are no operators found }
  426. if candidates.count=0 then
  427. begin
  428. CGMessage(parser_e_operator_not_overloaded);
  429. candidates.free;
  430. ppn.free;
  431. t:=cnothingnode.create;
  432. exit;
  433. end;
  434. { Retrieve information about the candidates }
  435. candidates.get_information;
  436. {$ifdef EXTDEBUG}
  437. { Display info when multiple candidates are found }
  438. candidates.dump_info(V_Debug);
  439. {$endif EXTDEBUG}
  440. cand_cnt:=candidates.choose_best(operpd,false);
  441. { exit when no overloads are found }
  442. if cand_cnt=0 then
  443. begin
  444. CGMessage(parser_e_operator_not_overloaded);
  445. candidates.free;
  446. ppn.free;
  447. t:=cnothingnode.create;
  448. exit;
  449. end;
  450. { Multiple candidates left? }
  451. if cand_cnt>1 then
  452. begin
  453. CGMessage(type_e_cant_choose_overload_function);
  454. {$ifdef EXTDEBUG}
  455. candidates.dump_info(V_Hint);
  456. {$else EXTDEBUG}
  457. candidates.list(false);
  458. {$endif EXTDEBUG}
  459. { we'll just use the first candidate to make the
  460. call }
  461. end;
  462. candidates.free;
  463. addsymref(operpd.procsym);
  464. { the nil as symtable signs firstcalln that this is
  465. an overloaded operator }
  466. t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
  467. { we already know the procdef to use, so it can
  468. skip the overload choosing in callnode.pass_typecheck }
  469. tcallnode(t).procdefinition:=operpd;
  470. end;
  471. function isbinaryoverloaded(var t : tnode) : boolean;
  472. var
  473. rd,ld : tdef;
  474. optoken : ttoken;
  475. operpd : tprocdef;
  476. ht : tnode;
  477. ppn : tcallparanode;
  478. candidates : tcallcandidates;
  479. cand_cnt : integer;
  480. begin
  481. isbinaryoverloaded:=false;
  482. operpd:=nil;
  483. { load easier access variables }
  484. ld:=tbinarynode(t).left.resultdef;
  485. rd:=tbinarynode(t).right.resultdef;
  486. if not isbinaryoperatoroverloadable(t.nodetype,ld,tbinarynode(t).left.nodetype,rd,tbinarynode(t).right.nodetype) then
  487. exit;
  488. { operator overload is possible }
  489. result:=true;
  490. case t.nodetype of
  491. equaln,
  492. unequaln :
  493. optoken:=_EQUAL;
  494. addn:
  495. optoken:=_PLUS;
  496. subn:
  497. optoken:=_MINUS;
  498. muln:
  499. optoken:=_STAR;
  500. starstarn:
  501. optoken:=_STARSTAR;
  502. slashn:
  503. optoken:=_SLASH;
  504. ltn:
  505. optoken:=_LT;
  506. gtn:
  507. optoken:=_GT;
  508. lten:
  509. optoken:=_LTE;
  510. gten:
  511. optoken:=_GTE;
  512. symdifn :
  513. optoken:=_SYMDIF;
  514. modn :
  515. optoken:=_OP_MOD;
  516. orn :
  517. optoken:=_OP_OR;
  518. xorn :
  519. optoken:=_OP_XOR;
  520. andn :
  521. optoken:=_OP_AND;
  522. divn :
  523. optoken:=_OP_DIV;
  524. shln :
  525. optoken:=_OP_SHL;
  526. shrn :
  527. optoken:=_OP_SHR;
  528. else
  529. begin
  530. CGMessage(parser_e_operator_not_overloaded);
  531. t:=cnothingnode.create;
  532. exit;
  533. end;
  534. end;
  535. { generate parameter nodes }
  536. ppn:=ccallparanode.create(tbinarynode(t).right.getcopy,ccallparanode.create(tbinarynode(t).left.getcopy,nil));
  537. ppn.get_paratype;
  538. candidates:=tcallcandidates.create_operator(optoken,ppn);
  539. { for commutative operators we can swap arguments and try again }
  540. if (candidates.count=0) and
  541. not(optoken in [_OP_SHL,_OP_SHR,_OP_DIV,_OP_MOD,_STARSTAR,_SLASH,_MINUS]) then
  542. begin
  543. candidates.free;
  544. reverseparameters(ppn);
  545. { reverse compare operators }
  546. case optoken of
  547. _LT:
  548. optoken:=_GTE;
  549. _GT:
  550. optoken:=_LTE;
  551. _LTE:
  552. optoken:=_GT;
  553. _GTE:
  554. optoken:=_LT;
  555. end;
  556. candidates:=tcallcandidates.create_operator(optoken,ppn);
  557. end;
  558. { stop when there are no operators found }
  559. if candidates.count=0 then
  560. begin
  561. CGMessage(parser_e_operator_not_overloaded);
  562. candidates.free;
  563. ppn.free;
  564. t:=cnothingnode.create;
  565. exit;
  566. end;
  567. { Retrieve information about the candidates }
  568. candidates.get_information;
  569. {$ifdef EXTDEBUG}
  570. { Display info when multiple candidates are found }
  571. candidates.dump_info(V_Debug);
  572. {$endif EXTDEBUG}
  573. cand_cnt:=candidates.choose_best(operpd,false);
  574. { exit when no overloads are found }
  575. if cand_cnt=0 then
  576. begin
  577. CGMessage(parser_e_operator_not_overloaded);
  578. candidates.free;
  579. ppn.free;
  580. t:=cnothingnode.create;
  581. exit;
  582. end;
  583. { Multiple candidates left? }
  584. if cand_cnt>1 then
  585. begin
  586. CGMessage(type_e_cant_choose_overload_function);
  587. {$ifdef EXTDEBUG}
  588. candidates.dump_info(V_Hint);
  589. {$else EXTDEBUG}
  590. candidates.list(false);
  591. {$endif EXTDEBUG}
  592. { we'll just use the first candidate to make the
  593. call }
  594. end;
  595. candidates.free;
  596. addsymref(operpd.procsym);
  597. { the nil as symtable signs firstcalln that this is
  598. an overloaded operator }
  599. ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil,[]);
  600. { we already know the procdef to use, so it can
  601. skip the overload choosing in callnode.pass_typecheck }
  602. tcallnode(ht).procdefinition:=operpd;
  603. if t.nodetype=unequaln then
  604. ht:=cnotnode.create(ht);
  605. t:=ht;
  606. end;
  607. {****************************************************************************
  608. Register Calculation
  609. ****************************************************************************}
  610. { marks an lvalue as "unregable" }
  611. procedure make_not_regable_intern(p : tnode; how: tregableinfoflags; records_only: boolean);
  612. var
  613. update_regable: boolean;
  614. begin
  615. update_regable:=true;
  616. repeat
  617. case p.nodetype of
  618. subscriptn:
  619. begin
  620. records_only:=true;
  621. p:=tsubscriptnode(p).left;
  622. end;
  623. vecn:
  624. begin
  625. { arrays are currently never regable and pointers indexed like }
  626. { arrays do not have be made unregable, but we do need to }
  627. { propagate the ra_addr_taken info }
  628. update_regable:=false;
  629. p:=tvecnode(p).left;
  630. end;
  631. typeconvn :
  632. begin
  633. if (ttypeconvnode(p).resultdef.typ = recorddef) then
  634. records_only:=false;
  635. p:=ttypeconvnode(p).left;
  636. end;
  637. loadn :
  638. begin
  639. if (tloadnode(p).symtableentry.typ in [staticvarsym,localvarsym,paravarsym]) then
  640. begin
  641. if (ra_addr_taken in how) then
  642. tabstractvarsym(tloadnode(p).symtableentry).addr_taken:=true;
  643. if update_regable and
  644. (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
  645. ((not records_only) or
  646. (tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then
  647. if (tloadnode(p).symtableentry.typ = paravarsym) and
  648. (ra_addr_regable in how) then
  649. tabstractvarsym(tloadnode(p).symtableentry).varregable:=vr_addr
  650. else
  651. tabstractvarsym(tloadnode(p).symtableentry).varregable:=vr_none;
  652. end;
  653. break;
  654. end;
  655. temprefn :
  656. begin
  657. if (ra_addr_taken in how) then
  658. include(ttemprefnode(p).tempinfo^.flags,ti_addr_taken);
  659. if update_regable and
  660. (ti_may_be_in_reg in ttemprefnode(p).tempinfo^.flags) and
  661. ((not records_only) or
  662. (ttemprefnode(p).tempinfo^.typedef.typ = recorddef)) then
  663. exclude(ttemprefnode(p).tempinfo^.flags,ti_may_be_in_reg);
  664. break;
  665. end;
  666. else
  667. break;
  668. end;
  669. until false;
  670. end;
  671. procedure make_not_regable(p : tnode; how: tregableinfoflags);
  672. begin
  673. make_not_regable_intern(p,how,false);
  674. end;
  675. {****************************************************************************
  676. Subroutine Handling
  677. ****************************************************************************}
  678. function is_procvar_load(p:tnode):boolean;
  679. begin
  680. result:=false;
  681. { remove voidpointer typecast for tp procvars }
  682. if ((m_tp_procvar in current_settings.modeswitches) or
  683. (m_mac_procvar in current_settings.modeswitches)) and
  684. (p.nodetype=typeconvn) and
  685. is_voidpointer(p.resultdef) then
  686. p:=tunarynode(p).left;
  687. result:=(p.nodetype=typeconvn) and
  688. (ttypeconvnode(p).convtype=tc_proc_2_procvar);
  689. end;
  690. { local routines can't be assigned to procvars }
  691. procedure test_local_to_procvar(from_def:tprocvardef;to_def:tdef);
  692. begin
  693. if (from_def.parast.symtablelevel>normal_function_level) and
  694. (to_def.typ=procvardef) then
  695. CGMessage(type_e_cannot_local_proc_to_procvar);
  696. end;
  697. procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
  698. const
  699. vstrans: array[tvarstate,tvarstate] of tvarstate = (
  700. { vs_none -> ... }
  701. (vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
  702. { vs_declared -> ... }
  703. (vs_none,vs_declared,vs_initialised,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
  704. { vs_initialised -> ... }
  705. (vs_none,vs_initialised,vs_initialised,vs_read,vs_read,vs_read,vs_written,vs_readwritten),
  706. { vs_read -> ... }
  707. (vs_none,vs_read,vs_read,vs_read,vs_read,vs_read,vs_readwritten,vs_readwritten),
  708. { vs_read_not_warned -> ... }
  709. (vs_none,vs_read_not_warned,vs_read,vs_read,vs_read_not_warned,vs_read_not_warned,vs_readwritten,vs_readwritten),
  710. { vs_referred_not_inited }
  711. (vs_none,vs_referred_not_inited,vs_read,vs_read,vs_read_not_warned,vs_referred_not_inited,vs_written,vs_readwritten),
  712. { vs_written -> ... }
  713. (vs_none,vs_written,vs_written,vs_readwritten,vs_readwritten,vs_written,vs_written,vs_readwritten),
  714. { vs_readwritten -> ... }
  715. (vs_none,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten));
  716. var
  717. hsym : tabstractvarsym;
  718. begin
  719. { make sure we can still warn about uninitialised use after high(v), @v etc }
  720. if (newstate = vs_read) and
  721. not(vsf_must_be_valid in varstateflags) then
  722. newstate := vs_referred_not_inited;
  723. while assigned(p) do
  724. begin
  725. case p.nodetype of
  726. derefn:
  727. begin
  728. if (tderefnode(p).left.nodetype=temprefn) and
  729. assigned(ttemprefnode(tderefnode(p).left).tempinfo^.withnode) then
  730. p:=ttemprefnode(tderefnode(p).left).tempinfo^.withnode
  731. else
  732. break;
  733. end;
  734. typeconvn :
  735. begin
  736. case ttypeconvnode(p).convtype of
  737. tc_cchar_2_pchar,
  738. tc_cstring_2_pchar,
  739. tc_array_2_pointer :
  740. exclude(varstateflags,vsf_must_be_valid);
  741. tc_pchar_2_string,
  742. tc_pointer_2_array :
  743. include(varstateflags,vsf_must_be_valid);
  744. end;
  745. p:=tunarynode(p).left;
  746. end;
  747. subscriptn :
  748. begin
  749. if is_class_or_interface(tunarynode(p).left.resultdef) then
  750. newstate := vs_read;
  751. p:=tunarynode(p).left;
  752. end;
  753. vecn:
  754. begin
  755. set_varstate(tbinarynode(p).right,vs_read,[vsf_must_be_valid]);
  756. if (newstate in [vs_read,vs_readwritten]) or
  757. not(tunarynode(p).left.resultdef.typ in [stringdef,arraydef]) then
  758. include(varstateflags,vsf_must_be_valid)
  759. else if (newstate = vs_written) then
  760. exclude(varstateflags,vsf_must_be_valid);
  761. p:=tunarynode(p).left;
  762. end;
  763. { do not parse calln }
  764. calln :
  765. break;
  766. loadn :
  767. begin
  768. if (tloadnode(p).symtableentry.typ in [localvarsym,paravarsym,staticvarsym]) then
  769. begin
  770. hsym:=tabstractvarsym(tloadnode(p).symtableentry);
  771. if (vsf_must_be_valid in varstateflags) and
  772. (hsym.varstate in [vs_declared,vs_read_not_warned,vs_referred_not_inited]) then
  773. begin
  774. { Give warning/note for uninitialized locals }
  775. if assigned(hsym.owner) and
  776. not(cs_opt_nodedfa in current_settings.optimizerswitches) and
  777. not(vo_is_external in hsym.varoptions) and
  778. (hsym.owner.symtabletype in [parasymtable,localsymtable,staticsymtable]) and
  779. ((hsym.owner=current_procinfo.procdef.localst) or
  780. (hsym.owner=current_procinfo.procdef.parast)) then
  781. begin
  782. if (vo_is_funcret in hsym.varoptions) then
  783. begin
  784. if (vsf_use_hints in varstateflags) then
  785. CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized)
  786. else
  787. CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized)
  788. end
  789. else
  790. begin
  791. if tloadnode(p).symtable.symtabletype=localsymtable then
  792. begin
  793. if (vsf_use_hints in varstateflags) then
  794. CGMessagePos1(p.fileinfo,sym_h_uninitialized_local_variable,hsym.realname)
  795. else
  796. CGMessagePos1(p.fileinfo,sym_w_uninitialized_local_variable,hsym.realname);
  797. end
  798. else
  799. begin
  800. if (vsf_use_hints in varstateflags) then
  801. CGMessagePos1(p.fileinfo,sym_h_uninitialized_variable,hsym.realname)
  802. else
  803. CGMessagePos1(p.fileinfo,sym_w_uninitialized_variable,hsym.realname);
  804. end;
  805. end;
  806. end
  807. else if (newstate = vs_read) then
  808. newstate := vs_read_not_warned;
  809. end;
  810. hsym.varstate := vstrans[hsym.varstate,newstate];
  811. end;
  812. break;
  813. end;
  814. callparan :
  815. internalerror(200310081);
  816. else
  817. break;
  818. end;{case }
  819. end;
  820. end;
  821. procedure set_unique(p : tnode);
  822. begin
  823. while assigned(p) do
  824. begin
  825. case p.nodetype of
  826. vecn:
  827. begin
  828. include(p.flags,nf_callunique);
  829. break;
  830. end;
  831. typeconvn,
  832. subscriptn,
  833. derefn:
  834. p:=tunarynode(p).left;
  835. else
  836. break;
  837. end;
  838. end;
  839. end;
  840. function valid_for_assign(p:tnode;opts:TValidAssigns; report_errors: boolean):boolean;
  841. var
  842. hp2,
  843. hp : tnode;
  844. gotstring,
  845. gotsubscript,
  846. gotrecord,
  847. gotpointer,
  848. gotvec,
  849. gotclass,
  850. gotdynarray,
  851. gotderef : boolean;
  852. fromdef,
  853. todef : tdef;
  854. errmsg,
  855. temp : longint;
  856. begin
  857. if valid_const in opts then
  858. errmsg:=type_e_variable_id_expected
  859. else if valid_property in opts then
  860. errmsg:=type_e_argument_cant_be_assigned
  861. else
  862. errmsg:=type_e_no_addr_of_constant;
  863. result:=false;
  864. gotsubscript:=false;
  865. gotvec:=false;
  866. gotderef:=false;
  867. gotrecord:=false;
  868. gotclass:=false;
  869. gotpointer:=false;
  870. gotdynarray:=false;
  871. gotstring:=false;
  872. hp:=p;
  873. if not(valid_void in opts) and
  874. is_void(hp.resultdef) then
  875. begin
  876. if report_errors then
  877. CGMessagePos(hp.fileinfo,errmsg);
  878. exit;
  879. end;
  880. while assigned(hp) do
  881. begin
  882. { property allowed? calln has a property check itself }
  883. if (nf_isproperty in hp.flags) then
  884. begin
  885. { check return type }
  886. case hp.resultdef.typ of
  887. pointerdef :
  888. gotpointer:=true;
  889. objectdef :
  890. gotclass:=is_class_or_interface(hp.resultdef);
  891. recorddef :
  892. gotrecord:=true;
  893. classrefdef :
  894. gotclass:=true;
  895. stringdef :
  896. gotstring:=true;
  897. end;
  898. if (valid_property in opts) then
  899. begin
  900. { don't allow writing to calls that will create
  901. temps like calls that return a structure and we
  902. are assigning to a member }
  903. if (valid_const in opts) or
  904. { if we got a deref, we won't modify the property itself }
  905. (gotderef) or
  906. { same when we got a class and subscript (= deref) }
  907. (gotclass and gotsubscript) or
  908. (
  909. not(gotsubscript and gotrecord) and
  910. not(gotstring and gotvec)
  911. ) then
  912. result:=true
  913. else
  914. if report_errors then
  915. CGMessagePos(hp.fileinfo,errmsg);
  916. end
  917. else
  918. begin
  919. { 1. if it returns a pointer and we've found a deref,
  920. 2. if it returns a class or record and a subscription or with is found
  921. 3. if the address is needed of a field (subscriptn, vecn) }
  922. if (gotpointer and gotderef) or
  923. (gotstring and gotvec) or
  924. (
  925. (gotclass or gotrecord) and
  926. (gotsubscript)
  927. ) or
  928. (
  929. (gotvec and gotdynarray)
  930. ) or
  931. (
  932. (Valid_Addr in opts) and
  933. (hp.nodetype in [subscriptn,vecn])
  934. ) then
  935. result:=true
  936. else
  937. if report_errors then
  938. CGMessagePos(hp.fileinfo,errmsg);
  939. end;
  940. exit;
  941. end;
  942. if (Valid_Const in opts) and is_constnode(hp) then
  943. begin
  944. result:=true;
  945. exit;
  946. end;
  947. case hp.nodetype of
  948. temprefn :
  949. begin
  950. valid_for_assign := true;
  951. exit;
  952. end;
  953. derefn :
  954. begin
  955. gotderef:=true;
  956. hp:=tderefnode(hp).left;
  957. end;
  958. typeconvn :
  959. begin
  960. { typecast sizes must match, exceptions:
  961. - implicit typecast made by absolute
  962. - from formaldef
  963. - from void
  964. - from/to open array
  965. - typecast from pointer to array }
  966. fromdef:=ttypeconvnode(hp).left.resultdef;
  967. todef:=hp.resultdef;
  968. if not((nf_absolute in ttypeconvnode(hp).flags) or
  969. (fromdef.typ=formaldef) or
  970. is_void(fromdef) or
  971. is_open_array(fromdef) or
  972. is_open_array(todef) or
  973. ((fromdef.typ=pointerdef) and (todef.typ=arraydef)) or
  974. ((fromdef.typ = objectdef) and (todef.typ = objectdef) and
  975. (tobjectdef(fromdef).is_related(tobjectdef(todef))))) and
  976. (fromdef.size<>todef.size) then
  977. begin
  978. { in TP it is allowed to typecast to smaller types. But the variable can't
  979. be in a register }
  980. if (m_tp7 in current_settings.modeswitches) or
  981. (todef.size<fromdef.size) then
  982. make_not_regable(hp,[ra_addr_regable])
  983. else
  984. if report_errors then
  985. CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
  986. end;
  987. { don't allow assignments to typeconvs that need special code }
  988. if not(gotsubscript or gotvec or gotderef) and
  989. not(ttypeconvnode(hp).assign_allowed) then
  990. begin
  991. if report_errors then
  992. CGMessagePos(hp.fileinfo,errmsg);
  993. exit;
  994. end;
  995. case hp.resultdef.typ of
  996. pointerdef :
  997. gotpointer:=true;
  998. objectdef :
  999. gotclass:=is_class_or_interface(hp.resultdef);
  1000. classrefdef :
  1001. gotclass:=true;
  1002. arraydef :
  1003. begin
  1004. { pointer -> array conversion is done then we need to see it
  1005. as a deref, because a ^ is then not required anymore }
  1006. if (ttypeconvnode(hp).left.resultdef.typ=pointerdef) then
  1007. gotderef:=true;
  1008. end;
  1009. end;
  1010. hp:=ttypeconvnode(hp).left;
  1011. end;
  1012. vecn :
  1013. begin
  1014. if { only check for first (= outermost) vec node }
  1015. not gotvec and
  1016. not(valid_packed in opts) and
  1017. (tvecnode(hp).left.resultdef.typ = arraydef) and
  1018. (ado_IsBitPacked in tarraydef(tvecnode(hp).left.resultdef).arrayoptions) and
  1019. ((tarraydef(tvecnode(hp).left.resultdef).elepackedbitsize mod 8 <> 0) or
  1020. (is_ordinal(tarraydef(tvecnode(hp).left.resultdef).elementdef) and
  1021. not ispowerof2(tarraydef(tvecnode(hp).left.resultdef).elepackedbitsize div 8,temp))) then
  1022. begin
  1023. if report_errors then
  1024. if (valid_property in opts) then
  1025. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_loop)
  1026. else
  1027. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_var_addr);
  1028. exit;
  1029. end;
  1030. gotvec:=true;
  1031. { accesses to dyn. arrays override read only access in delphi }
  1032. if (m_delphi in current_settings.modeswitches) and is_dynamic_array(tunarynode(hp).left.resultdef) then
  1033. gotdynarray:=true;
  1034. hp:=tunarynode(hp).left;
  1035. end;
  1036. blockn :
  1037. begin
  1038. hp2:=tblocknode(hp).statements;
  1039. if assigned(hp2) then
  1040. begin
  1041. if hp2.nodetype<>statementn then
  1042. internalerror(2006110801);
  1043. while assigned(tstatementnode(hp2).next) do
  1044. hp2:=tstatementnode(hp2).next;
  1045. hp:=tstatementnode(hp2).statement;
  1046. end
  1047. else
  1048. begin
  1049. if report_errors then
  1050. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1051. exit;
  1052. end;
  1053. end;
  1054. asn :
  1055. begin
  1056. { asn can't be assigned directly, it returns the value in a register instead
  1057. of reference. }
  1058. if not(gotsubscript or gotderef or gotvec) then
  1059. begin
  1060. if report_errors then
  1061. CGMessagePos(hp.fileinfo,errmsg);
  1062. exit;
  1063. end;
  1064. hp:=tunarynode(hp).left;
  1065. end;
  1066. subscriptn :
  1067. begin
  1068. { only check first (= outermost) subscriptn }
  1069. if not gotsubscript and
  1070. not(valid_packed in opts) and
  1071. is_packed_record_or_object(tsubscriptnode(hp).left.resultdef) and
  1072. ((tsubscriptnode(hp).vs.fieldoffset mod 8 <> 0) or
  1073. (is_ordinal(tsubscriptnode(hp).resultdef) and
  1074. not ispowerof2(tsubscriptnode(hp).resultdef.packedbitsize div 8,temp))) then
  1075. begin
  1076. if report_errors then
  1077. if (valid_property in opts) then
  1078. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_loop)
  1079. else
  1080. CGMessagePos(hp.fileinfo,parser_e_packed_element_no_var_addr);
  1081. exit;
  1082. end;
  1083. gotsubscript:=true;
  1084. { loop counter? }
  1085. if not(Valid_Const in opts) and
  1086. (vo_is_loop_counter in tsubscriptnode(hp).vs.varoptions) then
  1087. begin
  1088. if report_errors then
  1089. CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname)
  1090. else
  1091. exit;
  1092. end;
  1093. { a class/interface access is an implicit }
  1094. { dereferencing }
  1095. hp:=tsubscriptnode(hp).left;
  1096. if is_class_or_interface(hp.resultdef) then
  1097. gotderef:=true;
  1098. end;
  1099. muln,
  1100. divn,
  1101. andn,
  1102. xorn,
  1103. orn,
  1104. notn,
  1105. subn,
  1106. addn :
  1107. begin
  1108. { Allow operators on a pointer, or an integer
  1109. and a pointer typecast and deref has been found }
  1110. if ((hp.resultdef.typ=pointerdef) or
  1111. (is_integer(hp.resultdef) and gotpointer)) and
  1112. gotderef then
  1113. result:=true
  1114. else
  1115. { Temp strings are stored in memory, for compatibility with
  1116. delphi only }
  1117. if (m_delphi in current_settings.modeswitches) and
  1118. ((valid_addr in opts) or
  1119. (valid_const in opts)) and
  1120. (hp.resultdef.typ=stringdef) then
  1121. result:=true
  1122. else
  1123. if report_errors then
  1124. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1125. exit;
  1126. end;
  1127. niln,
  1128. pointerconstn :
  1129. begin
  1130. { to support e.g. @tmypointer(0)^.data; see tests/tbs/tb0481 }
  1131. if gotderef then
  1132. result:=true
  1133. else
  1134. if report_errors then
  1135. CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
  1136. exit;
  1137. end;
  1138. addrn :
  1139. begin
  1140. if gotderef then
  1141. result:=true
  1142. else
  1143. if report_errors then
  1144. CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
  1145. exit;
  1146. end;
  1147. calln :
  1148. begin
  1149. { check return type }
  1150. case hp.resultdef.typ of
  1151. arraydef :
  1152. begin
  1153. { dynamic arrays are allowed when there is also a
  1154. vec node }
  1155. if is_dynamic_array(hp.resultdef) and
  1156. gotvec then
  1157. begin
  1158. gotderef:=true;
  1159. gotpointer:=true;
  1160. end;
  1161. end;
  1162. pointerdef :
  1163. gotpointer:=true;
  1164. objectdef :
  1165. gotclass:=is_class_or_interface(hp.resultdef);
  1166. recorddef, { handle record like class it needs a subscription }
  1167. classrefdef :
  1168. gotclass:=true;
  1169. stringdef :
  1170. gotstring:=true;
  1171. end;
  1172. { 1. if it returns a pointer and we've found a deref,
  1173. 2. if it returns a class or record and a subscription or with is found
  1174. 3. string is returned }
  1175. if (gotstring and gotvec) or
  1176. (gotpointer and gotderef) or
  1177. (gotclass and gotsubscript) then
  1178. result:=true
  1179. else
  1180. { Temp strings are stored in memory, for compatibility with
  1181. delphi only }
  1182. if (m_delphi in current_settings.modeswitches) and
  1183. (valid_addr in opts) and
  1184. (hp.resultdef.typ=stringdef) then
  1185. result:=true
  1186. else
  1187. if ([valid_const,valid_addr] * opts = [valid_const]) then
  1188. result:=true
  1189. else
  1190. if report_errors then
  1191. CGMessagePos(hp.fileinfo,errmsg);
  1192. exit;
  1193. end;
  1194. inlinen :
  1195. begin
  1196. if ((valid_const in opts) and
  1197. (tinlinenode(hp).inlinenumber in [in_typeof_x]))
  1198. {$ifdef SUPPORT_UNALIGNED}
  1199. or (tinlinenode(hp).inlinenumber in [in_unaligned_x])
  1200. {$endif SUPPORT_UNALIGNED}
  1201. then
  1202. result:=true
  1203. else
  1204. if report_errors then
  1205. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1206. exit;
  1207. end;
  1208. dataconstn:
  1209. begin
  1210. { only created internally, so no additional checks necessary }
  1211. result:=true;
  1212. exit;
  1213. end;
  1214. loadn :
  1215. begin
  1216. case tloadnode(hp).symtableentry.typ of
  1217. absolutevarsym,
  1218. staticvarsym,
  1219. localvarsym,
  1220. paravarsym :
  1221. begin
  1222. { loop counter? }
  1223. if not(Valid_Const in opts) and
  1224. not gotderef and
  1225. (vo_is_loop_counter in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
  1226. if report_errors then
  1227. CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname)
  1228. else
  1229. exit;
  1230. { read-only variable? }
  1231. if (tabstractvarsym(tloadnode(hp).symtableentry).varspez=vs_const) then
  1232. begin
  1233. { allow p^:= constructions with p is const parameter }
  1234. if gotderef or gotdynarray or (Valid_Const in opts) or
  1235. (nf_isinternal_ignoreconst in tloadnode(hp).flags) then
  1236. result:=true
  1237. else
  1238. if report_errors then
  1239. CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
  1240. exit;
  1241. end;
  1242. result:=true;
  1243. exit;
  1244. end;
  1245. procsym :
  1246. begin
  1247. if (Valid_Const in opts) then
  1248. result:=true
  1249. else
  1250. if report_errors then
  1251. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1252. exit;
  1253. end;
  1254. labelsym :
  1255. begin
  1256. if (Valid_Addr in opts) then
  1257. result:=true
  1258. else
  1259. if report_errors then
  1260. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1261. exit;
  1262. end;
  1263. constsym:
  1264. begin
  1265. if (tconstsym(tloadnode(hp).symtableentry).consttyp=constresourcestring) and
  1266. (valid_addr in opts) then
  1267. result:=true
  1268. else
  1269. if report_errors then
  1270. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1271. exit;
  1272. end;
  1273. else
  1274. begin
  1275. if report_errors then
  1276. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1277. exit;
  1278. end;
  1279. end;
  1280. end;
  1281. else
  1282. begin
  1283. if report_errors then
  1284. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  1285. exit;
  1286. end;
  1287. end;
  1288. end;
  1289. end;
  1290. function valid_for_var(p:tnode; report_errors: boolean):boolean;
  1291. begin
  1292. valid_for_var:=valid_for_assign(p,[],report_errors);
  1293. end;
  1294. function valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
  1295. begin
  1296. valid_for_formal_var:=valid_for_assign(p,[valid_void],report_errors);
  1297. end;
  1298. function valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
  1299. begin
  1300. valid_for_formal_const:=(p.resultdef.typ=formaldef) or
  1301. valid_for_assign(p,[valid_void,valid_const,valid_property],report_errors);
  1302. end;
  1303. function valid_for_assignment(p:tnode; report_errors: boolean):boolean;
  1304. begin
  1305. valid_for_assignment:=valid_for_assign(p,[valid_property,valid_packed],report_errors);
  1306. end;
  1307. function valid_for_loopvar(p:tnode; report_errors: boolean):boolean;
  1308. begin
  1309. valid_for_loopvar:=valid_for_assign(p,[valid_property],report_errors);
  1310. end;
  1311. function valid_for_addr(p : tnode; report_errors: boolean) : boolean;
  1312. begin
  1313. result:=valid_for_assign(p,[valid_const,valid_addr,valid_void],report_errors);
  1314. end;
  1315. procedure var_para_allowed(var eq:tequaltype;def_from,def_to:Tdef);
  1316. begin
  1317. { Note: eq must be already valid, it will only be updated! }
  1318. case def_to.typ of
  1319. formaldef :
  1320. begin
  1321. { all types can be passed to a formaldef,
  1322. but it is not the prefered way }
  1323. eq:=te_convert_l2;
  1324. end;
  1325. orddef :
  1326. begin
  1327. { allows conversion from word to integer and
  1328. byte to shortint, but only for TP7 compatibility }
  1329. if (m_tp7 in current_settings.modeswitches) and
  1330. (def_from.typ=orddef) and
  1331. (def_from.size=def_to.size) then
  1332. eq:=te_convert_l1;
  1333. end;
  1334. arraydef :
  1335. begin
  1336. if is_open_array(def_to) then
  1337. begin
  1338. if is_dynamic_array(def_from) and
  1339. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  1340. eq:=te_convert_l2
  1341. else
  1342. if equal_defs(def_from,tarraydef(def_to).elementdef) then
  1343. eq:=te_convert_l2;
  1344. end;
  1345. end;
  1346. pointerdef :
  1347. begin
  1348. { an implicit pointer conversion is allowed }
  1349. if (def_from.typ=pointerdef) then
  1350. eq:=te_convert_l1;
  1351. end;
  1352. stringdef :
  1353. begin
  1354. { all shortstrings are allowed, size is not important }
  1355. if is_shortstring(def_from) and
  1356. is_shortstring(def_to) then
  1357. eq:=te_equal;
  1358. end;
  1359. objectdef :
  1360. begin
  1361. { child objects can be also passed }
  1362. { in non-delphi mode, otherwise }
  1363. { they must match exactly, except }
  1364. { if they are objects }
  1365. if (def_from.typ=objectdef) and
  1366. (
  1367. not(m_delphi in current_settings.modeswitches) or
  1368. (
  1369. (tobjectdef(def_from).objecttype=odt_object) and
  1370. (tobjectdef(def_to).objecttype=odt_object)
  1371. )
  1372. ) and
  1373. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  1374. eq:=te_convert_l1;
  1375. end;
  1376. filedef :
  1377. begin
  1378. { an implicit file conversion is also allowed }
  1379. { from a typed file to an untyped one }
  1380. if (def_from.typ=filedef) and
  1381. (tfiledef(def_from).filetyp = ft_typed) and
  1382. (tfiledef(def_to).filetyp = ft_untyped) then
  1383. eq:=te_convert_l1;
  1384. end;
  1385. end;
  1386. end;
  1387. procedure para_allowed(var eq:tequaltype;p:tcallparanode;def_to:tdef);
  1388. begin
  1389. { Note: eq must be already valid, it will only be updated! }
  1390. case def_to.typ of
  1391. formaldef :
  1392. begin
  1393. { all types can be passed to a formaldef }
  1394. eq:=te_equal;
  1395. end;
  1396. stringdef :
  1397. begin
  1398. { to support ansi/long/wide strings in a proper way }
  1399. { string and string[10] are assumed as equal }
  1400. { when searching the correct overloaded procedure }
  1401. if (p.resultdef.typ=stringdef) and
  1402. (tstringdef(def_to).stringtype=tstringdef(p.resultdef).stringtype) then
  1403. eq:=te_equal
  1404. else
  1405. { Passing a constant char to ansistring or shortstring or
  1406. a widechar to widestring then handle it as equal. }
  1407. if (p.left.nodetype=ordconstn) and
  1408. (
  1409. is_char(p.resultdef) and
  1410. (is_shortstring(def_to) or is_ansistring(def_to))
  1411. ) or
  1412. (
  1413. is_widechar(p.resultdef) and
  1414. is_widestring(def_to)
  1415. ) then
  1416. eq:=te_equal
  1417. end;
  1418. setdef :
  1419. begin
  1420. { set can also be a not yet converted array constructor }
  1421. if (p.resultdef.typ=arraydef) and
  1422. is_array_constructor(p.resultdef) and
  1423. not is_variant_array(p.resultdef) then
  1424. eq:=te_equal;
  1425. end;
  1426. procvardef :
  1427. begin
  1428. { in tp7 mode proc -> procvar is allowed }
  1429. if ((m_tp_procvar in current_settings.modeswitches) or
  1430. (m_mac_procvar in current_settings.modeswitches)) and
  1431. (p.left.nodetype=calln) and
  1432. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def_to))>=te_equal) then
  1433. eq:=te_equal
  1434. else
  1435. if (m_mac_procvar in current_settings.modeswitches) and
  1436. is_procvar_load(p.left) then
  1437. eq:=te_convert_l2;
  1438. end;
  1439. end;
  1440. end;
  1441. function allowenumop(nt:tnodetype):boolean;
  1442. begin
  1443. result:=(nt in [equaln,unequaln,ltn,lten,gtn,gten]) or
  1444. ((cs_allow_enum_calc in current_settings.localswitches) and
  1445. (nt in [addn,subn]));
  1446. end;
  1447. {****************************************************************************
  1448. TCallCandidates
  1449. ****************************************************************************}
  1450. constructor tcallcandidates.create(sym:tprocsym;st:TSymtable;ppn:tnode;isprop,ignorevis : boolean);
  1451. var
  1452. j : integer;
  1453. pd : tprocdef;
  1454. hp : pcandidate;
  1455. found,
  1456. has_overload_directive : boolean;
  1457. topclassh : tobjectdef;
  1458. srsymtable : TSymtable;
  1459. srprocsym : tprocsym;
  1460. pt : tcallparanode;
  1461. checkstack : psymtablestackitem;
  1462. hashedid : THashedIDString;
  1463. begin
  1464. if not assigned(sym) then
  1465. internalerror(200411015);
  1466. FProcSym:=sym;
  1467. FProcs:=nil;
  1468. FProccnt:=0;
  1469. FProcvisiblecnt:=0;
  1470. FParanode:=ppn;
  1471. FAllowVariant:=true;
  1472. { determine length of parameter list }
  1473. pt:=tcallparanode(ppn);
  1474. FParalength:=0;
  1475. while assigned(pt) do
  1476. begin
  1477. inc(FParalength);
  1478. pt:=tcallparanode(pt.right);
  1479. end;
  1480. { when the definition has overload directive set, we search for
  1481. overloaded definitions in the class, this only needs to be done once
  1482. for class entries as the tree keeps always the same }
  1483. if (not sym.overloadchecked) and
  1484. (sym.owner.symtabletype=ObjectSymtable) and
  1485. (po_overload in tprocdef(sym.ProcdefList[0]).procoptions) then
  1486. search_class_overloads(sym);
  1487. { when the class passed is defined in this unit we
  1488. need to use the scope of that class. This is a trick
  1489. that can be used to access protected members in other
  1490. units. At least kylix supports it this way (PFV) }
  1491. if assigned(st) and
  1492. (
  1493. (st.symtabletype=ObjectSymtable) or
  1494. ((st.symtabletype=withsymtable) and
  1495. (st.defowner.typ=objectdef))
  1496. ) and
  1497. (st.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1498. st.defowner.owner.iscurrentunit then
  1499. topclassh:=tobjectdef(st.defowner)
  1500. else
  1501. begin
  1502. if assigned(current_procinfo) then
  1503. topclassh:=current_procinfo.procdef._class
  1504. else
  1505. topclassh:=nil;
  1506. end;
  1507. { link all procedures which have the same # of parameters }
  1508. for j:=0 to sym.ProcdefList.Count-1 do
  1509. begin
  1510. pd:=tprocdef(sym.ProcdefList[j]);
  1511. { Is the procdef visible? This needs to be checked on
  1512. procdef level since a symbol can contain both private and
  1513. public declarations. But the check should not be done
  1514. when the callnode is generated by a property
  1515. inherited overrides invisible anonymous inherited (FK) }
  1516. if isprop or ignorevis or
  1517. (pd.owner.symtabletype<>ObjectSymtable) or
  1518. pd.is_visible_for_object(topclassh,nil) then
  1519. begin
  1520. { we have at least one procedure that is visible }
  1521. inc(FProcvisiblecnt);
  1522. { only when the # of parameter are supported by the
  1523. procedure }
  1524. if (FParalength>=pd.minparacount) and
  1525. ((po_varargs in pd.procoptions) or { varargs }
  1526. (FParalength<=pd.maxparacount)) then
  1527. proc_add(sym,pd);
  1528. end;
  1529. end;
  1530. { remember if the procedure is declared with the overload directive,
  1531. it's information is still needed also after all procs are removed }
  1532. has_overload_directive:=(po_overload in tprocdef(sym.ProcdefList[0]).procoptions);
  1533. { when the definition has overload directive set, we search for
  1534. overloaded definitions in the symtablestack. The found
  1535. entries are only added to the procs list and not the procsym, because
  1536. the list can change in every situation }
  1537. if has_overload_directive and
  1538. (sym.owner.symtabletype<>ObjectSymtable) then
  1539. begin
  1540. srsymtable:=sym.owner;
  1541. checkstack:=symtablestack.stack;
  1542. while assigned(checkstack) and
  1543. (checkstack^.symtable<>srsymtable) do
  1544. checkstack:=checkstack^.next;
  1545. { we've already processed the current symtable, start with
  1546. the next symtable in the stack }
  1547. if assigned(checkstack) then
  1548. checkstack:=checkstack^.next;
  1549. hashedid.id:=sym.name;
  1550. while assigned(checkstack) do
  1551. begin
  1552. srsymtable:=checkstack^.symtable;
  1553. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1554. begin
  1555. srprocsym:=tprocsym(srsymtable.FindWithHash(hashedid));
  1556. if assigned(srprocsym) and
  1557. (srprocsym.typ=procsym) then
  1558. begin
  1559. { if this visible procedure doesn't have overload we can stop
  1560. searching }
  1561. if not(po_overload in tprocdef(srprocsym.ProcdefList[0]).procoptions) and
  1562. tprocdef(srprocsym.ProcdefList[0]).is_visible_for_object(topclassh,nil) then
  1563. break;
  1564. { process all overloaded definitions }
  1565. for j:=0 to srprocsym.ProcdefList.Count-1 do
  1566. begin
  1567. pd:=tprocdef(srprocsym.ProcdefList[j]);
  1568. { only visible procedures need to be added }
  1569. if pd.is_visible_for_object(topclassh,nil) then
  1570. begin
  1571. { only when the # of parameter are supported by the
  1572. procedure }
  1573. if (FParalength>=pd.minparacount) and
  1574. ((po_varargs in pd.procoptions) or { varargs }
  1575. (FParalength<=pd.maxparacount)) then
  1576. begin
  1577. found:=false;
  1578. hp:=FProcs;
  1579. while assigned(hp) do
  1580. begin
  1581. { Only compare visible parameters for the user }
  1582. if compare_paras(hp^.data.paras,pd.paras,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
  1583. begin
  1584. found:=true;
  1585. break;
  1586. end;
  1587. hp:=hp^.next;
  1588. end;
  1589. if not found then
  1590. proc_add(srprocsym,pd);
  1591. end;
  1592. end;
  1593. end;
  1594. end;
  1595. end;
  1596. checkstack:=checkstack^.next;
  1597. end;
  1598. end;
  1599. end;
  1600. constructor tcallcandidates.create_operator(op:ttoken;ppn:tnode);
  1601. var
  1602. j : integer;
  1603. pd : tprocdef;
  1604. hp : pcandidate;
  1605. found : boolean;
  1606. srsymtable : TSymtable;
  1607. srprocsym : tprocsym;
  1608. pt : tcallparanode;
  1609. checkstack : psymtablestackitem;
  1610. hashedid : THashedIDString;
  1611. begin
  1612. FProcSym:=nil;
  1613. FProcs:=nil;
  1614. FProccnt:=0;
  1615. FProcvisiblecnt:=0;
  1616. FParanode:=ppn;
  1617. FAllowVariant:=false;
  1618. { determine length of parameter list }
  1619. pt:=tcallparanode(ppn);
  1620. FParalength:=0;
  1621. while assigned(pt) do
  1622. begin
  1623. if pt.resultdef.typ=variantdef then
  1624. FAllowVariant:=true;
  1625. inc(FParalength);
  1626. pt:=tcallparanode(pt.right);
  1627. end;
  1628. { we search all overloaded operator definitions in the symtablestack. The found
  1629. entries are only added to the procs list and not the procsym, because
  1630. the list can change in every situation }
  1631. hashedid.id:=overloaded_names[op];
  1632. checkstack:=symtablestack.stack;
  1633. while assigned(checkstack) do
  1634. begin
  1635. srsymtable:=checkstack^.symtable;
  1636. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1637. begin
  1638. srprocsym:=tprocsym(srsymtable.FindWithHash(hashedid));
  1639. if assigned(srprocsym) and
  1640. (srprocsym.typ=procsym) then
  1641. begin
  1642. { Store first procsym found }
  1643. if not assigned(FProcsym) then
  1644. FProcsym:=srprocsym;
  1645. { process all overloaded definitions }
  1646. for j:=0 to srprocsym.ProcdefList.Count-1 do
  1647. begin
  1648. pd:=tprocdef(srprocsym.ProcdefList[j]);
  1649. { only when the # of parameter are supported by the
  1650. procedure }
  1651. if (FParalength>=pd.minparacount) and
  1652. (FParalength<=pd.maxparacount) then
  1653. begin
  1654. found:=false;
  1655. hp:=FProcs;
  1656. while assigned(hp) do
  1657. begin
  1658. { Only compare visible parameters for the user }
  1659. if compare_paras(hp^.data.paras,pd.paras,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
  1660. begin
  1661. found:=true;
  1662. break;
  1663. end;
  1664. hp:=hp^.next;
  1665. end;
  1666. if not found then
  1667. proc_add(srprocsym,pd);
  1668. end;
  1669. end;
  1670. end;
  1671. end;
  1672. checkstack:=checkstack^.next;
  1673. end;
  1674. end;
  1675. destructor tcallcandidates.destroy;
  1676. var
  1677. hpnext,
  1678. hp : pcandidate;
  1679. begin
  1680. hp:=FProcs;
  1681. while assigned(hp) do
  1682. begin
  1683. hpnext:=hp^.next;
  1684. dispose(hp);
  1685. hp:=hpnext;
  1686. end;
  1687. end;
  1688. function tcallcandidates.proc_add(ps:tprocsym;pd:tprocdef):pcandidate;
  1689. var
  1690. defaultparacnt : integer;
  1691. begin
  1692. { generate new candidate entry }
  1693. new(result);
  1694. fillchar(result^,sizeof(tcandidate),0);
  1695. result^.data:=pd;
  1696. result^.next:=FProcs;
  1697. FProcs:=result;
  1698. inc(FProccnt);
  1699. { Find last parameter, skip all default parameters
  1700. that are not passed. Ignore this skipping for varargs }
  1701. result^.firstparaidx:=pd.paras.count-1;
  1702. if not(po_varargs in pd.procoptions) then
  1703. begin
  1704. { ignore hidden parameters }
  1705. while (result^.firstparaidx>=0) and (vo_is_hidden_para in tparavarsym(pd.paras[result^.firstparaidx]).varoptions) do
  1706. dec(result^.firstparaidx);
  1707. defaultparacnt:=pd.maxparacount-FParalength;
  1708. if defaultparacnt>0 then
  1709. begin
  1710. if defaultparacnt>result^.firstparaidx+1 then
  1711. internalerror(200401141);
  1712. dec(result^.firstparaidx,defaultparacnt);
  1713. end;
  1714. end;
  1715. { Give a small penalty for overloaded methods not in
  1716. defined the current class/unit }
  1717. if ps.owner<>pd.owner then
  1718. result^.ordinal_distance:=result^.ordinal_distance+1.0;
  1719. end;
  1720. procedure tcallcandidates.list(all:boolean);
  1721. var
  1722. hp : pcandidate;
  1723. begin
  1724. hp:=FProcs;
  1725. while assigned(hp) do
  1726. begin
  1727. if all or
  1728. (not hp^.invalid) then
  1729. MessagePos1(hp^.data.fileinfo,sym_h_param_list,hp^.data.fullprocname(false));
  1730. hp:=hp^.next;
  1731. end;
  1732. end;
  1733. {$ifdef EXTDEBUG}
  1734. procedure tcallcandidates.dump_info(lvl:longint);
  1735. function ParaTreeStr(p:tcallparanode):string;
  1736. begin
  1737. result:='';
  1738. while assigned(p) do
  1739. begin
  1740. if result<>'' then
  1741. result:=','+result;
  1742. result:=p.resultdef.typename+result;
  1743. p:=tcallparanode(p.right);
  1744. end;
  1745. end;
  1746. var
  1747. hp : pcandidate;
  1748. i : integer;
  1749. currpara : tparavarsym;
  1750. begin
  1751. if not CheckVerbosity(lvl) then
  1752. exit;
  1753. Comment(lvl+V_LineInfo,'Overloaded callnode: '+FProcSym.name+'('+ParaTreeStr(tcallparanode(FParaNode))+')');
  1754. hp:=FProcs;
  1755. while assigned(hp) do
  1756. begin
  1757. Comment(lvl,' '+hp^.data.fullprocname(false));
  1758. if (hp^.invalid) then
  1759. Comment(lvl,' invalid')
  1760. else
  1761. begin
  1762. Comment(lvl,' ex: '+tostr(hp^.exact_count)+
  1763. ' eq: '+tostr(hp^.equal_count)+
  1764. ' l1: '+tostr(hp^.cl1_count)+
  1765. ' l2: '+tostr(hp^.cl2_count)+
  1766. ' l3: '+tostr(hp^.cl3_count)+
  1767. ' l4: '+tostr(hp^.cl4_count)+
  1768. ' oper: '+tostr(hp^.coper_count)+
  1769. ' ord: '+realtostr(hp^.ordinal_distance));
  1770. { Print parameters in left-right order }
  1771. for i:=0 to hp^.data.paras.count-1 do
  1772. begin
  1773. currpara:=tparavarsym(hp^.data.paras[i]);
  1774. if not(vo_is_hidden_para in currpara.varoptions) then
  1775. Comment(lvl,' - '+currpara.vardef.typename+' : '+EqualTypeName[currpara.eqval]);
  1776. end;
  1777. end;
  1778. hp:=hp^.next;
  1779. end;
  1780. end;
  1781. {$endif EXTDEBUG}
  1782. procedure tcallcandidates.get_information;
  1783. var
  1784. hp : pcandidate;
  1785. currpara : tparavarsym;
  1786. paraidx : integer;
  1787. currparanr : byte;
  1788. rfh,rth : double;
  1789. objdef : tobjectdef;
  1790. def_from,
  1791. def_to : tdef;
  1792. currpt,
  1793. pt : tcallparanode;
  1794. eq : tequaltype;
  1795. convtype : tconverttype;
  1796. pdtemp,
  1797. pdoper : tprocdef;
  1798. releasecurrpt : boolean;
  1799. cdoptions : tcompare_defs_options;
  1800. {$ifopt r+}{$define ena_rq}{$q-}{$r-}{$endif}
  1801. const
  1802. inf=1.0/0.0;
  1803. {$ifdef ena_rq}{$q+}{$r+}{$endif}
  1804. begin
  1805. cdoptions:=[cdo_check_operator];
  1806. if FAllowVariant then
  1807. include(cdoptions,cdo_allow_variant);
  1808. { process all procs }
  1809. hp:=FProcs;
  1810. while assigned(hp) do
  1811. begin
  1812. { We compare parameters in reverse order (right to left),
  1813. the firstpara is already pointing to the last parameter
  1814. were we need to start comparing }
  1815. currparanr:=FParalength;
  1816. paraidx:=hp^.firstparaidx;
  1817. while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(hp^.data.paras[paraidx]).varoptions) do
  1818. dec(paraidx);
  1819. pt:=tcallparanode(FParaNode);
  1820. while assigned(pt) and (paraidx>=0) do
  1821. begin
  1822. currpara:=tparavarsym(hp^.data.paras[paraidx]);
  1823. { currpt can be changed from loadn to calln when a procvar
  1824. is passed. This is to prevent that the change is permanent }
  1825. currpt:=pt;
  1826. releasecurrpt:=false;
  1827. { retrieve current parameter definitions to compares }
  1828. eq:=te_incompatible;
  1829. def_from:=currpt.resultdef;
  1830. def_to:=currpara.vardef;
  1831. if not(assigned(def_from)) then
  1832. internalerror(200212091);
  1833. if not(
  1834. assigned(def_to) or
  1835. ((po_varargs in hp^.data.procoptions) and
  1836. (currparanr>hp^.data.minparacount))
  1837. ) then
  1838. internalerror(200212092);
  1839. { Convert tp procvars when not expecting a procvar }
  1840. if (def_to.typ<>procvardef) and
  1841. (currpt.left.resultdef.typ=procvardef) and
  1842. { Only convert to call when there is no overload or the return type
  1843. is equal to the expected type. }
  1844. (
  1845. (count=1) or
  1846. equal_defs(tprocvardef(currpt.left.resultdef).returndef,def_to)
  1847. ) then
  1848. begin
  1849. releasecurrpt:=true;
  1850. currpt:=tcallparanode(pt.getcopy);
  1851. if maybe_call_procvar(currpt.left,true) then
  1852. begin
  1853. currpt.resultdef:=currpt.left.resultdef;
  1854. def_from:=currpt.left.resultdef;
  1855. end;
  1856. end;
  1857. { If we expect a procvar and the left is loadnode that
  1858. returns a procdef we need to find the correct overloaded
  1859. procdef that matches the expected procvar. The loadnode
  1860. temporary returned the first procdef (PFV) }
  1861. if (def_to.typ=procvardef) and
  1862. (currpt.left.nodetype=loadn) and
  1863. (currpt.left.resultdef.typ=procdef) then
  1864. begin
  1865. pdtemp:=tprocsym(Tloadnode(currpt.left).symtableentry).Find_procdef_byprocvardef(Tprocvardef(def_to));
  1866. if assigned(pdtemp) then
  1867. begin
  1868. tloadnode(currpt.left).setprocdef(pdtemp);
  1869. currpt.resultdef:=currpt.left.resultdef;
  1870. def_from:=currpt.left.resultdef;
  1871. end;
  1872. end;
  1873. { varargs are always equal, but not exact }
  1874. if (po_varargs in hp^.data.procoptions) and
  1875. (currparanr>hp^.data.minparacount) and
  1876. not is_array_of_const(def_from) and
  1877. not is_array_constructor(def_from) then
  1878. eq:=te_equal
  1879. else
  1880. { same definition -> exact }
  1881. if (def_from=def_to) then
  1882. eq:=te_exact
  1883. else
  1884. { for value and const parameters check if a integer is constant or
  1885. included in other integer -> equal and calc ordinal_distance }
  1886. if not(currpara.varspez in [vs_var,vs_out]) and
  1887. is_integer(def_from) and
  1888. is_integer(def_to) and
  1889. is_in_limit(def_from,def_to) then
  1890. begin
  1891. eq:=te_equal;
  1892. hp^.ordinal_distance:=hp^.ordinal_distance+
  1893. abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
  1894. rth:=bestreal(torddef(def_to).high);
  1895. rfh:=bestreal(torddef(def_from).high);
  1896. hp^.ordinal_distance:=hp^.ordinal_distance+abs(rth-rfh);
  1897. { Give wrong sign a small penalty, this is need to get a diffrence
  1898. from word->[longword,longint] }
  1899. if is_signed(def_from)<>is_signed(def_to) then
  1900. {$ifopt r+}{$define ena_rq}{$q-}{$r-}{$endif}
  1901. hp^.ordinal_distance:=nextafter(hp^.ordinal_distance,inf);
  1902. {$ifdef ena_rq}{$r+}{$q+}{$endif}
  1903. end
  1904. else
  1905. { for value and const parameters check precision of real, give
  1906. penalty for loosing of precision. var and out parameters must match exactly }
  1907. if not(currpara.varspez in [vs_var,vs_out]) and
  1908. is_real(def_from) and
  1909. is_real(def_to) then
  1910. begin
  1911. eq:=te_equal;
  1912. if is_extended(def_to) then
  1913. rth:=4
  1914. else
  1915. if is_double (def_to) then
  1916. rth:=2
  1917. else
  1918. rth:=1;
  1919. if is_extended(def_from) then
  1920. rfh:=4
  1921. else
  1922. if is_double (def_from) then
  1923. rfh:=2
  1924. else
  1925. rfh:=1;
  1926. { penalty for shrinking of precision }
  1927. if rth<rfh then
  1928. rfh:=(rfh-rth)*16
  1929. else
  1930. rfh:=rth-rfh;
  1931. hp^.ordinal_distance:=hp^.ordinal_distance+rfh;
  1932. end
  1933. else
  1934. { related object parameters also need to determine the distance between the current
  1935. object and the object we are comparing with. var and out parameters must match exactly }
  1936. if not(currpara.varspez in [vs_var,vs_out]) and
  1937. (def_from.typ=objectdef) and
  1938. (def_to.typ=objectdef) and
  1939. (tobjectdef(def_from).objecttype=tobjectdef(def_to).objecttype) and
  1940. tobjectdef(def_from).is_related(tobjectdef(def_to)) then
  1941. begin
  1942. eq:=te_convert_l1;
  1943. objdef:=tobjectdef(def_from);
  1944. while assigned(objdef) do
  1945. begin
  1946. if objdef=def_to then
  1947. break;
  1948. hp^.ordinal_distance:=hp^.ordinal_distance+1;
  1949. objdef:=objdef.childof;
  1950. end;
  1951. end
  1952. else
  1953. { generic type comparision }
  1954. begin
  1955. eq:=compare_defs_ext(def_from,def_to,currpt.left.nodetype,convtype,pdoper,cdoptions);
  1956. { when the types are not equal we need to check
  1957. some special case for parameter passing }
  1958. if (eq<te_equal) then
  1959. begin
  1960. if currpara.varspez in [vs_var,vs_out] then
  1961. begin
  1962. { para requires an equal type so the previous found
  1963. match was not good enough, reset to incompatible }
  1964. eq:=te_incompatible;
  1965. { var_para_allowed will return te_equal and te_convert_l1 to
  1966. make a difference for best matching }
  1967. var_para_allowed(eq,currpt.resultdef,currpara.vardef)
  1968. end
  1969. else
  1970. para_allowed(eq,currpt,def_to);
  1971. end;
  1972. end;
  1973. { when a procvar was changed to a call an exact much is
  1974. downgraded to equal. This way an overload call with the
  1975. procvar is choosen. See tb0471 (PFV) }
  1976. if (pt<>currpt) and (eq=te_exact) then
  1977. eq:=te_equal;
  1978. { increase correct counter }
  1979. case eq of
  1980. te_exact :
  1981. inc(hp^.exact_count);
  1982. te_equal :
  1983. inc(hp^.equal_count);
  1984. te_convert_l1 :
  1985. inc(hp^.cl1_count);
  1986. te_convert_l2 :
  1987. inc(hp^.cl2_count);
  1988. te_convert_l3 :
  1989. inc(hp^.cl3_count);
  1990. te_convert_l4 :
  1991. inc(hp^.cl4_count);
  1992. te_convert_operator :
  1993. inc(hp^.coper_count);
  1994. te_incompatible :
  1995. hp^.invalid:=true;
  1996. else
  1997. internalerror(200212072);
  1998. end;
  1999. { stop checking when an incompatible parameter is found }
  2000. if hp^.invalid then
  2001. begin
  2002. { store the current parameter info for
  2003. a nice error message when no procedure is found }
  2004. hp^.wrongparaidx:=paraidx;
  2005. hp^.wrongparanr:=currparanr;
  2006. break;
  2007. end;
  2008. {$ifdef EXTDEBUG}
  2009. { store equal in node tree for dump }
  2010. currpara.eqval:=eq;
  2011. {$endif EXTDEBUG}
  2012. { maybe release temp currpt }
  2013. if releasecurrpt then
  2014. currpt.free;
  2015. { next parameter in the call tree }
  2016. pt:=tcallparanode(pt.right);
  2017. { next parameter for definition, only goto next para
  2018. if we're out of the varargs }
  2019. if not(po_varargs in hp^.data.procoptions) or
  2020. (currparanr<=hp^.data.maxparacount) then
  2021. begin
  2022. { Ignore vs_hidden parameters }
  2023. repeat
  2024. dec(paraidx);
  2025. until (paraidx<0) or not(vo_is_hidden_para in tparavarsym(hp^.data.paras[paraidx]).varoptions);
  2026. end;
  2027. dec(currparanr);
  2028. end;
  2029. if not(hp^.invalid) and
  2030. (assigned(pt) or (paraidx>=0) or (currparanr<>0)) then
  2031. internalerror(200212141);
  2032. { next candidate }
  2033. hp:=hp^.next;
  2034. end;
  2035. end;
  2036. function get_variantequaltype(def: tdef): tvariantequaltype;
  2037. const
  2038. variantorddef_cl: array[tordtype] of tvariantequaltype =
  2039. (tve_incompatible,tve_byte,tve_word,tve_cardinal,tve_chari64,
  2040. tve_shortint,tve_smallint,tve_longint,tve_chari64,
  2041. tve_boolformal,tve_boolformal,tve_boolformal,tve_boolformal,
  2042. tve_chari64,tve_chari64,tve_dblcurrency);
  2043. {$warning fixme for 128 bit floats }
  2044. variantfloatdef_cl: array[tfloattype] of tvariantequaltype =
  2045. (tve_single,tve_dblcurrency,tve_extended,
  2046. tve_dblcurrency,tve_dblcurrency,tve_extended);
  2047. variantstringdef_cl: array[tstringtype] of tvariantequaltype =
  2048. (tve_sstring,tve_astring,tve_astring,tve_wstring);
  2049. begin
  2050. result:=tve_incompatible;
  2051. case def.typ of
  2052. orddef:
  2053. begin
  2054. result:=variantorddef_cl[torddef(def).ordtype];
  2055. end;
  2056. floatdef:
  2057. begin
  2058. result:=variantfloatdef_cl[tfloatdef(def).floattype];
  2059. end;
  2060. stringdef:
  2061. begin
  2062. result:=variantstringdef_cl[tstringdef(def).stringtype];
  2063. end;
  2064. formaldef:
  2065. begin
  2066. result:=tve_boolformal;
  2067. end;
  2068. else
  2069. internalerror(2006122804);
  2070. end
  2071. end;
  2072. function is_better_candidate(currpd,bestpd:pcandidate):integer;
  2073. var
  2074. res : integer;
  2075. begin
  2076. {
  2077. Return values:
  2078. > 0 when currpd is better than bestpd
  2079. < 0 when bestpd is better than currpd
  2080. = 0 when both are equal
  2081. To choose the best candidate we use the following order:
  2082. - Incompatible flag
  2083. - (Smaller) Number of convert operator parameters.
  2084. - (Smaller) Number of convertlevel 2 parameters.
  2085. - (Smaller) Number of convertlevel 1 parameters.
  2086. - (Bigger) Number of exact parameters.
  2087. - (Smaller) Number of equal parameters.
  2088. - (Smaller) Total of ordinal distance. For example, the distance of a word
  2089. to a byte is 65535-255=65280.
  2090. }
  2091. if bestpd^.invalid then
  2092. begin
  2093. if currpd^.invalid then
  2094. res:=0
  2095. else
  2096. res:=1;
  2097. end
  2098. else
  2099. if currpd^.invalid then
  2100. res:=-1
  2101. else
  2102. begin
  2103. { less operator parameters? }
  2104. res:=(bestpd^.coper_count-currpd^.coper_count);
  2105. if (res=0) then
  2106. begin
  2107. { less cl4 parameters? }
  2108. res:=(bestpd^.cl4_count-currpd^.cl4_count);
  2109. if (res=0) then
  2110. begin
  2111. { less cl3 parameters? }
  2112. res:=(bestpd^.cl3_count-currpd^.cl3_count);
  2113. if (res=0) then
  2114. begin
  2115. { less cl2 parameters? }
  2116. res:=(bestpd^.cl2_count-currpd^.cl2_count);
  2117. if (res=0) then
  2118. begin
  2119. { less cl1 parameters? }
  2120. res:=(bestpd^.cl1_count-currpd^.cl1_count);
  2121. if (res=0) then
  2122. begin
  2123. { more exact parameters? }
  2124. res:=(currpd^.exact_count-bestpd^.exact_count);
  2125. if (res=0) then
  2126. begin
  2127. { less equal parameters? }
  2128. res:=(bestpd^.equal_count-currpd^.equal_count);
  2129. if (res=0) then
  2130. begin
  2131. { smaller ordinal distance? }
  2132. if (currpd^.ordinal_distance<bestpd^.ordinal_distance) then
  2133. res:=1
  2134. else
  2135. if (currpd^.ordinal_distance>bestpd^.ordinal_distance) then
  2136. res:=-1
  2137. else
  2138. res:=0;
  2139. end;
  2140. end;
  2141. end;
  2142. end;
  2143. end;
  2144. end;
  2145. end;
  2146. end;
  2147. is_better_candidate:=res;
  2148. end;
  2149. { Delphi precedence rules extracted from test programs. Only valid if passing
  2150. a variant parameter to overloaded procedures expecting exactly one parameter.
  2151. single > (char, currency, int64, shortstring, ansistring, widestring, extended, double)
  2152. double/currency > (char, int64, shortstring, ansistring, widestring, extended)
  2153. extended > (char, int64, shortstring, ansistring, widestring)
  2154. longint/cardinal > (int64, shortstring, ansistring, widestring, extended, double, single, char, currency)
  2155. smallint > (longint, int64, shortstring, ansistring, widestring, extended, double single, char, currency);
  2156. word > (longint, cardinal, int64, shortstring, ansistring, widestring, extended, double single, char, currency);
  2157. shortint > (longint, smallint, int64, shortstring, ansistring, widestring, extended, double, single, char, currency)
  2158. byte > (longint, cardinal, word, smallint, int64, shortstring, ansistring, widestring, extended, double, single, char, currency);
  2159. boolean/formal > (char, int64, shortstring, ansistring, widestring)
  2160. shortstring > (char, int64, ansistring, widestring)
  2161. ansistring > (char, int64, widestring)
  2162. widestring > (char, int64)
  2163. Relations not mentioned mean that they conflict: no decision possible }
  2164. function is_better_candidate_single_variant(currpd,bestpd:pcandidate):integer;
  2165. function calculate_relation(const currvcl, bestvcl, testvcl:
  2166. tvariantequaltype; const conflictvcls: tvariantequaltypes):integer;
  2167. begin
  2168. { if (bestvcl=conflictvcl) or
  2169. (currvcl=conflictvcl) then
  2170. result:=0
  2171. else if (bestvcl=testvcl) then
  2172. result:=-1
  2173. else result:=1 }
  2174. result:=1-2*ord(bestvcl=testvcl)+
  2175. ord(currvcl in conflictvcls)-ord(bestvcl in conflictvcls);
  2176. end;
  2177. var
  2178. paraidx : integer;
  2179. currpara, bestpara: tparavarsym;
  2180. currvcl, bestvcl: tvariantequaltype;
  2181. begin
  2182. {
  2183. Return values:
  2184. > 0 when currpd is better than bestpd
  2185. < 0 when bestpd is better than currpd
  2186. = 0 when both are equal
  2187. }
  2188. if (currpd^.firstparaidx<>bestpd^.firstparaidx) then
  2189. internalerror(2006122801);
  2190. paraidx:=currpd^.firstparaidx;
  2191. while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(currpd^.data.paras[paraidx]).varoptions) do
  2192. if (vo_is_hidden_para in tparavarsym(bestpd^.data.paras[paraidx]).varoptions) then
  2193. dec(paraidx)
  2194. else
  2195. internalerror(2006122802);
  2196. if (vo_is_hidden_para in tparavarsym(currpd^.data.paras[paraidx]).varoptions) then
  2197. internalerror(2006122803);
  2198. currpara:=tparavarsym(currpd^.data.paras[paraidx]);
  2199. bestpara:=tparavarsym(bestpd^.data.paras[paraidx]);
  2200. { if one of the parameters is a regular variant, fall back to the }
  2201. { default algorithm }
  2202. if (currpara.vardef.typ = variantdef) or
  2203. (bestpara.vardef.typ = variantdef) then
  2204. begin
  2205. result:=is_better_candidate(currpd,bestpd);
  2206. exit;
  2207. end;
  2208. currvcl:=get_variantequaltype(currpara.vardef);
  2209. bestvcl:=get_variantequaltype(bestpara.vardef);
  2210. { sanity check }
  2211. result:=-5;
  2212. { if both are the same, there is a conflict }
  2213. if (currvcl=bestvcl) then
  2214. result:=0
  2215. { boolean and formal are better than chari64str, but conflict with }
  2216. { everything else }
  2217. else if (currvcl=tve_boolformal) or
  2218. (bestvcl=tve_boolformal) then
  2219. if (currvcl=tve_boolformal) then
  2220. result:=ord(bestvcl in [tve_chari64,tve_sstring,tve_astring,tve_wstring])
  2221. else
  2222. result:=-ord(currvcl in [tve_chari64,tve_sstring,tve_astring,tve_wstring])
  2223. { byte is better than everything else (we assume both aren't byte, }
  2224. { since there's only one parameter and that one can't be the same) }
  2225. else if (currvcl=tve_byte) or
  2226. (bestvcl=tve_byte) then
  2227. result:=calculate_relation(currvcl,bestvcl,tve_byte,[tve_shortint])
  2228. { shortint conflicts with word and cardinal, but is better than }
  2229. { everything else but byte (which has already been handled) }
  2230. else if (currvcl=tve_shortint) or
  2231. (bestvcl=tve_shortint) then
  2232. result:=calculate_relation(currvcl,bestvcl,tve_shortint,[tve_word, tve_cardinal])
  2233. { word conflicts with smallint, but is better than everything else }
  2234. { but shortint and byte (which has already been handled) }
  2235. else if (currvcl=tve_word) or
  2236. (bestvcl=tve_word) then
  2237. result:=calculate_relation(currvcl,bestvcl,tve_word,[tve_smallint])
  2238. { smallint conflicts with cardinal, but is better than everything }
  2239. { which has not yet been tested }
  2240. else if (currvcl=tve_smallint) or
  2241. (bestvcl=tve_smallint) then
  2242. result:=calculate_relation(currvcl,bestvcl,tve_smallint,[tve_cardinal])
  2243. { cardinal conflicts with each longint and is better than everything }
  2244. { which has not yet been tested }
  2245. else if (currvcl = tve_cardinal) or
  2246. (bestvcl=tve_cardinal) then
  2247. result:=calculate_relation(currvcl,bestvcl,tve_cardinal,[tve_longint])
  2248. { longint is better than everything which has not yet been tested }
  2249. else if (currvcl=tve_longint) or
  2250. (bestvcl=tve_longint) then
  2251. { if bestvcl=tve_longint then
  2252. result:=-1
  2253. else
  2254. result:=1 }
  2255. result:=1-2*ord(bestvcl=tve_longint)
  2256. { single is better than everything left }
  2257. else if (currvcl=tve_single) or
  2258. (bestvcl=tve_single) then
  2259. result:=1-2*ord(bestvcl=tve_single)
  2260. { double/comp/currency are better than everything left, and conflict }
  2261. { with each other (but that's already tested) }
  2262. else if (currvcl=tve_dblcurrency) or
  2263. (bestvcl=tve_dblcurrency) then
  2264. result:=1-2*ord(bestvcl=tve_dblcurrency)
  2265. { extended is better than everything left }
  2266. else if (currvcl=tve_extended) or
  2267. (bestvcl=tve_extended) then
  2268. result:=1-2*ord(bestvcl=tve_extended)
  2269. { shortstring is better than everything left }
  2270. else if (currvcl=tve_sstring) or
  2271. (bestvcl=tve_sstring) then
  2272. result:=1-2*ord(bestvcl=tve_sstring)
  2273. { ansistring is better than everything left }
  2274. else if (currvcl=tve_astring) or
  2275. (bestvcl=tve_astring) then
  2276. result:=1-2*ord(bestvcl=tve_astring)
  2277. { widestring is better than everything left }
  2278. else if (currvcl=tve_wstring) or
  2279. (bestvcl=tve_wstring) then
  2280. result:=1-2*ord(bestvcl=tve_wstring);
  2281. { all possibilities should have been checked now }
  2282. if (result=-5) then
  2283. internalerror(2006122805);
  2284. end;
  2285. function tcallcandidates.choose_best(var bestpd:tabstractprocdef; singlevariant: boolean):integer;
  2286. var
  2287. besthpstart,
  2288. hp : pcandidate;
  2289. cntpd,
  2290. res : integer;
  2291. begin
  2292. {
  2293. Returns the number of candidates left and the
  2294. first candidate is returned in pdbest
  2295. }
  2296. { Setup the first procdef as best, only count it as a result
  2297. when it is valid }
  2298. bestpd:=FProcs^.data;
  2299. if FProcs^.invalid then
  2300. cntpd:=0
  2301. else
  2302. cntpd:=1;
  2303. if assigned(FProcs^.next) then
  2304. begin
  2305. besthpstart:=FProcs;
  2306. hp:=FProcs^.next;
  2307. while assigned(hp) do
  2308. begin
  2309. if not singlevariant then
  2310. res:=is_better_candidate(hp,besthpstart)
  2311. else
  2312. res:=is_better_candidate_single_variant(hp,besthpstart);
  2313. if (res>0) then
  2314. begin
  2315. { hp is better, flag all procs to be incompatible }
  2316. while (besthpstart<>hp) do
  2317. begin
  2318. besthpstart^.invalid:=true;
  2319. besthpstart:=besthpstart^.next;
  2320. end;
  2321. { besthpstart is already set to hp }
  2322. bestpd:=besthpstart^.data;
  2323. cntpd:=1;
  2324. end
  2325. else
  2326. if (res<0) then
  2327. begin
  2328. { besthpstart is better, flag current hp to be incompatible }
  2329. hp^.invalid:=true;
  2330. end
  2331. else
  2332. begin
  2333. { res=0, both are valid }
  2334. if not hp^.invalid then
  2335. inc(cntpd);
  2336. end;
  2337. hp:=hp^.next;
  2338. end;
  2339. end;
  2340. result:=cntpd;
  2341. end;
  2342. procedure tcallcandidates.find_wrong_para;
  2343. var
  2344. currparanr : smallint;
  2345. hp : pcandidate;
  2346. pt : tcallparanode;
  2347. wrongpara : tparavarsym;
  2348. begin
  2349. { Only process the first overloaded procdef }
  2350. hp:=FProcs;
  2351. { Find callparanode corresponding to the argument }
  2352. pt:=tcallparanode(FParanode);
  2353. currparanr:=FParalength;
  2354. while assigned(pt) and
  2355. (currparanr>hp^.wrongparanr) do
  2356. begin
  2357. pt:=tcallparanode(pt.right);
  2358. dec(currparanr);
  2359. end;
  2360. if (currparanr<>hp^.wrongparanr) or
  2361. not assigned(pt) then
  2362. internalerror(200212094);
  2363. { Show error message, when it was a var or out parameter
  2364. guess that it is a missing typeconv }
  2365. wrongpara:=tparavarsym(hp^.data.paras[hp^.wrongparaidx]);
  2366. if wrongpara.varspez in [vs_var,vs_out] then
  2367. begin
  2368. { Maybe passing the correct type but passing a const to var parameter }
  2369. if (compare_defs(pt.resultdef,wrongpara.vardef,pt.nodetype)<>te_incompatible) and
  2370. not valid_for_var(pt.left,true) then
  2371. CGMessagePos(pt.left.fileinfo,type_e_variable_id_expected)
  2372. else
  2373. CGMessagePos3(pt.left.fileinfo,parser_e_call_by_ref_without_typeconv,tostr(hp^.wrongparanr),
  2374. FullTypeName(pt.left.resultdef,wrongpara.vardef),
  2375. FullTypeName(wrongpara.vardef,pt.left.resultdef))
  2376. end
  2377. else
  2378. CGMessagePos3(pt.left.fileinfo,type_e_wrong_parameter_type,tostr(hp^.wrongparanr),
  2379. FullTypeName(pt.left.resultdef,wrongpara.vardef),
  2380. FullTypeName(wrongpara.vardef,pt.left.resultdef));
  2381. end;
  2382. procedure check_hints(const srsym: tsym; const symoptions: tsymoptions);
  2383. begin
  2384. if not assigned(srsym) then
  2385. internalerror(200602051);
  2386. if sp_hint_deprecated in symoptions then
  2387. Message1(sym_w_deprecated_symbol,srsym.realname);
  2388. if sp_hint_platform in symoptions then
  2389. Message1(sym_w_non_portable_symbol,srsym.realname);
  2390. if sp_hint_unimplemented in symoptions then
  2391. Message1(sym_w_non_implemented_symbol,srsym.realname);
  2392. end;
  2393. procedure check_ranges(const location: tfileposinfo; source: tnode; destdef: tdef);
  2394. begin
  2395. if not(cs_check_ordinal_size in current_settings.localswitches) then
  2396. exit;
  2397. { check if the assignment may cause a range check error }
  2398. { if its not explicit, and only if the values are }
  2399. { ordinals, enumdef and floatdef }
  2400. if assigned(destdef) and
  2401. (destdef.typ in [enumdef,orddef,floatdef]) and
  2402. not is_boolean(destdef) and
  2403. assigned(source.resultdef) and
  2404. (source.resultdef.typ in [enumdef,orddef,floatdef]) and
  2405. not is_boolean(source.resultdef) and
  2406. not is_constrealnode(source) then
  2407. begin
  2408. if (destdef.size < source.resultdef.size) then
  2409. begin
  2410. if (cs_check_range in current_settings.localswitches) then
  2411. MessagePos(location,type_w_smaller_possible_range_check)
  2412. else
  2413. MessagePos(location,type_h_smaller_possible_range_check);
  2414. end;
  2415. end;
  2416. end;
  2417. end.