htypechk.pas 87 KB

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