htypechk.pas 87 KB

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