htypechk.pas 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit exports some help routines for the type checking
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit htypechk;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. tokens,cpuinfo,
  23. node,
  24. symconst,symtype,symdef,symsym,symbase;
  25. type
  26. Ttok2nodeRec=record
  27. tok : ttoken;
  28. nod : tnodetype;
  29. op_overloading_supported : boolean;
  30. end;
  31. pcandidate = ^tcandidate;
  32. tcandidate = record
  33. next : pcandidate;
  34. data : tprocdef;
  35. wrongpara,
  36. firstpara : tparaitem;
  37. exact_count,
  38. equal_count,
  39. cl1_count,
  40. cl2_count,
  41. cl3_count,
  42. coper_count : integer; { should be signed }
  43. ordinal_distance : bestreal;
  44. invalid : boolean;
  45. wrongparanr : byte;
  46. end;
  47. tcallcandidates = class
  48. private
  49. FProcSym : tprocsym;
  50. FProcs : pcandidate;
  51. FProcVisibleCnt,
  52. FProcCnt : integer;
  53. FParaNode : tnode;
  54. FParaLength : smallint;
  55. FAllowVariant : boolean;
  56. function proc_add(pd:tprocdef):pcandidate;
  57. public
  58. constructor create(sym:tprocsym;st:tsymtable;ppn:tnode;isprop:boolean);
  59. constructor create_operator(op:ttoken;ppn:tnode);
  60. destructor destroy;override;
  61. procedure list(all:boolean);
  62. {$ifdef EXTDEBUG}
  63. procedure dump_info(lvl:longint);
  64. {$endif EXTDEBUG}
  65. procedure get_information;
  66. function choose_best(var bestpd:tabstractprocdef):integer;
  67. procedure find_wrong_para;
  68. property Count:integer read FProcCnt;
  69. property VisibleCount:integer read FProcVisibleCnt;
  70. end;
  71. const
  72. tok2nodes=25;
  73. tok2node:array[1..tok2nodes] of ttok2noderec=(
  74. (tok:_PLUS ;nod:addn;op_overloading_supported:true), { binary overloading supported }
  75. (tok:_MINUS ;nod:subn;op_overloading_supported:true), { binary and unary overloading supported }
  76. (tok:_STAR ;nod:muln;op_overloading_supported:true), { binary overloading supported }
  77. (tok:_SLASH ;nod:slashn;op_overloading_supported:true), { binary overloading supported }
  78. (tok:_EQUAL ;nod:equaln;op_overloading_supported:true), { binary overloading supported }
  79. (tok:_GT ;nod:gtn;op_overloading_supported:true), { binary overloading supported }
  80. (tok:_LT ;nod:ltn;op_overloading_supported:true), { binary overloading supported }
  81. (tok:_GTE ;nod:gten;op_overloading_supported:true), { binary overloading supported }
  82. (tok:_LTE ;nod:lten;op_overloading_supported:true), { binary overloading supported }
  83. (tok:_SYMDIF ;nod:symdifn;op_overloading_supported:true), { binary overloading supported }
  84. (tok:_STARSTAR;nod:starstarn;op_overloading_supported:true), { binary overloading supported }
  85. (tok:_OP_AS ;nod:asn;op_overloading_supported:false), { binary overloading NOT supported }
  86. (tok:_OP_IN ;nod:inn;op_overloading_supported:false), { binary overloading NOT supported }
  87. (tok:_OP_IS ;nod:isn;op_overloading_supported:false), { binary overloading NOT supported }
  88. (tok:_OP_OR ;nod:orn;op_overloading_supported:true), { binary overloading supported }
  89. (tok:_OP_AND ;nod:andn;op_overloading_supported:true), { binary overloading supported }
  90. (tok:_OP_DIV ;nod:divn;op_overloading_supported:true), { binary overloading supported }
  91. (tok:_OP_NOT ;nod:notn;op_overloading_supported:true), { unary overloading supported }
  92. (tok:_OP_MOD ;nod:modn;op_overloading_supported:true), { binary overloading supported }
  93. (tok:_OP_SHL ;nod:shln;op_overloading_supported:true), { binary overloading supported }
  94. (tok:_OP_SHR ;nod:shrn;op_overloading_supported:true), { binary overloading supported }
  95. (tok:_OP_XOR ;nod:xorn;op_overloading_supported:true), { binary overloading supported }
  96. (tok:_ASSIGNMENT;nod:assignn;op_overloading_supported:true), { unary overloading supported }
  97. (tok:_CARET ;nod:caretn;op_overloading_supported:false), { binary overloading NOT supported }
  98. (tok:_UNEQUAL ;nod:unequaln;op_overloading_supported:false) { binary overloading NOT supported overload = instead }
  99. );
  100. const
  101. { firstcallparan without varspez we don't count the ref }
  102. {$ifdef extdebug}
  103. count_ref : boolean = true;
  104. {$endif def extdebug}
  105. allow_array_constructor : boolean = false;
  106. function node2opstr(nt:tnodetype):string;
  107. { check operator args and result type }
  108. function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
  109. function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
  110. function isunaryoverloaded(var t : tnode) : boolean;
  111. function isbinaryoverloaded(var t : tnode) : boolean;
  112. { Register Allocation }
  113. procedure make_not_regable(p : tnode);
  114. procedure calcregisters(p : tbinarynode;r32,fpu,mmx : word);
  115. { subroutine handling }
  116. function is_procsym_load(p:tnode):boolean;
  117. procedure test_local_to_procvar(from_def:tprocvardef;to_def:tdef);
  118. { sets varsym varstate field correctly }
  119. procedure set_varstate(p:tnode;newstate:tvarstate;must_be_valid:boolean);
  120. { sets the callunique flag, if the node is a vecn, }
  121. { takes care of type casts etc. }
  122. procedure set_unique(p : tnode);
  123. function valid_for_formal_var(p : tnode) : boolean;
  124. function valid_for_formal_const(p : tnode) : boolean;
  125. function valid_for_var(p:tnode):boolean;
  126. function valid_for_assignment(p:tnode):boolean;
  127. implementation
  128. uses
  129. globtype,systems,
  130. cutils,verbose,globals,
  131. symtable,
  132. defutil,defcmp,
  133. pass_1,nbas,ncnv,nld,nmem,ncal,nmat,nutils,
  134. cgbase,procinfo
  135. ;
  136. type
  137. TValidAssign=(Valid_Property,Valid_Void);
  138. TValidAssigns=set of TValidAssign;
  139. function node2opstr(nt:tnodetype):string;
  140. var
  141. i : integer;
  142. begin
  143. result:='<unknown>';
  144. for i:=1 to tok2nodes do
  145. if tok2node[i].nod=nt then
  146. begin
  147. result:=tokeninfo^[tok2node[i].tok].str;
  148. break;
  149. end;
  150. end;
  151. function isbinaryoperatoroverloadable(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype) : boolean;
  152. function internal_check(treetyp:tnodetype;ld:tdef;lt:tnodetype;rd:tdef;rt:tnodetype;var allowed:boolean):boolean;
  153. begin
  154. internal_check:=true;
  155. case ld.deftype of
  156. formaldef,
  157. recorddef,
  158. variantdef :
  159. begin
  160. allowed:=true;
  161. end;
  162. procvardef :
  163. begin
  164. if (rd.deftype in [pointerdef,procdef,procvardef]) then
  165. begin
  166. allowed:=false;
  167. exit;
  168. end;
  169. allowed:=true;
  170. end;
  171. pointerdef :
  172. begin
  173. if ((rd.deftype in [orddef,enumdef,pointerdef,classrefdef,procvardef]) or
  174. is_class_or_interface(rd)) then
  175. begin
  176. allowed:=false;
  177. exit;
  178. end;
  179. { don't allow pchar+string }
  180. if (is_pchar(ld) or is_pwidechar(ld)) and
  181. ((rd.deftype=stringdef) or
  182. is_pchar(rd) or
  183. is_pwidechar(rd) or
  184. is_chararray(rd) or
  185. is_widechararray(rd)) then
  186. begin
  187. allowed:=false;
  188. exit;
  189. end;
  190. allowed:=true;
  191. end;
  192. arraydef :
  193. begin
  194. { not mmx }
  195. if (cs_mmx in aktlocalswitches) and
  196. is_mmx_able_array(ld) then
  197. begin
  198. allowed:=false;
  199. exit;
  200. end;
  201. { not chararray+[(wide)char,(wide)string,(wide)chararray] }
  202. if (is_chararray(ld) or is_widechararray(ld)) and
  203. ((rd.deftype in [stringdef,orddef,enumdef]) or
  204. is_pchar(rd) or
  205. is_pwidechar(rd) or
  206. is_chararray(rd) or
  207. is_widechararray(rd) or
  208. (rt=niln)) then
  209. begin
  210. allowed:=false;
  211. exit;
  212. end;
  213. { dynamic array compare with niln }
  214. if ((is_dynamic_array(ld) and
  215. (rt=niln)) or
  216. (is_dynamic_array(ld) and is_dynamic_array(rd)))
  217. and
  218. (treetyp in [equaln,unequaln]) then
  219. begin
  220. allowed:=false;
  221. exit;
  222. end;
  223. allowed:=true;
  224. end;
  225. objectdef :
  226. begin
  227. { <> and = are defined for classes }
  228. if (treetyp in [equaln,unequaln]) and
  229. is_class_or_interface(ld) then
  230. begin
  231. allowed:=false;
  232. exit;
  233. end;
  234. allowed:=true;
  235. end;
  236. stringdef :
  237. begin
  238. if ((rd.deftype in [orddef,enumdef,stringdef]) or
  239. is_pchar(rd) or
  240. is_pwidechar(rd) or
  241. is_chararray(rd) or
  242. is_widechararray(rd)) then
  243. begin
  244. allowed:=false;
  245. exit;
  246. end;
  247. allowed:=true;
  248. end;
  249. else
  250. internal_check:=false;
  251. end;
  252. end;
  253. var
  254. allowed : boolean;
  255. begin
  256. { power ** is always possible }
  257. if (treetyp=starstarn) then
  258. begin
  259. isbinaryoperatoroverloadable:=true;
  260. exit;
  261. end;
  262. { order of arguments does not matter so we have to check also
  263. the reversed order }
  264. allowed:=false;
  265. if not internal_check(treetyp,ld,lt,rd,rt,allowed) then
  266. internal_check(treetyp,rd,rt,ld,lt,allowed);
  267. isbinaryoperatoroverloadable:=allowed;
  268. end;
  269. function isunaryoperatoroverloadable(treetyp : tnodetype;ld : tdef) : boolean;
  270. begin
  271. result:=false;
  272. case treetyp of
  273. subn,
  274. unaryminusn :
  275. begin
  276. if is_integer(ld) or
  277. (ld.deftype=floatdef) then
  278. exit;
  279. {$ifdef SUPPORT_MMX}
  280. if (cs_mmx in aktlocalswitches) and
  281. is_mmx_able_array(ld) then
  282. exit;
  283. {$endif SUPPORT_MMX}
  284. result:=true;
  285. end;
  286. notn :
  287. begin
  288. if is_integer(ld) or
  289. is_boolean(ld) 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. end;
  299. end;
  300. function isoperatoracceptable(pf : tprocdef; optoken : ttoken) : boolean;
  301. var
  302. ld,rd : tdef;
  303. i : longint;
  304. eq : tequaltype;
  305. conv : tconverttype;
  306. pd : tprocdef;
  307. begin
  308. result:=false;
  309. case pf.parast.symindex.count of
  310. 1 : begin
  311. ld:=tvarsym(pf.parast.symindex.first).vartype.def;
  312. { assignment is a special case }
  313. if optoken=_ASSIGNMENT then
  314. begin
  315. eq:=compare_defs_ext(ld,pf.rettype.def,nothingn,conv,pd,[cdo_explicit]);
  316. result:=(eq=te_incompatible);
  317. end
  318. else
  319. begin
  320. for i:=1 to tok2nodes do
  321. if tok2node[i].tok=optoken then
  322. begin
  323. result:=
  324. tok2node[i].op_overloading_supported and
  325. isunaryoperatoroverloadable(tok2node[i].nod,ld);
  326. break;
  327. end;
  328. end;
  329. end;
  330. 2 : begin
  331. for i:=1 to tok2nodes do
  332. if tok2node[i].tok=optoken then
  333. begin
  334. ld:=tvarsym(pf.parast.symindex.first).vartype.def;
  335. rd:=tvarsym(pf.parast.symindex.first.indexnext).vartype.def;
  336. result:=
  337. tok2node[i].op_overloading_supported and
  338. isbinaryoperatoroverloadable(tok2node[i].nod,ld,nothingn,rd,nothingn);
  339. break;
  340. end;
  341. end;
  342. end;
  343. end;
  344. function isunaryoverloaded(var t : tnode) : boolean;
  345. var
  346. ld : tdef;
  347. optoken : ttoken;
  348. operpd : tprocdef;
  349. ppn : tcallparanode;
  350. candidates : tcallcandidates;
  351. cand_cnt : integer;
  352. begin
  353. result:=false;
  354. operpd:=nil;
  355. { load easier access variables }
  356. ld:=tunarynode(t).left.resulttype.def;
  357. if not isunaryoperatoroverloadable(t.nodetype,ld) then
  358. exit;
  359. { operator overload is possible }
  360. result:=true;
  361. case t.nodetype of
  362. notn:
  363. optoken:=_OP_NOT;
  364. unaryminusn:
  365. optoken:=_MINUS;
  366. else
  367. begin
  368. CGMessage(parser_e_operator_not_overloaded);
  369. t:=cnothingnode.create;
  370. exit;
  371. end;
  372. end;
  373. { generate parameter nodes }
  374. ppn:=ccallparanode.create(tunarynode(t).left.getcopy,nil);
  375. ppn.get_paratype;
  376. candidates:=tcallcandidates.create_operator(optoken,ppn);
  377. { stop when there are no operators found }
  378. if candidates.count=0 then
  379. begin
  380. CGMessage(parser_e_operator_not_overloaded);
  381. candidates.free;
  382. ppn.free;
  383. t:=cnothingnode.create;
  384. exit;
  385. end;
  386. { Retrieve information about the candidates }
  387. candidates.get_information;
  388. {$ifdef EXTDEBUG}
  389. { Display info when multiple candidates are found }
  390. candidates.dump_info(V_Debug);
  391. {$endif EXTDEBUG}
  392. cand_cnt:=candidates.choose_best(operpd);
  393. { exit when no overloads are found }
  394. if cand_cnt=0 then
  395. begin
  396. CGMessage(parser_e_operator_not_overloaded);
  397. candidates.free;
  398. ppn.free;
  399. t:=cnothingnode.create;
  400. exit;
  401. end;
  402. { Multiple candidates left? }
  403. if cand_cnt>1 then
  404. begin
  405. CGMessage(cg_e_cant_choose_overload_function);
  406. {$ifdef EXTDEBUG}
  407. candidates.dump_info(V_Hint);
  408. {$else EXTDEBUG}
  409. candidates.list(false);
  410. {$endif EXTDEBUG}
  411. { we'll just use the first candidate to make the
  412. call }
  413. end;
  414. candidates.free;
  415. inc(operpd.procsym.refs);
  416. { the nil as symtable signs firstcalln that this is
  417. an overloaded operator }
  418. t:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil);
  419. { we already know the procdef to use, so it can
  420. skip the overload choosing in callnode.det_resulttype }
  421. tcallnode(t).procdefinition:=operpd;
  422. end;
  423. function isbinaryoverloaded(var t : tnode) : boolean;
  424. var
  425. rd,ld : tdef;
  426. optoken : ttoken;
  427. operpd : tprocdef;
  428. ht : tnode;
  429. ppn : tcallparanode;
  430. candidates : tcallcandidates;
  431. cand_cnt : integer;
  432. begin
  433. isbinaryoverloaded:=false;
  434. operpd:=nil;
  435. { load easier access variables }
  436. ld:=tbinarynode(t).left.resulttype.def;
  437. rd:=tbinarynode(t).right.resulttype.def;
  438. if not isbinaryoperatoroverloadable(t.nodetype,ld,tbinarynode(t).left.nodetype,rd,tbinarynode(t).right.nodetype) then
  439. exit;
  440. { operator overload is possible }
  441. result:=true;
  442. case t.nodetype of
  443. equaln,
  444. unequaln :
  445. optoken:=_EQUAL;
  446. addn:
  447. optoken:=_PLUS;
  448. subn:
  449. optoken:=_MINUS;
  450. muln:
  451. optoken:=_STAR;
  452. starstarn:
  453. optoken:=_STARSTAR;
  454. slashn:
  455. optoken:=_SLASH;
  456. ltn:
  457. optoken:=_LT;
  458. gtn:
  459. optoken:=_GT;
  460. lten:
  461. optoken:=_LTE;
  462. gten:
  463. optoken:=_GTE;
  464. symdifn :
  465. optoken:=_SYMDIF;
  466. modn :
  467. optoken:=_OP_MOD;
  468. orn :
  469. optoken:=_OP_OR;
  470. xorn :
  471. optoken:=_OP_XOR;
  472. andn :
  473. optoken:=_OP_AND;
  474. divn :
  475. optoken:=_OP_DIV;
  476. shln :
  477. optoken:=_OP_SHL;
  478. shrn :
  479. optoken:=_OP_SHR;
  480. else
  481. begin
  482. CGMessage(parser_e_operator_not_overloaded);
  483. t:=cnothingnode.create;
  484. exit;
  485. end;
  486. end;
  487. { generate parameter nodes }
  488. ppn:=ccallparanode.create(tbinarynode(t).right.getcopy,ccallparanode.create(tbinarynode(t).left.getcopy,nil));
  489. ppn.get_paratype;
  490. candidates:=tcallcandidates.create_operator(optoken,ppn);
  491. { for commutative operators we can swap arguments and try again }
  492. if (candidates.count=0) and
  493. not(optoken in [_OP_SHL,_OP_SHR,_OP_DIV,_OP_MOD,_STARSTAR,_SLASH,_MINUS]) then
  494. begin
  495. candidates.free;
  496. reverseparameters(ppn);
  497. { reverse compare operators }
  498. case optoken of
  499. _LT:
  500. optoken:=_GTE;
  501. _GT:
  502. optoken:=_LTE;
  503. _LTE:
  504. optoken:=_GT;
  505. _GTE:
  506. optoken:=_LT;
  507. end;
  508. candidates:=tcallcandidates.create_operator(optoken,ppn);
  509. end;
  510. { stop when there are no operators found }
  511. if candidates.count=0 then
  512. begin
  513. CGMessage(parser_e_operator_not_overloaded);
  514. candidates.free;
  515. ppn.free;
  516. t:=cnothingnode.create;
  517. exit;
  518. end;
  519. { Retrieve information about the candidates }
  520. candidates.get_information;
  521. {$ifdef EXTDEBUG}
  522. { Display info when multiple candidates are found }
  523. candidates.dump_info(V_Debug);
  524. {$endif EXTDEBUG}
  525. cand_cnt:=candidates.choose_best(operpd);
  526. { exit when no overloads are found }
  527. if cand_cnt=0 then
  528. begin
  529. CGMessage(parser_e_operator_not_overloaded);
  530. candidates.free;
  531. ppn.free;
  532. t:=cnothingnode.create;
  533. exit;
  534. end;
  535. { Multiple candidates left? }
  536. if cand_cnt>1 then
  537. begin
  538. CGMessage(cg_e_cant_choose_overload_function);
  539. {$ifdef EXTDEBUG}
  540. candidates.dump_info(V_Hint);
  541. {$else EXTDEBUG}
  542. candidates.list(false);
  543. {$endif EXTDEBUG}
  544. { we'll just use the first candidate to make the
  545. call }
  546. end;
  547. candidates.free;
  548. inc(operpd.procsym.refs);
  549. { the nil as symtable signs firstcalln that this is
  550. an overloaded operator }
  551. ht:=ccallnode.create(ppn,Tprocsym(operpd.procsym),nil,nil);
  552. { we already know the procdef to use, so it can
  553. skip the overload choosing in callnode.det_resulttype }
  554. tcallnode(ht).procdefinition:=operpd;
  555. if t.nodetype=unequaln then
  556. ht:=cnotnode.create(ht);
  557. t:=ht;
  558. end;
  559. {****************************************************************************
  560. Register Calculation
  561. ****************************************************************************}
  562. { marks an lvalue as "unregable" }
  563. procedure make_not_regable(p : tnode);
  564. begin
  565. case p.nodetype of
  566. typeconvn :
  567. make_not_regable(ttypeconvnode(p).left);
  568. loadn :
  569. if tloadnode(p).symtableentry.typ=varsym then
  570. tvarsym(tloadnode(p).symtableentry).varoptions:=tvarsym(tloadnode(p).symtableentry).varoptions-[vo_regable,vo_fpuregable];
  571. end;
  572. end;
  573. { calculates the needed registers for a binary operator }
  574. procedure calcregisters(p : tbinarynode;r32,fpu,mmx : word);
  575. begin
  576. p.left_right_max;
  577. { Only when the difference between the left and right registers < the
  578. wanted registers allocate the amount of registers }
  579. if assigned(p.left) then
  580. begin
  581. if assigned(p.right) then
  582. begin
  583. { the location must be already filled in because we need it to }
  584. { calculate the necessary number of registers (JM) }
  585. if p.expectloc = LOC_INVALID then
  586. internalerror(200110101);
  587. if (abs(p.left.registersint-p.right.registersint)<r32) or
  588. ((p.expectloc = LOC_FPUREGISTER) and
  589. (p.right.registersfpu <= p.left.registersfpu) and
  590. ((p.right.registersfpu <> 0) or (p.left.registersfpu <> 0)) and
  591. (p.left.registersint < p.right.registersint)) then
  592. inc(p.registersint,r32);
  593. if (abs(p.left.registersfpu-p.right.registersfpu)<fpu) then
  594. inc(p.registersfpu,fpu);
  595. {$ifdef SUPPORT_MMX}
  596. if (abs(p.left.registersmmx-p.right.registersmmx)<mmx) then
  597. inc(p.registersmmx,mmx);
  598. {$endif SUPPORT_MMX}
  599. { the following is a little bit guessing but I think }
  600. { it's the only way to solve same internalerrors: }
  601. { if the left and right node both uses registers }
  602. { and return a mem location, but the current node }
  603. { doesn't use an integer register we get probably }
  604. { trouble when restoring a node }
  605. if (p.left.registersint=p.right.registersint) and
  606. (p.registersint=p.left.registersint) and
  607. (p.registersint>0) and
  608. (p.left.expectloc in [LOC_REFERENCE,LOC_CREFERENCE]) and
  609. (p.right.expectloc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  610. inc(p.registersint);
  611. end
  612. else
  613. begin
  614. if (p.left.registersint<r32) then
  615. inc(p.registersint,r32);
  616. if (p.left.registersfpu<fpu) then
  617. inc(p.registersfpu,fpu);
  618. {$ifdef SUPPORT_MMX}
  619. if (p.left.registersmmx<mmx) then
  620. inc(p.registersmmx,mmx);
  621. {$endif SUPPORT_MMX}
  622. end;
  623. end;
  624. { error CGMessage, if more than 8 floating point }
  625. { registers are needed }
  626. { if p.registersfpu>maxfpuregs then
  627. CGMessage(cg_e_too_complex_expr); now pushed if needed PM }
  628. end;
  629. {****************************************************************************
  630. Subroutine Handling
  631. ****************************************************************************}
  632. function is_procsym_load(p:tnode):boolean;
  633. begin
  634. { ignore vecn,subscriptn }
  635. repeat
  636. case p.nodetype of
  637. vecn :
  638. p:=tvecnode(p).left;
  639. subscriptn :
  640. p:=tsubscriptnode(p).left;
  641. else
  642. break;
  643. end;
  644. until false;
  645. is_procsym_load:=((p.nodetype=loadn) and (tloadnode(p).symtableentry.typ=procsym)) or
  646. ((p.nodetype=addrn) and (taddrnode(p).left.nodetype=loadn)
  647. and (tloadnode(taddrnode(p).left).symtableentry.typ=procsym)) ;
  648. end;
  649. { local routines can't be assigned to procvars }
  650. procedure test_local_to_procvar(from_def:tprocvardef;to_def:tdef);
  651. begin
  652. if (from_def.parast.symtablelevel>normal_function_level) and
  653. (to_def.deftype=procvardef) then
  654. CGMessage(type_e_cannot_local_proc_to_procvar);
  655. end;
  656. procedure set_varstate(p:tnode;newstate:tvarstate;must_be_valid:boolean);
  657. var
  658. hsym : tvarsym;
  659. begin
  660. while assigned(p) do
  661. begin
  662. case p.nodetype of
  663. typeconvn :
  664. begin
  665. case ttypeconvnode(p).convtype of
  666. tc_cchar_2_pchar,
  667. tc_cstring_2_pchar,
  668. tc_array_2_pointer :
  669. must_be_valid:=false;
  670. tc_pchar_2_string,
  671. tc_pointer_2_array :
  672. must_be_valid:=true;
  673. end;
  674. p:=tunarynode(p).left;
  675. end;
  676. subscriptn :
  677. p:=tunarynode(p).left;
  678. vecn:
  679. begin
  680. set_varstate(tbinarynode(p).right,vs_used,true);
  681. if not(tunarynode(p).left.resulttype.def.deftype in [stringdef,arraydef]) then
  682. must_be_valid:=true;
  683. p:=tunarynode(p).left;
  684. end;
  685. { do not parse calln }
  686. calln :
  687. break;
  688. loadn :
  689. begin
  690. if (tloadnode(p).symtableentry.typ=varsym) then
  691. begin
  692. hsym:=tvarsym(tloadnode(p).symtableentry);
  693. if must_be_valid and (hsym.varstate=vs_declared) then
  694. begin
  695. { Give warning/note for uninitialized locals }
  696. if assigned(hsym.owner) and
  697. not(vo_is_external in hsym.varoptions) and
  698. (hsym.owner.symtabletype in [localsymtable,staticsymtable]) and
  699. (hsym.owner=current_procinfo.procdef.localst) then
  700. begin
  701. if (vo_is_funcret in hsym.varoptions) then
  702. CGMessage(sym_w_function_result_not_set)
  703. else
  704. if tloadnode(p).symtable.symtabletype=localsymtable then
  705. CGMessage1(sym_n_uninitialized_local_variable,hsym.realname)
  706. else
  707. CGMessage1(sym_n_uninitialized_variable,hsym.realname);
  708. end;
  709. end;
  710. { don't override vs_used with vs_assigned }
  711. if hsym.varstate<>vs_used then
  712. hsym.varstate:=newstate;
  713. end;
  714. break;
  715. end;
  716. callparan :
  717. internalerror(200310081);
  718. else
  719. break;
  720. end;{case }
  721. end;
  722. end;
  723. procedure set_unique(p : tnode);
  724. begin
  725. while assigned(p) do
  726. begin
  727. case p.nodetype of
  728. vecn:
  729. begin
  730. include(p.flags,nf_callunique);
  731. break;
  732. end;
  733. typeconvn,
  734. subscriptn,
  735. derefn:
  736. p:=tunarynode(p).left;
  737. else
  738. break;
  739. end;
  740. end;
  741. end;
  742. function valid_for_assign(p:tnode;opts:TValidAssigns):boolean;
  743. var
  744. hp : tnode;
  745. gotwith,
  746. gotsubscript,
  747. gotpointer,
  748. gotvec,
  749. gotclass,
  750. gotderef : boolean;
  751. fromdef,
  752. todef : tdef;
  753. begin
  754. valid_for_assign:=false;
  755. gotsubscript:=false;
  756. gotvec:=false;
  757. gotderef:=false;
  758. gotclass:=false;
  759. gotpointer:=false;
  760. gotwith:=false;
  761. hp:=p;
  762. if not(valid_void in opts) and
  763. is_void(hp.resulttype.def) then
  764. begin
  765. CGMessagePos(hp.fileinfo,type_e_argument_cant_be_assigned);
  766. exit;
  767. end;
  768. while assigned(hp) do
  769. begin
  770. { property allowed? calln has a property check itself }
  771. if (nf_isproperty in hp.flags) then
  772. begin
  773. if (valid_property in opts) then
  774. valid_for_assign:=true
  775. else
  776. begin
  777. { check return type }
  778. case hp.resulttype.def.deftype of
  779. pointerdef :
  780. gotpointer:=true;
  781. objectdef :
  782. gotclass:=is_class_or_interface(hp.resulttype.def);
  783. recorddef, { handle record like class it needs a subscription }
  784. classrefdef :
  785. gotclass:=true;
  786. end;
  787. { 1. if it returns a pointer and we've found a deref,
  788. 2. if it returns a class or record and a subscription or with is found }
  789. if (gotpointer and gotderef) or
  790. (gotclass and (gotsubscript or gotwith)) then
  791. valid_for_assign:=true
  792. else
  793. CGMessagePos(hp.fileinfo,type_e_argument_cant_be_assigned);
  794. end;
  795. exit;
  796. end;
  797. case hp.nodetype of
  798. temprefn :
  799. begin
  800. valid_for_assign := true;
  801. exit;
  802. end;
  803. derefn :
  804. begin
  805. gotderef:=true;
  806. hp:=tderefnode(hp).left;
  807. end;
  808. typeconvn :
  809. begin
  810. { typecast sizes must match, exceptions:
  811. - implicit typecast made by absolute
  812. - from formaldef
  813. - from void
  814. - from/to open array
  815. - typecast from pointer to array }
  816. fromdef:=ttypeconvnode(hp).left.resulttype.def;
  817. todef:=hp.resulttype.def;
  818. if not((nf_absolute in ttypeconvnode(hp).flags) or
  819. (fromdef.deftype=formaldef) or
  820. is_void(fromdef) or
  821. is_open_array(fromdef) or
  822. is_open_array(todef) or
  823. ((fromdef.deftype=pointerdef) and (todef.deftype=arraydef)) or
  824. ((fromdef.deftype = objectdef) and (todef.deftype = objectdef) and
  825. (tobjectdef(fromdef).is_related(tobjectdef(todef))))) and
  826. (fromdef.size<>todef.size) then
  827. begin
  828. { in TP it is allowed to typecast to smaller types }
  829. if not(m_tp7 in aktmodeswitches) or
  830. (todef.size>fromdef.size) then
  831. CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
  832. end;
  833. case hp.resulttype.def.deftype of
  834. pointerdef :
  835. gotpointer:=true;
  836. objectdef :
  837. gotclass:=is_class_or_interface(hp.resulttype.def);
  838. classrefdef :
  839. gotclass:=true;
  840. arraydef :
  841. begin
  842. { pointer -> array conversion is done then we need to see it
  843. as a deref, because a ^ is then not required anymore }
  844. if (ttypeconvnode(hp).left.resulttype.def.deftype=pointerdef) then
  845. gotderef:=true;
  846. end;
  847. end;
  848. hp:=ttypeconvnode(hp).left;
  849. end;
  850. vecn :
  851. begin
  852. gotvec:=true;
  853. hp:=tunarynode(hp).left;
  854. end;
  855. asn :
  856. begin
  857. { asn can't be assigned directly, it returns the value in a register instead
  858. of reference. }
  859. if not(gotsubscript or gotderef or gotvec) then
  860. begin
  861. CGMessagePos(hp.fileinfo,type_e_argument_cant_be_assigned);
  862. exit;
  863. end;
  864. hp:=tunarynode(hp).left;
  865. end;
  866. subscriptn :
  867. begin
  868. gotsubscript:=true;
  869. { a class/interface access is an implicit }
  870. { dereferencing }
  871. hp:=tsubscriptnode(hp).left;
  872. if is_class_or_interface(hp.resulttype.def) then
  873. gotderef:=true;
  874. end;
  875. subn,
  876. addn :
  877. begin
  878. { Allow add/sub operators on a pointer, or an integer
  879. and a pointer typecast and deref has been found }
  880. if ((hp.resulttype.def.deftype=pointerdef) or
  881. (is_integer(hp.resulttype.def) and gotpointer)) and
  882. gotderef then
  883. valid_for_assign:=true
  884. else
  885. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  886. exit;
  887. end;
  888. addrn :
  889. begin
  890. if gotderef or
  891. (nf_procvarload in hp.flags) then
  892. valid_for_assign:=true
  893. else
  894. CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
  895. exit;
  896. end;
  897. calln :
  898. begin
  899. { check return type }
  900. case hp.resulttype.def.deftype of
  901. arraydef :
  902. begin
  903. { dynamic arrays are allowed when there is also a
  904. vec node }
  905. if is_dynamic_array(hp.resulttype.def) and
  906. gotvec then
  907. begin
  908. gotderef:=true;
  909. gotpointer:=true;
  910. end;
  911. end;
  912. pointerdef :
  913. gotpointer:=true;
  914. objectdef :
  915. gotclass:=is_class_or_interface(hp.resulttype.def);
  916. recorddef, { handle record like class it needs a subscription }
  917. classrefdef :
  918. gotclass:=true;
  919. end;
  920. { 1. if it returns a pointer and we've found a deref,
  921. 2. if it returns a class or record and a subscription or with is found }
  922. if (gotpointer and gotderef) or
  923. (gotclass and (gotsubscript or gotwith)) then
  924. valid_for_assign:=true
  925. else
  926. CGMessagePos(hp.fileinfo,type_e_argument_cant_be_assigned);
  927. exit;
  928. end;
  929. loadn :
  930. begin
  931. case tloadnode(hp).symtableentry.typ of
  932. absolutesym,
  933. varsym :
  934. begin
  935. if (tvarsym(tloadnode(hp).symtableentry).varspez=vs_const) then
  936. begin
  937. { allow p^:= constructions with p is const parameter }
  938. if gotderef then
  939. valid_for_assign:=true
  940. else
  941. CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
  942. exit;
  943. end;
  944. { Are we at a with symtable, then we need to process the
  945. withrefnode also to check for maybe a const load }
  946. if (tloadnode(hp).symtable.symtabletype=withsymtable) then
  947. begin
  948. { continue with processing the withref node }
  949. hp:=tnode(twithsymtable(tloadnode(hp).symtable).withrefnode);
  950. gotwith:=true;
  951. end
  952. else
  953. begin
  954. valid_for_assign:=true;
  955. exit;
  956. end;
  957. end;
  958. typedconstsym :
  959. begin
  960. if ttypedconstsym(tloadnode(hp).symtableentry).is_writable then
  961. valid_for_assign:=true
  962. else
  963. CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
  964. exit;
  965. end;
  966. else
  967. begin
  968. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  969. exit;
  970. end;
  971. end;
  972. end;
  973. else
  974. begin
  975. CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
  976. exit;
  977. end;
  978. end;
  979. end;
  980. end;
  981. function valid_for_var(p:tnode):boolean;
  982. begin
  983. valid_for_var:=valid_for_assign(p,[]);
  984. end;
  985. function valid_for_formal_var(p : tnode) : boolean;
  986. begin
  987. valid_for_formal_var:=valid_for_assign(p,[valid_void]);
  988. end;
  989. function valid_for_formal_const(p : tnode) : boolean;
  990. var
  991. v : boolean;
  992. begin
  993. { p must have been firstpass'd before }
  994. { accept about anything but not a statement ! }
  995. case p.nodetype of
  996. calln,
  997. statementn,
  998. addrn :
  999. begin
  1000. { addrn is not allowed as this generate a constant value,
  1001. but a tp procvar are allowed (PFV) }
  1002. if nf_procvarload in p.flags then
  1003. v:=true
  1004. else
  1005. v:=false;
  1006. end;
  1007. else
  1008. v:=true;
  1009. end;
  1010. valid_for_formal_const:=v;
  1011. end;
  1012. function valid_for_assignment(p:tnode):boolean;
  1013. begin
  1014. valid_for_assignment:=valid_for_assign(p,[valid_property]);
  1015. end;
  1016. procedure var_para_allowed(var eq:tequaltype;def_from,def_to:Tdef);
  1017. begin
  1018. { Note: eq must be already valid, it will only be updated! }
  1019. case def_to.deftype of
  1020. formaldef :
  1021. begin
  1022. { all types can be passed to a formaldef }
  1023. eq:=te_equal;
  1024. end;
  1025. orddef :
  1026. begin
  1027. { allows conversion from word to integer and
  1028. byte to shortint, but only for TP7 compatibility }
  1029. if (m_tp7 in aktmodeswitches) and
  1030. (def_from.deftype=orddef) and
  1031. (def_from.size=def_to.size) then
  1032. eq:=te_convert_l1;
  1033. end;
  1034. arraydef :
  1035. begin
  1036. if is_open_array(def_to) and
  1037. is_dynamic_array(def_from) and
  1038. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  1039. eq:=te_convert_l2;
  1040. end;
  1041. pointerdef :
  1042. begin
  1043. { an implicit pointer conversion is allowed }
  1044. if (def_from.deftype=pointerdef) then
  1045. eq:=te_convert_l1;
  1046. end;
  1047. stringdef :
  1048. begin
  1049. { all shortstrings are allowed, size is not important }
  1050. if is_shortstring(def_from) and
  1051. is_shortstring(def_to) then
  1052. eq:=te_equal;
  1053. end;
  1054. objectdef :
  1055. begin
  1056. { child objects can be also passed }
  1057. { in non-delphi mode, otherwise }
  1058. { they must match exactly, except }
  1059. { if they are objects }
  1060. if (def_from.deftype=objectdef) and
  1061. (
  1062. not(m_delphi in aktmodeswitches) or
  1063. (
  1064. (tobjectdef(def_from).objecttype=odt_object) and
  1065. (tobjectdef(def_to).objecttype=odt_object)
  1066. )
  1067. ) and
  1068. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  1069. eq:=te_convert_l1;
  1070. end;
  1071. filedef :
  1072. begin
  1073. { an implicit file conversion is also allowed }
  1074. { from a typed file to an untyped one }
  1075. if (def_from.deftype=filedef) and
  1076. (tfiledef(def_from).filetyp = ft_typed) and
  1077. (tfiledef(def_to).filetyp = ft_untyped) then
  1078. eq:=te_convert_l1;
  1079. end;
  1080. end;
  1081. end;
  1082. procedure para_allowed(var eq:tequaltype;p:tcallparanode;def_to:tdef);
  1083. begin
  1084. { Note: eq must be already valid, it will only be updated! }
  1085. case def_to.deftype of
  1086. formaldef :
  1087. begin
  1088. { all types can be passed to a formaldef }
  1089. eq:=te_equal;
  1090. end;
  1091. stringdef :
  1092. begin
  1093. { to support ansi/long/wide strings in a proper way }
  1094. { string and string[10] are assumed as equal }
  1095. { when searching the correct overloaded procedure }
  1096. if (p.resulttype.def.deftype=stringdef) and
  1097. (tstringdef(def_to).string_typ=tstringdef(p.resulttype.def).string_typ) then
  1098. eq:=te_equal
  1099. else
  1100. { Passing a constant char to ansistring or shortstring or
  1101. a widechar to widestring then handle it as equal. }
  1102. if (p.left.nodetype=ordconstn) and
  1103. (
  1104. is_char(p.resulttype.def) and
  1105. (is_shortstring(def_to) or is_ansistring(def_to))
  1106. ) or
  1107. (
  1108. is_widechar(p.resulttype.def) and
  1109. is_widestring(def_to)
  1110. ) then
  1111. eq:=te_equal
  1112. end;
  1113. setdef :
  1114. begin
  1115. { set can also be a not yet converted array constructor }
  1116. if (p.resulttype.def.deftype=arraydef) and
  1117. (tarraydef(p.resulttype.def).IsConstructor) and
  1118. not(tarraydef(p.resulttype.def).IsVariant) then
  1119. eq:=te_equal;
  1120. end;
  1121. procvardef :
  1122. begin
  1123. { in tp7 mode proc -> procvar is allowed }
  1124. if (m_tp_procvar in aktmodeswitches) and
  1125. (p.left.nodetype=calln) and
  1126. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def_to),true)>=te_equal) then
  1127. eq:=te_equal;
  1128. end;
  1129. end;
  1130. end;
  1131. {****************************************************************************
  1132. TCallCandidates
  1133. ****************************************************************************}
  1134. constructor tcallcandidates.create(sym:tprocsym;st:tsymtable;ppn:tnode;isprop:boolean);
  1135. var
  1136. j : integer;
  1137. pd : tprocdef;
  1138. hp : pcandidate;
  1139. found,
  1140. has_overload_directive : boolean;
  1141. topclassh : tobjectdef;
  1142. srsymtable : tsymtable;
  1143. srprocsym : tprocsym;
  1144. pt : tcallparanode;
  1145. begin
  1146. FProcSym:=sym;
  1147. FProcs:=nil;
  1148. FProccnt:=0;
  1149. FProcvisiblecnt:=0;
  1150. FParanode:=ppn;
  1151. FAllowVariant:=true;
  1152. { determine length of parameter list }
  1153. pt:=tcallparanode(ppn);
  1154. FParalength:=0;
  1155. while assigned(pt) do
  1156. begin
  1157. inc(FParalength);
  1158. pt:=tcallparanode(pt.right);
  1159. end;
  1160. { when the definition has overload directive set, we search for
  1161. overloaded definitions in the class, this only needs to be done once
  1162. for class entries as the tree keeps always the same }
  1163. if (not sym.overloadchecked) and
  1164. (sym.owner.symtabletype=objectsymtable) and
  1165. (po_overload in sym.first_procdef.procoptions) then
  1166. search_class_overloads(sym);
  1167. { when the class passed is defined in this unit we
  1168. need to use the scope of that class. This is a trick
  1169. that can be used to access protected members in other
  1170. units. At least kylix supports it this way (PFV) }
  1171. if assigned(st) and
  1172. (st.symtabletype=objectsymtable) and
  1173. (st.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  1174. (st.defowner.owner.unitid=0) then
  1175. topclassh:=tobjectdef(st.defowner)
  1176. else
  1177. begin
  1178. if assigned(current_procinfo) then
  1179. topclassh:=current_procinfo.procdef._class
  1180. else
  1181. topclassh:=nil;
  1182. end;
  1183. { link all procedures which have the same # of parameters }
  1184. for j:=1 to sym.procdef_count do
  1185. begin
  1186. pd:=sym.procdef[j];
  1187. { Is the procdef visible? This needs to be checked on
  1188. procdef level since a symbol can contain both private and
  1189. public declarations. But the check should not be done
  1190. when the callnode is generated by a property }
  1191. if isprop or
  1192. (pd.owner.symtabletype<>objectsymtable) or
  1193. pd.is_visible_for_object(topclassh) then
  1194. begin
  1195. { we have at least one procedure that is visible }
  1196. inc(FProcvisiblecnt);
  1197. { only when the # of parameter are supported by the
  1198. procedure }
  1199. if (FParalength>=pd.minparacount) and
  1200. ((po_varargs in pd.procoptions) or { varargs }
  1201. (FParalength<=pd.maxparacount)) then
  1202. proc_add(pd);
  1203. end;
  1204. end;
  1205. { remember if the procedure is declared with the overload directive,
  1206. it's information is still needed also after all procs are removed }
  1207. has_overload_directive:=(po_overload in sym.first_procdef.procoptions);
  1208. { when the definition has overload directive set, we search for
  1209. overloaded definitions in the symtablestack. The found
  1210. entries are only added to the procs list and not the procsym, because
  1211. the list can change in every situation }
  1212. if has_overload_directive and
  1213. (sym.owner.symtabletype<>objectsymtable) then
  1214. begin
  1215. srsymtable:=sym.owner.next;
  1216. while assigned(srsymtable) do
  1217. begin
  1218. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1219. begin
  1220. srprocsym:=tprocsym(srsymtable.speedsearch(sym.name,sym.speedvalue));
  1221. { process only visible procsyms }
  1222. if assigned(srprocsym) and
  1223. (srprocsym.typ=procsym) and
  1224. srprocsym.is_visible_for_object(topclassh) then
  1225. begin
  1226. { if this procedure doesn't have overload we can stop
  1227. searching }
  1228. if not(po_overload in srprocsym.first_procdef.procoptions) then
  1229. break;
  1230. { process all overloaded definitions }
  1231. for j:=1 to srprocsym.procdef_count do
  1232. begin
  1233. pd:=srprocsym.procdef[j];
  1234. { only when the # of parameter are supported by the
  1235. procedure }
  1236. if (FParalength>=pd.minparacount) and
  1237. ((po_varargs in pd.procoptions) or { varargs }
  1238. (FParalength<=pd.maxparacount)) then
  1239. begin
  1240. found:=false;
  1241. hp:=FProcs;
  1242. while assigned(hp) do
  1243. begin
  1244. { Only compare visible parameters for the user }
  1245. if compare_paras(hp^.data.para,pd.para,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
  1246. begin
  1247. found:=true;
  1248. break;
  1249. end;
  1250. hp:=hp^.next;
  1251. end;
  1252. if not found then
  1253. proc_add(pd);
  1254. end;
  1255. end;
  1256. end;
  1257. end;
  1258. srsymtable:=srsymtable.next;
  1259. end;
  1260. end;
  1261. end;
  1262. constructor tcallcandidates.create_operator(op:ttoken;ppn:tnode);
  1263. var
  1264. j : integer;
  1265. pd : tprocdef;
  1266. hp : pcandidate;
  1267. found : boolean;
  1268. srsymtable : tsymtable;
  1269. srprocsym : tprocsym;
  1270. pt : tcallparanode;
  1271. sv : cardinal;
  1272. begin
  1273. FProcSym:=nil;
  1274. FProcs:=nil;
  1275. FProccnt:=0;
  1276. FProcvisiblecnt:=0;
  1277. FParanode:=ppn;
  1278. FAllowVariant:=false;
  1279. { determine length of parameter list }
  1280. pt:=tcallparanode(ppn);
  1281. FParalength:=0;
  1282. while assigned(pt) do
  1283. begin
  1284. if pt.resulttype.def.deftype=variantdef then
  1285. FAllowVariant:=true;
  1286. inc(FParalength);
  1287. pt:=tcallparanode(pt.right);
  1288. end;
  1289. { we search all overloaded operator definitions in the symtablestack. The found
  1290. entries are only added to the procs list and not the procsym, because
  1291. the list can change in every situation }
  1292. sv:=getspeedvalue(overloaded_names[op]);
  1293. srsymtable:=symtablestack;
  1294. while assigned(srsymtable) do
  1295. begin
  1296. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1297. begin
  1298. srprocsym:=tprocsym(srsymtable.speedsearch(overloaded_names[op],sv));
  1299. if assigned(srprocsym) and
  1300. (srprocsym.typ=procsym) then
  1301. begin
  1302. { Store first procsym found }
  1303. if not assigned(FProcsym) then
  1304. FProcsym:=srprocsym;
  1305. { process all overloaded definitions }
  1306. for j:=1 to srprocsym.procdef_count do
  1307. begin
  1308. pd:=srprocsym.procdef[j];
  1309. { only when the # of parameter are supported by the
  1310. procedure }
  1311. if (FParalength>=pd.minparacount) and
  1312. (FParalength<=pd.maxparacount) then
  1313. begin
  1314. found:=false;
  1315. hp:=FProcs;
  1316. while assigned(hp) do
  1317. begin
  1318. { Only compare visible parameters for the user }
  1319. if compare_paras(hp^.data.para,pd.para,cp_value_equal_const,[cpo_ignorehidden])>=te_equal then
  1320. begin
  1321. found:=true;
  1322. break;
  1323. end;
  1324. hp:=hp^.next;
  1325. end;
  1326. if not found then
  1327. proc_add(pd);
  1328. end;
  1329. end;
  1330. end;
  1331. end;
  1332. srsymtable:=srsymtable.next;
  1333. end;
  1334. end;
  1335. destructor tcallcandidates.destroy;
  1336. var
  1337. hpnext,
  1338. hp : pcandidate;
  1339. begin
  1340. hp:=FProcs;
  1341. while assigned(hp) do
  1342. begin
  1343. hpnext:=hp^.next;
  1344. dispose(hp);
  1345. hp:=hpnext;
  1346. end;
  1347. end;
  1348. function tcallcandidates.proc_add(pd:tprocdef):pcandidate;
  1349. var
  1350. i : integer;
  1351. begin
  1352. { generate new candidate entry }
  1353. new(result);
  1354. fillchar(result^,sizeof(tcandidate),0);
  1355. result^.data:=pd;
  1356. result^.next:=FProcs;
  1357. FProcs:=result;
  1358. inc(FProccnt);
  1359. { Find last parameter, skip all default parameters
  1360. that are not passed. Ignore this skipping for varargs }
  1361. result^.firstpara:=tparaitem(pd.Para.last);
  1362. if not(po_varargs in pd.procoptions) then
  1363. begin
  1364. { ignore hidden parameters }
  1365. while assigned(result^.firstpara) and (result^.firstpara.is_hidden) do
  1366. result^.firstpara:=tparaitem(result^.firstpara.previous);
  1367. for i:=1 to pd.maxparacount-FParalength do
  1368. begin
  1369. if not assigned(result^.firstpara) then
  1370. internalerror(200401141);
  1371. result^.firstpara:=tparaitem(result^.firstPara.previous);
  1372. end;
  1373. end;
  1374. end;
  1375. procedure tcallcandidates.list(all:boolean);
  1376. var
  1377. hp : pcandidate;
  1378. begin
  1379. hp:=FProcs;
  1380. while assigned(hp) do
  1381. begin
  1382. if all or
  1383. (not hp^.invalid) then
  1384. MessagePos1(hp^.data.fileinfo,sym_h_param_list,hp^.data.fullprocname(false));
  1385. hp:=hp^.next;
  1386. end;
  1387. end;
  1388. {$ifdef EXTDEBUG}
  1389. procedure tcallcandidates.dump_info(lvl:longint);
  1390. function ParaTreeStr(p:tcallparanode):string;
  1391. begin
  1392. result:='';
  1393. while assigned(p) do
  1394. begin
  1395. if result<>'' then
  1396. result:=result+',';
  1397. result:=result+p.resulttype.def.typename;
  1398. p:=tcallparanode(p.right);
  1399. end;
  1400. end;
  1401. var
  1402. hp : pcandidate;
  1403. currpara : tparaitem;
  1404. begin
  1405. if not CheckVerbosity(lvl) then
  1406. exit;
  1407. Comment(lvl+V_LineInfo,'Overloaded callnode: '+FProcSym.name+'('+ParaTreeStr(tcallparanode(FParaNode))+')');
  1408. hp:=FProcs;
  1409. while assigned(hp) do
  1410. begin
  1411. Comment(lvl,' '+hp^.data.fullprocname(false));
  1412. if (hp^.invalid) then
  1413. Comment(lvl,' invalid')
  1414. else
  1415. begin
  1416. Comment(lvl,' ex: '+tostr(hp^.exact_count)+
  1417. ' eq: '+tostr(hp^.equal_count)+
  1418. ' l1: '+tostr(hp^.cl1_count)+
  1419. ' l2: '+tostr(hp^.cl2_count)+
  1420. ' l3: '+tostr(hp^.cl3_count)+
  1421. ' oper: '+tostr(hp^.coper_count)+
  1422. ' ord: '+realtostr(hp^.exact_count));
  1423. { Print parameters in left-right order }
  1424. currpara:=hp^.firstpara;
  1425. if assigned(currpara) then
  1426. begin
  1427. while assigned(currpara.next) do
  1428. currpara:=tparaitem(currpara.next);
  1429. end;
  1430. while assigned(currpara) do
  1431. begin
  1432. if (not currpara.is_hidden) then
  1433. Comment(lvl,' - '+currpara.paratype.def.typename+' : '+EqualTypeName[currpara.eqval]);
  1434. currpara:=tparaitem(currpara.previous);
  1435. end;
  1436. end;
  1437. hp:=hp^.next;
  1438. end;
  1439. end;
  1440. {$endif EXTDEBUG}
  1441. procedure tcallcandidates.get_information;
  1442. var
  1443. hp : pcandidate;
  1444. currpara : tparaitem;
  1445. currparanr : byte;
  1446. def_from,
  1447. def_to : tdef;
  1448. currpt,
  1449. pt : tcallparanode;
  1450. eq : tequaltype;
  1451. convtype : tconverttype;
  1452. pdoper : tprocdef;
  1453. releasecurrpt : boolean;
  1454. cdoptions : tcompare_defs_options;
  1455. begin
  1456. cdoptions:=[cdo_check_operator];
  1457. if FAllowVariant then
  1458. include(cdoptions,cdo_allow_variant);
  1459. { process all procs }
  1460. hp:=FProcs;
  1461. while assigned(hp) do
  1462. begin
  1463. { We compare parameters in reverse order (right to left),
  1464. the firstpara is already pointing to the last parameter
  1465. were we need to start comparing }
  1466. currparanr:=FParalength;
  1467. currpara:=hp^.firstpara;
  1468. while assigned(currpara) and (currpara.is_hidden) do
  1469. currpara:=tparaitem(currpara.previous);
  1470. pt:=tcallparanode(FParaNode);
  1471. while assigned(pt) and assigned(currpara) do
  1472. begin
  1473. { currpt can be changed from loadn to calln when a procvar
  1474. is passed. This is to prevent that the change is permanent }
  1475. currpt:=pt;
  1476. releasecurrpt:=false;
  1477. { retrieve current parameter definitions to compares }
  1478. eq:=te_incompatible;
  1479. def_from:=currpt.resulttype.def;
  1480. def_to:=currpara.paratype.def;
  1481. if not(assigned(def_from)) then
  1482. internalerror(200212091);
  1483. if not(
  1484. assigned(def_to) or
  1485. ((po_varargs in hp^.data.procoptions) and
  1486. (currparanr>hp^.data.minparacount))
  1487. ) then
  1488. internalerror(200212092);
  1489. { Convert tp procvars when not expecting a procvar }
  1490. if (def_to.deftype<>procvardef) and
  1491. (currpt.left.resulttype.def.deftype=procvardef) then
  1492. begin
  1493. releasecurrpt:=true;
  1494. currpt:=tcallparanode(pt.getcopy);
  1495. if maybe_call_procvar(currpt.left,true) then
  1496. begin
  1497. currpt.resulttype:=currpt.left.resulttype;
  1498. def_from:=currpt.left.resulttype.def;
  1499. end;
  1500. end;
  1501. { varargs are always equal, but not exact }
  1502. if (po_varargs in hp^.data.procoptions) and
  1503. (currparanr>hp^.data.minparacount) then
  1504. begin
  1505. eq:=te_equal;
  1506. end
  1507. else
  1508. { same definition -> exact }
  1509. if (def_from=def_to) then
  1510. begin
  1511. eq:=te_exact;
  1512. end
  1513. else
  1514. { for value and const parameters check if a integer is constant or
  1515. included in other integer -> equal and calc ordinal_distance }
  1516. if not(currpara.paratyp in [vs_var,vs_out]) and
  1517. is_integer(def_from) and
  1518. is_integer(def_to) and
  1519. is_in_limit(def_from,def_to) then
  1520. begin
  1521. eq:=te_equal;
  1522. hp^.ordinal_distance:=hp^.ordinal_distance+
  1523. abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
  1524. hp^.ordinal_distance:=hp^.ordinal_distance+
  1525. abs(bestreal(torddef(def_to).high)-bestreal(torddef(def_from).high));
  1526. { Give wrong sign a small penalty, this is need to get a diffrence
  1527. from word->[longword,longint] }
  1528. if is_signed(def_from)<>is_signed(def_to) then
  1529. hp^.ordinal_distance:=hp^.ordinal_distance+1.0;
  1530. end
  1531. else
  1532. { generic type comparision }
  1533. begin
  1534. eq:=compare_defs_ext(def_from,def_to,currpt.left.nodetype,convtype,pdoper,cdoptions);
  1535. { when the types are not equal we need to check
  1536. some special case for parameter passing }
  1537. if (eq<te_equal) then
  1538. begin
  1539. if currpara.paratyp in [vs_var,vs_out] then
  1540. begin
  1541. { para requires an equal type so the previous found
  1542. match was not good enough, reset to incompatible }
  1543. eq:=te_incompatible;
  1544. { var_para_allowed will return te_equal and te_convert_l1 to
  1545. make a difference for best matching }
  1546. var_para_allowed(eq,currpt.resulttype.def,currpara.paratype.def)
  1547. end
  1548. else
  1549. para_allowed(eq,currpt,def_to);
  1550. end;
  1551. end;
  1552. { when a procvar was changed to a call an exact much is
  1553. downgraded to equal. This way an overload call with the
  1554. procvar is choosen. See tb0471 (PFV) }
  1555. if (pt<>currpt) and (eq=te_exact) then
  1556. eq:=te_equal;
  1557. { increase correct counter }
  1558. case eq of
  1559. te_exact :
  1560. inc(hp^.exact_count);
  1561. te_equal :
  1562. inc(hp^.equal_count);
  1563. te_convert_l1 :
  1564. inc(hp^.cl1_count);
  1565. te_convert_l2 :
  1566. inc(hp^.cl2_count);
  1567. te_convert_l3 :
  1568. inc(hp^.cl3_count);
  1569. te_convert_operator :
  1570. inc(hp^.coper_count);
  1571. te_incompatible :
  1572. hp^.invalid:=true;
  1573. else
  1574. internalerror(200212072);
  1575. end;
  1576. { stop checking when an incompatible parameter is found }
  1577. if hp^.invalid then
  1578. begin
  1579. { store the current parameter info for
  1580. a nice error message when no procedure is found }
  1581. hp^.wrongpara:=currpara;
  1582. hp^.wrongparanr:=currparanr;
  1583. break;
  1584. end;
  1585. {$ifdef EXTDEBUG}
  1586. { store equal in node tree for dump }
  1587. currpara.eqval:=eq;
  1588. {$endif EXTDEBUG}
  1589. { maybe release temp currpt }
  1590. if releasecurrpt then
  1591. currpt.free;
  1592. { next parameter in the call tree }
  1593. pt:=tcallparanode(pt.right);
  1594. { next parameter for definition, only goto next para
  1595. if we're out of the varargs }
  1596. if not(po_varargs in hp^.data.procoptions) or
  1597. (currparanr<=hp^.data.maxparacount) then
  1598. begin
  1599. { Ignore vs_hidden parameters }
  1600. repeat
  1601. currpara:=tparaitem(currpara.previous);
  1602. until (not assigned(currpara)) or (not currpara.is_hidden);
  1603. end;
  1604. dec(currparanr);
  1605. end;
  1606. if not(hp^.invalid) and
  1607. (assigned(pt) or assigned(currpara) or (currparanr<>0)) then
  1608. internalerror(200212141);
  1609. { next candidate }
  1610. hp:=hp^.next;
  1611. end;
  1612. end;
  1613. function is_better_candidate(currpd,bestpd:pcandidate):integer;
  1614. var
  1615. res : integer;
  1616. begin
  1617. {
  1618. Return values:
  1619. > 0 when currpd is better than bestpd
  1620. < 0 when bestpd is better than currpd
  1621. = 0 when both are equal
  1622. To choose the best candidate we use the following order:
  1623. - Incompatible flag
  1624. - (Smaller) Number of convert operator parameters.
  1625. - (Smaller) Number of convertlevel 2 parameters.
  1626. - (Smaller) Number of convertlevel 1 parameters.
  1627. - (Bigger) Number of exact parameters.
  1628. - (Smaller) Number of equal parameters.
  1629. - (Smaller) Total of ordinal distance. For example, the distance of a word
  1630. to a byte is 65535-255=65280.
  1631. }
  1632. if bestpd^.invalid then
  1633. begin
  1634. if currpd^.invalid then
  1635. res:=0
  1636. else
  1637. res:=1;
  1638. end
  1639. else
  1640. if currpd^.invalid then
  1641. res:=-1
  1642. else
  1643. begin
  1644. { less operator parameters? }
  1645. res:=(bestpd^.coper_count-currpd^.coper_count);
  1646. if (res=0) then
  1647. begin
  1648. { less cl3 parameters? }
  1649. res:=(bestpd^.cl3_count-currpd^.cl3_count);
  1650. if (res=0) then
  1651. begin
  1652. { less cl2 parameters? }
  1653. res:=(bestpd^.cl2_count-currpd^.cl2_count);
  1654. if (res=0) then
  1655. begin
  1656. { less cl1 parameters? }
  1657. res:=(bestpd^.cl1_count-currpd^.cl1_count);
  1658. if (res=0) then
  1659. begin
  1660. { more exact parameters? }
  1661. res:=(currpd^.exact_count-bestpd^.exact_count);
  1662. if (res=0) then
  1663. begin
  1664. { less equal parameters? }
  1665. res:=(bestpd^.equal_count-currpd^.equal_count);
  1666. if (res=0) then
  1667. begin
  1668. { smaller ordinal distance? }
  1669. if (currpd^.ordinal_distance<bestpd^.ordinal_distance) then
  1670. res:=1
  1671. else
  1672. if (currpd^.ordinal_distance>bestpd^.ordinal_distance) then
  1673. res:=-1
  1674. else
  1675. res:=0;
  1676. end;
  1677. end;
  1678. end;
  1679. end;
  1680. end;
  1681. end;
  1682. end;
  1683. is_better_candidate:=res;
  1684. end;
  1685. function tcallcandidates.choose_best(var bestpd:tabstractprocdef):integer;
  1686. var
  1687. besthpstart,
  1688. hp : pcandidate;
  1689. cntpd,
  1690. res : integer;
  1691. begin
  1692. {
  1693. Returns the number of candidates left and the
  1694. first candidate is returned in pdbest
  1695. }
  1696. { Setup the first procdef as best, only count it as a result
  1697. when it is valid }
  1698. bestpd:=FProcs^.data;
  1699. if FProcs^.invalid then
  1700. cntpd:=0
  1701. else
  1702. cntpd:=1;
  1703. if assigned(FProcs^.next) then
  1704. begin
  1705. besthpstart:=FProcs;
  1706. hp:=FProcs^.next;
  1707. while assigned(hp) do
  1708. begin
  1709. res:=is_better_candidate(hp,besthpstart);
  1710. if (res>0) then
  1711. begin
  1712. { hp is better, flag all procs to be incompatible }
  1713. while (besthpstart<>hp) do
  1714. begin
  1715. besthpstart^.invalid:=true;
  1716. besthpstart:=besthpstart^.next;
  1717. end;
  1718. { besthpstart is already set to hp }
  1719. bestpd:=besthpstart^.data;
  1720. cntpd:=1;
  1721. end
  1722. else
  1723. if (res<0) then
  1724. begin
  1725. { besthpstart is better, flag current hp to be incompatible }
  1726. hp^.invalid:=true;
  1727. end
  1728. else
  1729. begin
  1730. { res=0, both are valid }
  1731. if not hp^.invalid then
  1732. inc(cntpd);
  1733. end;
  1734. hp:=hp^.next;
  1735. end;
  1736. end;
  1737. result:=cntpd;
  1738. end;
  1739. procedure tcallcandidates.find_wrong_para;
  1740. var
  1741. currparanr : smallint;
  1742. hp : pcandidate;
  1743. pt : tcallparanode;
  1744. begin
  1745. { Only process the first overloaded procdef }
  1746. hp:=FProcs;
  1747. { Find callparanode corresponding to the argument }
  1748. pt:=tcallparanode(FParanode);
  1749. currparanr:=FParalength;
  1750. while assigned(pt) and
  1751. (currparanr>hp^.wrongparanr) do
  1752. begin
  1753. pt:=tcallparanode(pt.right);
  1754. dec(currparanr);
  1755. end;
  1756. if (currparanr<>hp^.wrongparanr) or
  1757. not assigned(pt) then
  1758. internalerror(200212094);
  1759. { Show error message, when it was a var or out parameter
  1760. guess that it is a missing typeconv }
  1761. if hp^.wrongpara.paratyp in [vs_var,vs_out] then
  1762. CGMessagePos2(pt.fileinfo,parser_e_call_by_ref_without_typeconv,
  1763. pt.resulttype.def.typename,hp^.wrongpara.paratype.def.typename)
  1764. else
  1765. CGMessagePos3(pt.fileinfo,type_e_wrong_parameter_type,
  1766. tostr(hp^.wrongparanr),pt.resulttype.def.typename,hp^.wrongpara.paratype.def.typename);
  1767. end;
  1768. end.
  1769. {
  1770. $Log$
  1771. Revision 1.86 2004-05-16 13:29:46 peter
  1772. * forbid more overloaded operators with orddef/enumdef
  1773. Revision 1.85 2004/04/18 07:52:43 florian
  1774. * fixed web bug 3048: comparision of dyn. arrays
  1775. Revision 1.84 2004/03/18 16:29:07 peter
  1776. * missing result initialization in node2opstr
  1777. Revision 1.83 2004/03/18 16:19:03 peter
  1778. * fixed operator overload allowing for pointer-string
  1779. * replaced some type_e_mismatch with more informational messages
  1780. Revision 1.82 2004/02/26 16:11:09 peter
  1781. * return cnothingn and give error when the operator is not overloaded
  1782. Revision 1.81 2004/02/24 16:12:39 peter
  1783. * operator overload chooses rewrite
  1784. * overload choosing is now generic and moved to htypechk
  1785. Revision 1.80 2004/02/20 21:55:19 peter
  1786. * widestring conversions added to allowed operator check
  1787. Revision 1.79 2004/02/13 15:42:21 peter
  1788. * compare_defs_ext has now a options argument
  1789. * fixes for variants
  1790. Revision 1.78 2004/02/12 15:54:03 peter
  1791. * make extcycle is working again
  1792. Revision 1.77 2004/02/04 22:15:15 daniel
  1793. * Rtti generation moved to ncgutil
  1794. * Assmtai usage of symsym removed
  1795. * operator overloading cleanup up
  1796. Revision 1.76 2004/02/03 22:32:53 peter
  1797. * renamed xNNbittype to xNNinttype
  1798. * renamed registers32 to registersint
  1799. * replace some s32bit,u32bit with torddef([su]inttype).def.typ
  1800. Revision 1.75 2003/11/12 15:48:27 peter
  1801. * fix set_varstate in for loops
  1802. * fix set_varstate from case statements
  1803. Revision 1.74 2003/10/30 19:20:05 peter
  1804. * fix IE when passing array to open array
  1805. Revision 1.73 2003/10/30 17:42:48 peter
  1806. * also check for uninited vars in staticsymtable
  1807. Revision 1.72 2003/10/28 15:36:01 peter
  1808. * absolute to object field supported, fixes tb0458
  1809. Revision 1.71 2003/10/21 18:16:13 peter
  1810. * IncompatibleTypes() added that will include unit names when
  1811. the typenames are the same
  1812. Revision 1.70 2003/10/20 19:29:12 peter
  1813. * fix check for typecasting wrong sizes in assignment left
  1814. Revision 1.69 2003/10/08 19:19:45 peter
  1815. * set_varstate cleanup
  1816. Revision 1.68 2003/10/05 21:21:52 peter
  1817. * c style array of const generates callparanodes
  1818. * varargs paraloc fixes
  1819. Revision 1.67 2003/10/01 20:34:48 peter
  1820. * procinfo unit contains tprocinfo
  1821. * cginfo renamed to cgbase
  1822. * moved cgmessage to verbose
  1823. * fixed ppc and sparc compiles
  1824. Revision 1.66 2003/08/23 18:52:18 peter
  1825. * don't check size for open array in valid_for_assign
  1826. Revision 1.65 2003/07/08 15:20:56 peter
  1827. * don't allow add/assignments for formaldef
  1828. * formaldef size changed to 0
  1829. Revision 1.64 2003/06/13 21:19:30 peter
  1830. * current_procdef removed, use current_procinfo.procdef instead
  1831. Revision 1.63 2003/05/09 17:47:02 peter
  1832. * self moved to hidden parameter
  1833. * removed hdisposen,hnewn,selfn
  1834. Revision 1.62 2003/04/27 11:21:32 peter
  1835. * aktprocdef renamed to current_procinfo.procdef
  1836. * procinfo renamed to current_procinfo
  1837. * procinfo will now be stored in current_module so it can be
  1838. cleaned up properly
  1839. * gen_main_procsym changed to create_main_proc and release_main_proc
  1840. to also generate a tprocinfo structure
  1841. * fixed unit implicit initfinal
  1842. Revision 1.61 2003/04/27 07:29:50 peter
  1843. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  1844. a new procdef declaration
  1845. * aktprocsym removed
  1846. * lexlevel removed, use symtable.symtablelevel instead
  1847. * implicit init/final code uses the normal genentry/genexit
  1848. * funcret state checking updated for new funcret handling
  1849. Revision 1.60 2003/04/25 20:59:33 peter
  1850. * removed funcretn,funcretsym, function result is now in varsym
  1851. and aliases for result and function name are added using absolutesym
  1852. * vs_hidden parameter for funcret passed in parameter
  1853. * vs_hidden fixes
  1854. * writenode changed to printnode and released from extdebug
  1855. * -vp option added to generate a tree.log with the nodetree
  1856. * nicer printnode for statements, callnode
  1857. Revision 1.59 2003/04/22 23:50:22 peter
  1858. * firstpass uses expectloc
  1859. * checks if there are differences between the expectloc and
  1860. location.loc from secondpass in EXTDEBUG
  1861. Revision 1.58 2003/01/03 17:17:26 peter
  1862. * use compare_def_ext to test if assignn operator is allowed
  1863. Revision 1.57 2003/01/02 22:21:19 peter
  1864. * fixed previous operator change
  1865. Revision 1.56 2003/01/02 19:50:21 peter
  1866. * fixed operator checking for objects
  1867. * made binary operator checking simpeler
  1868. Revision 1.55 2002/12/27 18:06:32 peter
  1869. * fix overload error for dynarr:=nil
  1870. Revision 1.54 2002/12/22 16:34:49 peter
  1871. * proc-procvar crash fixed (tw2277)
  1872. Revision 1.53 2002/12/11 22:39:24 peter
  1873. * better error message when no operator is found for equal
  1874. Revision 1.52 2002/11/27 22:11:59 peter
  1875. * rewrote isbinaryoverloadable to use a case. it's now much easier
  1876. to understand what is happening
  1877. Revision 1.51 2002/11/25 17:43:17 peter
  1878. * splitted defbase in defutil,symutil,defcmp
  1879. * merged isconvertable and is_equal into compare_defs(_ext)
  1880. * made operator search faster by walking the list only once
  1881. Revision 1.50 2002/10/07 20:12:08 peter
  1882. * ugly hack to fix tb0411
  1883. Revision 1.49 2002/10/05 00:47:03 peter
  1884. * support dynamicarray<>nil
  1885. Revision 1.48 2002/10/04 21:13:59 peter
  1886. * ignore vecn,subscriptn when checking for a procvar loadn
  1887. Revision 1.47 2002/09/16 18:09:34 peter
  1888. * set_funcret_valid fixed when result was already used in a nested
  1889. procedure
  1890. Revision 1.46 2002/07/20 11:57:53 florian
  1891. * types.pas renamed to defbase.pas because D6 contains a types
  1892. unit so this would conflicts if D6 programms are compiled
  1893. + Willamette/SSE2 instructions to assembler added
  1894. Revision 1.45 2002/05/18 13:34:08 peter
  1895. * readded missing revisions
  1896. Revision 1.44 2002/05/16 19:46:37 carl
  1897. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1898. + try to fix temp allocation (still in ifdef)
  1899. + generic constructor calls
  1900. + start of tassembler / tmodulebase class cleanup
  1901. Revision 1.42 2002/04/02 17:11:28 peter
  1902. * tlocation,treference update
  1903. * LOC_CONSTANT added for better constant handling
  1904. * secondadd splitted in multiple routines
  1905. * location_force_reg added for loading a location to a register
  1906. of a specified size
  1907. * secondassignment parses now first the right and then the left node
  1908. (this is compatible with Kylix). This saves a lot of push/pop especially
  1909. with string operations
  1910. * adapted some routines to use the new cg methods
  1911. Revision 1.41 2002/01/16 09:33:46 jonas
  1912. * no longer allow assignments to pointer expressions (unless there's a
  1913. deref), reported by John Lee
  1914. }