defcmp.pas 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Compare definitions and parameter lists
  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 defcmp;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,
  23. cpuinfo,
  24. globals,
  25. node,
  26. symconst,symbase,symtype,symdef;
  27. type
  28. { if acp is cp_all the var const or nothing are considered equal }
  29. compare_type = ( cp_none, cp_value_equal_const, cp_all,cp_procvar);
  30. tconverttype = (
  31. tc_equal,
  32. tc_not_possible,
  33. tc_string_2_string,
  34. tc_char_2_string,
  35. tc_char_2_chararray,
  36. tc_pchar_2_string,
  37. tc_cchar_2_pchar,
  38. tc_cstring_2_pchar,
  39. tc_ansistring_2_pchar,
  40. tc_string_2_chararray,
  41. tc_chararray_2_string,
  42. tc_array_2_pointer,
  43. tc_pointer_2_array,
  44. tc_int_2_int,
  45. tc_int_2_bool,
  46. tc_bool_2_bool,
  47. tc_bool_2_int,
  48. tc_real_2_real,
  49. tc_int_2_real,
  50. tc_real_2_currency,
  51. tc_proc_2_procvar,
  52. tc_arrayconstructor_2_set,
  53. tc_load_smallset,
  54. tc_cord_2_pointer,
  55. tc_intf_2_string,
  56. tc_intf_2_guid,
  57. tc_class_2_intf,
  58. tc_char_2_char,
  59. tc_normal_2_smallset,
  60. tc_dynarray_2_openarray,
  61. tc_pwchar_2_string,
  62. tc_variant_2_dynarray,
  63. tc_dynarray_2_variant
  64. );
  65. function compare_defs_ext(def_from,def_to : tdef;
  66. fromtreetype : tnodetype;
  67. explicit : boolean;
  68. check_operator : boolean;
  69. var doconv : tconverttype;
  70. var operatorpd : tprocdef):tequaltype;
  71. { Returns if the type def_from can be converted to def_to or if both types are equal }
  72. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  73. { Returns true, if def1 and def2 are semantically the same }
  74. function equal_defs(def_from,def_to:tdef):boolean;
  75. { Checks for type compatibility (subgroups of type)
  76. used for case statements... probably missing stuff
  77. to use on other types }
  78. function is_subequal(def1, def2: tdef): boolean;
  79. function assignment_overloaded(from_def,to_def : tdef) : tprocdef;
  80. {# true, if two parameter lists are equal
  81. if acp is cp_none, all have to match exactly
  82. if acp is cp_value_equal_const call by value
  83. and call by const parameter are assumed as
  84. equal
  85. allowdefaults indicates if default value parameters
  86. are allowed (in this case, the search order will first
  87. search for a routine with default parameters, before
  88. searching for the same definition with no parameters)
  89. }
  90. function compare_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean):tequaltype;
  91. { True if a function can be assigned to a procvar }
  92. { changed first argument type to pabstractprocdef so that it can also be }
  93. { used to test compatibility between two pprocvardefs (JM) }
  94. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef;methoderr:boolean):tequaltype;
  95. implementation
  96. uses
  97. globtype,tokens,
  98. verbose,systems,
  99. symsym,symtable,
  100. defutil,symutil;
  101. function assignment_overloaded(from_def,to_def:tdef):tprocdef;
  102. begin
  103. if assigned(overloaded_operators[_ASSIGNMENT]) then
  104. assignment_overloaded:=overloaded_operators[_ASSIGNMENT].search_procdef_assignment_operator(from_def,to_def)
  105. else
  106. assignment_overloaded:=nil;
  107. end;
  108. function compare_defs_ext(def_from,def_to : tdef;
  109. fromtreetype : tnodetype;
  110. explicit : boolean;
  111. check_operator : boolean;
  112. var doconv : tconverttype;
  113. var operatorpd : tprocdef):tequaltype;
  114. { Tbasetype:
  115. uvoid,
  116. u8bit,u16bit,u32bit,u64bit,
  117. s8bit,s16bit,s32bit,s64bit,
  118. bool8bit,bool16bit,bool32bit,
  119. uchar,uwidechar }
  120. type
  121. tbasedef=(bvoid,bchar,bint,bbool);
  122. const
  123. basedeftbl:array[tbasetype] of tbasedef =
  124. (bvoid,
  125. bint,bint,bint,bint,
  126. bint,bint,bint,bint,
  127. bbool,bbool,bbool,
  128. bchar,bchar,bint);
  129. basedefconvertsimplicit : array[tbasedef,tbasedef] of tconverttype =
  130. { void, char, int, bool }
  131. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  132. (tc_not_possible,tc_char_2_char,tc_not_possible,tc_not_possible),
  133. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_not_possible),
  134. (tc_not_possible,tc_not_possible,tc_not_possible,tc_bool_2_bool));
  135. basedefconvertsexplicit : array[tbasedef,tbasedef] of tconverttype =
  136. { void, char, int, bool }
  137. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  138. (tc_not_possible,tc_char_2_char,tc_int_2_int,tc_int_2_bool),
  139. (tc_not_possible,tc_int_2_int,tc_int_2_int,tc_int_2_bool),
  140. (tc_not_possible,tc_bool_2_int,tc_bool_2_int,tc_bool_2_bool));
  141. var
  142. subeq,eq : tequaltype;
  143. hd1,hd2 : tdef;
  144. hct : tconverttype;
  145. hd3 : tobjectdef;
  146. hpd : tprocdef;
  147. begin
  148. { safety check }
  149. if not(assigned(def_from) and assigned(def_to)) then
  150. begin
  151. compare_defs_ext:=te_incompatible;
  152. exit;
  153. end;
  154. { same def? then we've an exact match }
  155. if def_from=def_to then
  156. begin
  157. compare_defs_ext:=te_exact;
  158. exit;
  159. end;
  160. { we walk the wanted (def_to) types and check then the def_from
  161. types if there is a conversion possible }
  162. eq:=te_incompatible;
  163. doconv:=tc_not_possible;
  164. case def_to.deftype of
  165. orddef :
  166. begin
  167. case def_from.deftype of
  168. orddef :
  169. begin
  170. if (torddef(def_from).typ=torddef(def_to).typ) then
  171. begin
  172. case torddef(def_from).typ of
  173. u8bit,u16bit,u32bit,u64bit,
  174. s8bit,s16bit,s32bit,s64bit:
  175. begin
  176. if (torddef(def_from).low=torddef(def_to).low) and
  177. (torddef(def_from).high=torddef(def_to).high) then
  178. eq:=te_equal
  179. else
  180. eq:=te_convert_l1;
  181. end;
  182. uvoid,uchar,uwidechar,
  183. bool8bit,bool16bit,bool32bit:
  184. eq:=te_equal;
  185. else
  186. internalerror(200210061);
  187. end;
  188. end
  189. else
  190. begin
  191. if explicit then
  192. doconv:=basedefconvertsexplicit[basedeftbl[torddef(def_from).typ],basedeftbl[torddef(def_to).typ]]
  193. else
  194. doconv:=basedefconvertsimplicit[basedeftbl[torddef(def_from).typ],basedeftbl[torddef(def_to).typ]];
  195. if (doconv=tc_not_possible) then
  196. eq:=te_incompatible
  197. else
  198. { "punish" bad type conversions :) (JM) }
  199. if (not is_in_limit(def_from,def_to)) and
  200. (def_from.size > def_to.size) then
  201. eq:=te_convert_l3
  202. else
  203. eq:=te_convert_l1;
  204. end;
  205. end;
  206. enumdef :
  207. begin
  208. { needed for char(enum) }
  209. if explicit then
  210. begin
  211. doconv:=tc_int_2_int;
  212. eq:=te_convert_l1;
  213. end;
  214. end;
  215. floatdef :
  216. begin
  217. if is_currency(def_to) then
  218. begin
  219. doconv:=tc_real_2_currency;
  220. eq:=te_convert_l2;
  221. end;
  222. end;
  223. classrefdef,
  224. procvardef,
  225. pointerdef :
  226. begin
  227. if explicit then
  228. begin
  229. eq:=te_convert_l1;
  230. if (fromtreetype=niln) then
  231. begin
  232. { will be handled by the constant folding }
  233. doconv:=tc_equal;
  234. end
  235. else
  236. doconv:=tc_int_2_int;
  237. end;
  238. end;
  239. end;
  240. end;
  241. stringdef :
  242. begin
  243. case def_from.deftype of
  244. stringdef :
  245. begin
  246. { Constant string }
  247. if (fromtreetype=stringconstn) then
  248. begin
  249. if (tstringdef(def_from).string_typ=tstringdef(def_to).string_typ) then
  250. eq:=te_equal
  251. else
  252. begin
  253. doconv:=tc_string_2_string;
  254. { Don't prefer conversions from widestring to a
  255. normal string as we can loose information }
  256. if tstringdef(def_from).string_typ=st_widestring then
  257. eq:=te_convert_l1
  258. else
  259. begin
  260. if tstringdef(def_to).string_typ=st_widestring then
  261. eq:=te_convert_l1
  262. else
  263. eq:=te_equal; { we can change the stringconst node }
  264. end;
  265. end;
  266. end
  267. else
  268. { Same string type, for shortstrings also the length must match }
  269. if (tstringdef(def_from).string_typ=tstringdef(def_to).string_typ) and
  270. ((tstringdef(def_from).string_typ<>st_shortstring) or
  271. (tstringdef(def_from).len=tstringdef(def_to).len)) then
  272. eq:=te_equal
  273. else
  274. begin
  275. doconv:=tc_string_2_string;
  276. { Prefer conversions to shortstring over other
  277. conversions. This is compatible with Delphi (PFV) }
  278. if tstringdef(def_to).string_typ=st_shortstring then
  279. eq:=te_convert_l2
  280. else
  281. eq:=te_convert_l3;
  282. end;
  283. end;
  284. orddef :
  285. begin
  286. { char to string}
  287. if is_char(def_from) or
  288. is_widechar(def_from) then
  289. begin
  290. doconv:=tc_char_2_string;
  291. eq:=te_convert_l1;
  292. end;
  293. end;
  294. arraydef :
  295. begin
  296. { array of char to string, the length check is done by the firstpass of this node }
  297. if is_chararray(def_from) or
  298. (is_char(tarraydef(def_from).elementtype.def) and
  299. is_open_array(def_from)) then
  300. begin
  301. doconv:=tc_chararray_2_string;
  302. if is_open_array(def_from) or
  303. (is_shortstring(def_to) and
  304. (def_from.size <= 255)) or
  305. (is_ansistring(def_to) and
  306. (def_from.size > 255)) then
  307. eq:=te_convert_l1
  308. else
  309. eq:=te_convert_l2;
  310. end;
  311. end;
  312. pointerdef :
  313. begin
  314. { pchar can be assigned to short/ansistrings,
  315. but not in tp7 compatible mode }
  316. if not(m_tp7 in aktmodeswitches) then
  317. begin
  318. if is_pchar(def_from) then
  319. begin
  320. doconv:=tc_pchar_2_string;
  321. { prefer ansistrings because pchars can overflow shortstrings, }
  322. { but only if ansistrings are the default (JM) }
  323. if (is_shortstring(def_to) and
  324. not(cs_ansistrings in aktlocalswitches)) or
  325. (is_ansistring(def_to) and
  326. (cs_ansistrings in aktlocalswitches)) then
  327. eq:=te_convert_l1
  328. else
  329. eq:=te_convert_l2;
  330. end
  331. else if is_pwidechar(def_from) then
  332. begin
  333. doconv:=tc_pwchar_2_string;
  334. { prefer ansistrings because pchars can overflow shortstrings, }
  335. { but only if ansistrings are the default (JM) }
  336. if is_widestring(def_to) then
  337. eq:=te_convert_l1
  338. else
  339. eq:=te_convert_l3;
  340. end;
  341. end;
  342. end;
  343. end;
  344. end;
  345. floatdef :
  346. begin
  347. case def_from.deftype of
  348. orddef :
  349. begin { ordinal to real }
  350. if is_integer(def_from) or
  351. is_currency(def_from) then
  352. begin
  353. doconv:=tc_int_2_real;
  354. eq:=te_convert_l1;
  355. end;
  356. end;
  357. floatdef :
  358. begin
  359. if tfloatdef(def_from).typ=tfloatdef(def_to).typ then
  360. eq:=te_equal
  361. else
  362. begin
  363. doconv:=tc_real_2_real;
  364. eq:=te_convert_l1;
  365. end;
  366. end;
  367. end;
  368. end;
  369. enumdef :
  370. begin
  371. case def_from.deftype of
  372. enumdef :
  373. begin
  374. if explicit then
  375. begin
  376. eq:=te_convert_l1;
  377. doconv:=tc_int_2_int;
  378. end
  379. else
  380. begin
  381. hd1:=def_from;
  382. while assigned(tenumdef(hd1).basedef) do
  383. hd1:=tenumdef(hd1).basedef;
  384. hd2:=def_to;
  385. while assigned(tenumdef(hd2).basedef) do
  386. hd2:=tenumdef(hd2).basedef;
  387. if (hd1=hd2) then
  388. begin
  389. eq:=te_convert_l1;
  390. { because of packenum they can have different sizes! (JM) }
  391. doconv:=tc_int_2_int;
  392. end;
  393. end;
  394. end;
  395. orddef :
  396. begin
  397. if explicit then
  398. begin
  399. eq:=te_convert_l1;
  400. doconv:=tc_int_2_int;
  401. end;
  402. end;
  403. end;
  404. end;
  405. arraydef :
  406. begin
  407. { open array is also compatible with a single element of its base type }
  408. if is_open_array(def_to) and
  409. equal_defs(def_from,tarraydef(def_to).elementtype.def) then
  410. begin
  411. doconv:=tc_equal;
  412. eq:=te_convert_l1;
  413. end
  414. else
  415. begin
  416. case def_from.deftype of
  417. arraydef :
  418. begin
  419. { to dynamic array }
  420. if is_dynamic_array(def_to) then
  421. begin
  422. { dynamic array -> dynamic array }
  423. if is_dynamic_array(def_from) and
  424. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  425. eq:=te_equal;
  426. end
  427. else
  428. { to open array }
  429. if is_open_array(def_to) then
  430. begin
  431. { array constructor -> open array }
  432. if is_array_constructor(def_from) then
  433. begin
  434. if is_void(tarraydef(def_from).elementtype.def) then
  435. begin
  436. doconv:=tc_equal;
  437. eq:=te_convert_l1;
  438. end
  439. else
  440. begin
  441. subeq:=compare_defs_ext(tarraydef(def_from).elementtype.def,
  442. tarraydef(def_to).elementtype.def,
  443. arrayconstructorn,false,true,hct,hpd);
  444. if (subeq>=te_equal) then
  445. begin
  446. doconv:=tc_equal;
  447. eq:=te_convert_l1;
  448. end
  449. else
  450. if (subeq>te_incompatible) then
  451. begin
  452. doconv:=hct;
  453. eq:=te_convert_l2;
  454. end;
  455. end;
  456. end
  457. else
  458. { dynamic array -> open array }
  459. if is_dynamic_array(def_from) and
  460. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  461. begin
  462. doconv:=tc_dynarray_2_openarray;
  463. eq:=te_convert_l2;
  464. end
  465. else
  466. { array -> open array }
  467. if equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  468. eq:=te_equal;
  469. end
  470. else
  471. { to array of const }
  472. if is_array_of_const(def_to) then
  473. begin
  474. if is_array_of_const(def_from) or
  475. is_array_constructor(def_from) then
  476. begin
  477. eq:=te_equal;
  478. end
  479. else
  480. { array of tvarrec -> array of const }
  481. if equal_defs(tarraydef(def_to).elementtype.def,tarraydef(def_from).elementtype.def) then
  482. begin
  483. doconv:=tc_equal;
  484. eq:=te_convert_l1;
  485. end;
  486. end
  487. else
  488. { other arrays }
  489. begin
  490. { open array -> array }
  491. if is_open_array(def_from) and
  492. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  493. begin
  494. eq:=te_equal
  495. end
  496. else
  497. { array -> array }
  498. if not(m_tp7 in aktmodeswitches) and
  499. not(m_delphi in aktmodeswitches) and
  500. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  501. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  502. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) and
  503. equal_defs(tarraydef(def_from).rangetype.def,tarraydef(def_to).rangetype.def) then
  504. begin
  505. eq:=te_equal
  506. end;
  507. end;
  508. end;
  509. pointerdef :
  510. begin
  511. { nil is compatible with dyn. arrays }
  512. if is_dynamic_array(def_to) and
  513. (fromtreetype=niln) then
  514. begin
  515. doconv:=tc_equal;
  516. eq:=te_convert_l1;
  517. end
  518. else
  519. if is_zero_based_array(def_to) and
  520. equal_defs(tpointerdef(def_from).pointertype.def,tarraydef(def_to).elementtype.def) then
  521. begin
  522. doconv:=tc_pointer_2_array;
  523. eq:=te_convert_l1;
  524. end;
  525. end;
  526. stringdef :
  527. begin
  528. { string to char array }
  529. if (not is_special_array(def_to)) and
  530. is_char(tarraydef(def_to).elementtype.def) then
  531. begin
  532. doconv:=tc_string_2_chararray;
  533. eq:=te_convert_l1;
  534. end;
  535. end;
  536. orddef:
  537. begin
  538. if is_chararray(def_to) and
  539. is_char(def_from) then
  540. begin
  541. doconv:=tc_char_2_chararray;
  542. eq:=te_convert_l2;
  543. end;
  544. end;
  545. recorddef :
  546. begin
  547. { tvarrec -> array of const }
  548. if is_array_of_const(def_to) and
  549. equal_defs(def_from,tarraydef(def_to).elementtype.def) then
  550. begin
  551. doconv:=tc_equal;
  552. eq:=te_convert_l1;
  553. end;
  554. end;
  555. variantdef :
  556. begin
  557. if is_dynamic_array(def_to) then
  558. begin
  559. doconv:=tc_variant_2_dynarray;
  560. eq:=te_convert_l1;
  561. end;
  562. end;
  563. end;
  564. end;
  565. end;
  566. pointerdef :
  567. begin
  568. case def_from.deftype of
  569. stringdef :
  570. begin
  571. { string constant (which can be part of array constructor)
  572. to zero terminated string constant }
  573. if (fromtreetype in [arrayconstructorn,stringconstn]) and
  574. (is_pchar(def_to) or is_pwidechar(def_to)) then
  575. begin
  576. doconv:=tc_cstring_2_pchar;
  577. eq:=te_convert_l1;
  578. end
  579. else
  580. if explicit then
  581. begin
  582. { pchar(ansistring) }
  583. if is_pchar(def_to) and
  584. is_ansistring(def_from) then
  585. begin
  586. doconv:=tc_ansistring_2_pchar;
  587. eq:=te_convert_l1;
  588. end
  589. else
  590. { pwidechar(ansistring) }
  591. if is_pwidechar(def_to) and
  592. is_widestring(def_from) then
  593. begin
  594. doconv:=tc_ansistring_2_pchar;
  595. eq:=te_convert_l1;
  596. end;
  597. end;
  598. end;
  599. orddef :
  600. begin
  601. { char constant to zero terminated string constant }
  602. if (fromtreetype=ordconstn) then
  603. begin
  604. if is_char(def_from) and
  605. is_pchar(def_to) then
  606. begin
  607. doconv:=tc_cchar_2_pchar;
  608. eq:=te_convert_l1;
  609. end
  610. else
  611. if is_integer(def_from) then
  612. begin
  613. doconv:=tc_cord_2_pointer;
  614. eq:=te_convert_l1;
  615. end;
  616. end;
  617. if (eq=te_incompatible) and
  618. explicit and
  619. (m_delphi in aktmodeswitches) then
  620. begin
  621. doconv:=tc_int_2_int;
  622. eq:=te_convert_l1;
  623. end;
  624. end;
  625. arraydef :
  626. begin
  627. { chararray to pointer }
  628. if is_zero_based_array(def_from) and
  629. equal_defs(tarraydef(def_from).elementtype.def,tpointerdef(def_to).pointertype.def) then
  630. begin
  631. doconv:=tc_array_2_pointer;
  632. eq:=te_convert_l1;
  633. end;
  634. end;
  635. pointerdef :
  636. begin
  637. { check for far pointers }
  638. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  639. begin
  640. eq:=te_incompatible;
  641. end
  642. else
  643. { the types can be forward type, handle before normal type check !! }
  644. if assigned(def_to.typesym) and
  645. (tpointerdef(def_to).pointertype.def.deftype=forwarddef) then
  646. begin
  647. if (def_from.typesym=def_to.typesym) then
  648. eq:=te_equal
  649. end
  650. else
  651. { same types }
  652. if (tpointerdef(def_from).pointertype.def=tpointerdef(def_to).pointertype.def) then
  653. begin
  654. eq:=te_equal
  655. end
  656. else
  657. { child class pointer can be assigned to anchestor pointers }
  658. if (
  659. (tpointerdef(def_from).pointertype.def.deftype=objectdef) and
  660. (tpointerdef(def_to).pointertype.def.deftype=objectdef) and
  661. tobjectdef(tpointerdef(def_from).pointertype.def).is_related(
  662. tobjectdef(tpointerdef(def_to).pointertype.def))
  663. ) or
  664. { all pointers can be assigned to/from void-pointer }
  665. is_void(tpointerdef(def_to).pointertype.def) or
  666. is_void(tpointerdef(def_from).pointertype.def) then
  667. begin
  668. doconv:=tc_equal;
  669. { give pwidechar a penalty }
  670. if is_pwidechar(def_to) then
  671. eq:=te_convert_l2
  672. else
  673. eq:=te_convert_l1;
  674. end;
  675. end;
  676. procvardef :
  677. begin
  678. { procedure variable can be assigned to an void pointer }
  679. { Not anymore. Use the @ operator now.}
  680. if not(m_tp_procvar in aktmodeswitches) and
  681. (tpointerdef(def_to).pointertype.def.deftype=orddef) and
  682. (torddef(tpointerdef(def_to).pointertype.def).typ=uvoid) then
  683. begin
  684. doconv:=tc_equal;
  685. eq:=te_convert_l1;
  686. end;
  687. end;
  688. classrefdef,
  689. objectdef :
  690. begin
  691. { class types and class reference type
  692. can be assigned to void pointers }
  693. if (
  694. is_class_or_interface(def_from) or
  695. (def_from.deftype=classrefdef)
  696. ) and
  697. (tpointerdef(def_to).pointertype.def.deftype=orddef) and
  698. (torddef(tpointerdef(def_to).pointertype.def).typ=uvoid) then
  699. begin
  700. doconv:=tc_equal;
  701. eq:=te_convert_l1;
  702. end;
  703. end;
  704. end;
  705. end;
  706. setdef :
  707. begin
  708. case def_from.deftype of
  709. setdef :
  710. begin
  711. if assigned(tsetdef(def_from).elementtype.def) and
  712. assigned(tsetdef(def_to).elementtype.def) then
  713. begin
  714. { sets with the same element base type are equal }
  715. if is_subequal(tsetdef(def_from).elementtype.def,tsetdef(def_to).elementtype.def) then
  716. eq:=te_equal;
  717. end
  718. else
  719. { empty set is compatible with everything }
  720. eq:=te_equal;
  721. end;
  722. arraydef :
  723. begin
  724. { automatic arrayconstructor -> set conversion }
  725. if is_array_constructor(def_from) then
  726. begin
  727. doconv:=tc_arrayconstructor_2_set;
  728. eq:=te_convert_l1;
  729. end;
  730. end;
  731. end;
  732. end;
  733. procvardef :
  734. begin
  735. case def_from.deftype of
  736. procdef :
  737. begin
  738. { proc -> procvar }
  739. if (m_tp_procvar in aktmodeswitches) then
  740. begin
  741. subeq:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to),true);
  742. if subeq>te_incompatible then
  743. begin
  744. doconv:=tc_proc_2_procvar;
  745. eq:=te_convert_l1;
  746. end;
  747. end;
  748. end;
  749. procvardef :
  750. begin
  751. { procvar -> procvar }
  752. eq:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to),true);
  753. end;
  754. pointerdef :
  755. begin
  756. { nil is compatible with procvars }
  757. if (fromtreetype=niln) then
  758. begin
  759. doconv:=tc_equal;
  760. eq:=te_convert_l1;
  761. end
  762. else
  763. { for example delphi allows the assignement from pointers }
  764. { to procedure variables }
  765. if (m_pointer_2_procedure in aktmodeswitches) and
  766. (tpointerdef(def_from).pointertype.def.deftype=orddef) and
  767. (torddef(tpointerdef(def_from).pointertype.def).typ=uvoid) then
  768. begin
  769. doconv:=tc_equal;
  770. eq:=te_convert_l1;
  771. end;
  772. end;
  773. end;
  774. end;
  775. objectdef :
  776. begin
  777. { object pascal objects }
  778. if (def_from.deftype=objectdef) and
  779. tobjectdef(def_from).is_related(tobjectdef(def_to)) then
  780. begin
  781. doconv:=tc_equal;
  782. eq:=te_convert_l1;
  783. end
  784. else
  785. { Class/interface specific }
  786. if is_class_or_interface(def_to) then
  787. begin
  788. { void pointer also for delphi mode }
  789. if (m_delphi in aktmodeswitches) and
  790. is_voidpointer(def_from) then
  791. begin
  792. doconv:=tc_equal;
  793. eq:=te_convert_l1;
  794. end
  795. else
  796. { nil is compatible with class instances and interfaces }
  797. if (fromtreetype=niln) then
  798. begin
  799. doconv:=tc_equal;
  800. eq:=te_convert_l1;
  801. end
  802. { classes can be assigned to interfaces }
  803. else if is_interface(def_to) and
  804. is_class(def_from) and
  805. assigned(tobjectdef(def_from).implementedinterfaces) then
  806. begin
  807. { we've to search in parent classes as well }
  808. hd3:=tobjectdef(def_from);
  809. while assigned(hd3) do
  810. begin
  811. if hd3.implementedinterfaces.searchintf(def_to)<>-1 then
  812. begin
  813. doconv:=tc_class_2_intf;
  814. eq:=te_convert_l1;
  815. break;
  816. end;
  817. hd3:=hd3.childof;
  818. end;
  819. end
  820. { Interface 2 GUID handling }
  821. else if (def_to=tdef(rec_tguid)) and
  822. (fromtreetype=typen) and
  823. is_interface(def_from) and
  824. assigned(tobjectdef(def_from).iidguid) then
  825. begin
  826. eq:=te_convert_l1;
  827. doconv:=tc_equal;
  828. end;
  829. end;
  830. end;
  831. classrefdef :
  832. begin
  833. { similar to pointerdef wrt forwards }
  834. if assigned(def_to.typesym) and
  835. (tclassrefdef(def_to).pointertype.def.deftype=forwarddef) then
  836. begin
  837. if (def_from.typesym=def_to.typesym) then
  838. eq:=te_equal;
  839. end
  840. else
  841. { class reference types }
  842. if (def_from.deftype=classrefdef) then
  843. begin
  844. if equal_defs(tclassrefdef(def_from).pointertype.def,tclassrefdef(def_to).pointertype.def) then
  845. begin
  846. eq:=te_equal;
  847. end
  848. else
  849. begin
  850. doconv:=tc_equal;
  851. if explicit or
  852. tobjectdef(tclassrefdef(def_from).pointertype.def).is_related(
  853. tobjectdef(tclassrefdef(def_to).pointertype.def)) then
  854. eq:=te_convert_l1;
  855. end;
  856. end
  857. else
  858. { nil is compatible with class references }
  859. if (fromtreetype=niln) then
  860. begin
  861. doconv:=tc_equal;
  862. eq:=te_convert_l1;
  863. end;
  864. end;
  865. filedef :
  866. begin
  867. { typed files are all equal to the abstract file type
  868. name TYPEDFILE in system.pp in is_equal in types.pas
  869. the problem is that it sholud be also compatible to FILE
  870. but this would leed to a problem for ASSIGN RESET and REWRITE
  871. when trying to find the good overloaded function !!
  872. so all file function are doubled in system.pp
  873. this is not very beautiful !!}
  874. if (def_from.deftype=filedef) then
  875. begin
  876. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  877. begin
  878. if
  879. (
  880. (tfiledef(def_from).typedfiletype.def=nil) and
  881. (tfiledef(def_to).typedfiletype.def=nil)
  882. ) or
  883. (
  884. (tfiledef(def_from).typedfiletype.def<>nil) and
  885. (tfiledef(def_to).typedfiletype.def<>nil) and
  886. equal_defs(tfiledef(def_from).typedfiletype.def,tfiledef(def_to).typedfiletype.def)
  887. ) or
  888. (
  889. (tfiledef(def_from).filetyp = ft_typed) and
  890. (tfiledef(def_to).filetyp = ft_typed) and
  891. (
  892. (tfiledef(def_from).typedfiletype.def = tdef(voidtype.def)) or
  893. (tfiledef(def_to).typedfiletype.def = tdef(voidtype.def))
  894. )
  895. ) then
  896. begin
  897. eq:=te_equal;
  898. end;
  899. end
  900. else
  901. if ((tfiledef(def_from).filetyp = ft_untyped) and
  902. (tfiledef(def_to).filetyp = ft_typed)) or
  903. ((tfiledef(def_from).filetyp = ft_typed) and
  904. (tfiledef(def_to).filetyp = ft_untyped)) then
  905. begin
  906. doconv:=tc_equal;
  907. eq:=te_convert_l1;
  908. end;
  909. end;
  910. end;
  911. recorddef :
  912. begin
  913. { interface -> guid }
  914. if is_interface(def_from) and
  915. (def_to=rec_tguid) then
  916. begin
  917. doconv:=tc_intf_2_guid;
  918. eq:=te_convert_l1;
  919. end;
  920. end;
  921. formaldef :
  922. begin
  923. doconv:=tc_equal;
  924. if (def_from.deftype=formaldef) then
  925. eq:=te_equal
  926. else
  927. { Just about everything can be converted to a formaldef...}
  928. if not (def_from.deftype in [abstractdef,errordef]) then
  929. eq:=te_convert_l1;
  930. end;
  931. end;
  932. { if we didn't find an appropriate type conversion yet and
  933. there is a variant involved then we search also the := operator }
  934. if (eq=te_incompatible) and
  935. check_operator and
  936. ((def_from.deftype in [objectdef,recorddef,arraydef,stringdef,variantdef]) or
  937. (def_to.deftype in [objectdef,recorddef,arraydef,stringdef,variantdef])) then
  938. begin
  939. operatorpd:=assignment_overloaded(def_from,def_to);
  940. if assigned(operatorpd) then
  941. eq:=te_convert_operator;
  942. end;
  943. { update convtype for te_equal when it is not yet set }
  944. if (eq=te_equal) and
  945. (doconv=tc_not_possible) then
  946. doconv:=tc_equal;
  947. compare_defs_ext:=eq;
  948. end;
  949. function equal_defs(def_from,def_to:tdef):boolean;
  950. var
  951. convtyp : tconverttype;
  952. pd : tprocdef;
  953. begin
  954. { Compare defs with nothingn and no explicit typecasts and
  955. searching for overloaded operators is not needed }
  956. equal_defs:=(compare_defs_ext(def_from,def_to,nothingn,false,false,convtyp,pd)>=te_equal);
  957. end;
  958. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  959. var
  960. doconv : tconverttype;
  961. pd : tprocdef;
  962. begin
  963. compare_defs:=compare_defs_ext(def_from,def_to,fromtreetype,false,true,doconv,pd);
  964. end;
  965. function is_subequal(def1, def2: tdef): boolean;
  966. var
  967. basedef1,basedef2 : tenumdef;
  968. Begin
  969. is_subequal := false;
  970. if assigned(def1) and assigned(def2) then
  971. Begin
  972. if (def1.deftype = orddef) and (def2.deftype = orddef) then
  973. Begin
  974. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  975. { range checking for case statements is done with testrange }
  976. case torddef(def1).typ of
  977. u8bit,u16bit,u32bit,u64bit,
  978. s8bit,s16bit,s32bit,s64bit :
  979. is_subequal:=(torddef(def2).typ in [s64bit,u64bit,s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  980. bool8bit,bool16bit,bool32bit :
  981. is_subequal:=(torddef(def2).typ in [bool8bit,bool16bit,bool32bit]);
  982. uchar :
  983. is_subequal:=(torddef(def2).typ=uchar);
  984. uwidechar :
  985. is_subequal:=(torddef(def2).typ=uwidechar);
  986. end;
  987. end
  988. else
  989. Begin
  990. { Check if both basedefs are equal }
  991. if (def1.deftype=enumdef) and (def2.deftype=enumdef) then
  992. Begin
  993. { get both basedefs }
  994. basedef1:=tenumdef(def1);
  995. while assigned(basedef1.basedef) do
  996. basedef1:=basedef1.basedef;
  997. basedef2:=tenumdef(def2);
  998. while assigned(basedef2.basedef) do
  999. basedef2:=basedef2.basedef;
  1000. is_subequal:=(basedef1=basedef2);
  1001. end;
  1002. end;
  1003. end;
  1004. end;
  1005. function compare_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean):tequaltype;
  1006. var
  1007. currpara1,
  1008. currpara2 : TParaItem;
  1009. eq,lowesteq : tequaltype;
  1010. hpd : tprocdef;
  1011. convtype : tconverttype;
  1012. begin
  1013. compare_paras:=te_incompatible;
  1014. { we need to parse the list from left-right so the
  1015. not-default parameters are checked first }
  1016. lowesteq:=high(tequaltype);
  1017. currpara1:=TParaItem(paralist1.first);
  1018. currpara2:=TParaItem(paralist2.first);
  1019. while (assigned(currpara1)) and (assigned(currpara2)) do
  1020. begin
  1021. eq:=te_incompatible;
  1022. { Unique types must match exact }
  1023. if ((df_unique in currpara1.paratype.def.defoptions) or (df_unique in currpara2.paratype.def.defoptions)) and
  1024. (currpara1.paratype.def<>currpara2.paratype.def) then
  1025. exit;
  1026. { Handle hidden parameters separately, because self is
  1027. defined as voidpointer for methodpointers }
  1028. if (currpara1.is_hidden or
  1029. currpara2.is_hidden) then
  1030. begin
  1031. eq:=te_equal;
  1032. if not(vo_is_self in tvarsym(currpara1.parasym).varoptions) and
  1033. not(vo_is_self in tvarsym(currpara2.parasym).varoptions) then
  1034. begin
  1035. if (currpara1.paratyp<>currpara2.paratyp) then
  1036. exit;
  1037. eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
  1038. end;
  1039. end
  1040. else
  1041. begin
  1042. case acp of
  1043. cp_value_equal_const :
  1044. begin
  1045. if (
  1046. (currpara1.paratyp<>currpara2.paratyp) and
  1047. ((currpara1.paratyp in [vs_var,vs_out]) or
  1048. (currpara2.paratyp in [vs_var,vs_out]))
  1049. ) then
  1050. exit;
  1051. eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
  1052. end;
  1053. cp_all :
  1054. begin
  1055. if (currpara1.paratyp<>currpara2.paratyp) then
  1056. exit;
  1057. eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
  1058. end;
  1059. cp_procvar :
  1060. begin
  1061. if (currpara1.paratyp<>currpara2.paratyp) then
  1062. exit;
  1063. eq:=compare_defs_ext(currpara1.paratype.def,currpara2.paratype.def,nothingn,
  1064. false,true,convtype,hpd);
  1065. if (eq>te_incompatible) and
  1066. (eq<te_equal) and
  1067. not(
  1068. (convtype in [tc_equal,tc_int_2_int]) and
  1069. (currpara1.paratype.def.size=currpara2.paratype.def.size)
  1070. ) then
  1071. begin
  1072. eq:=te_incompatible;
  1073. end;
  1074. end;
  1075. else
  1076. eq:=compare_defs(currpara1.paratype.def,currpara2.paratype.def,nothingn);
  1077. end;
  1078. end;
  1079. { check type }
  1080. if eq=te_incompatible then
  1081. exit;
  1082. if eq<lowesteq then
  1083. lowesteq:=eq;
  1084. { also check default value if both have it declared }
  1085. if assigned(currpara1.defaultvalue) and
  1086. assigned(currpara2.defaultvalue) then
  1087. begin
  1088. if not equal_constsym(tconstsym(currpara1.defaultvalue),tconstsym(currpara2.defaultvalue)) then
  1089. exit;
  1090. end;
  1091. currpara1:=TParaItem(currpara1.next);
  1092. currpara2:=TParaItem(currpara2.next);
  1093. end;
  1094. { when both lists are empty then the parameters are equal. Also
  1095. when one list is empty and the other has a parameter with default
  1096. value assigned then the parameters are also equal }
  1097. if ((currpara1=nil) and (currpara2=nil)) or
  1098. (allowdefaults and
  1099. ((assigned(currpara1) and assigned(currpara1.defaultvalue)) or
  1100. (assigned(currpara2) and assigned(currpara2.defaultvalue)))) then
  1101. compare_paras:=lowesteq;
  1102. end;
  1103. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef;methoderr:boolean):tequaltype;
  1104. var
  1105. eq : tequaltype;
  1106. po_comp : tprocoptions;
  1107. begin
  1108. proc_to_procvar_equal:=te_incompatible;
  1109. if not(assigned(def1)) or not(assigned(def2)) then
  1110. exit;
  1111. { check for method pointer }
  1112. if (def1.is_methodpointer xor def2.is_methodpointer) or
  1113. (def1.is_addressonly xor def2.is_addressonly) then
  1114. begin
  1115. if methoderr then
  1116. Message(type_e_no_method_and_procedure_not_compatible);
  1117. exit;
  1118. end;
  1119. { check return value and options, methodpointer is already checked }
  1120. po_comp:=[po_staticmethod,po_containsself,po_interrupt,
  1121. po_iocheck,po_varargs];
  1122. if (m_delphi in aktmodeswitches) then
  1123. exclude(po_comp,po_varargs);
  1124. if ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1125. equal_defs(def1.rettype.def,def2.rettype.def) and
  1126. (def1.para_size(target_info.alignment.paraalign)=def2.para_size(target_info.alignment.paraalign)) then
  1127. begin
  1128. { return equal type based on the parameters, but a proc->procvar
  1129. is never exact, so map an exact match of the parameters to
  1130. te_equal }
  1131. eq:=compare_paras(def1.para,def2.para,cp_procvar,false);
  1132. if eq=te_exact then
  1133. eq:=te_equal;
  1134. proc_to_procvar_equal:=eq;
  1135. end;
  1136. end;
  1137. function is_equal(def1,def2 : tdef) : boolean;
  1138. var
  1139. doconv : tconverttype;
  1140. hpd : tprocdef;
  1141. begin
  1142. is_equal:=(compare_defs_ext(def1,def2,nothingn,false,true,doconv,hpd)>=te_equal);
  1143. end;
  1144. function equal_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean) : boolean;
  1145. begin
  1146. equal_paras:=(compare_paras(paralist1,paralist2,acp,allowdefaults)>=te_equal);
  1147. end;
  1148. end.
  1149. {
  1150. $Log$
  1151. Revision 1.24 2003-05-09 17:47:02 peter
  1152. * self moved to hidden parameter
  1153. * removed hdisposen,hnewn,selfn
  1154. Revision 1.23 2003/04/23 20:16:04 peter
  1155. + added currency support based on int64
  1156. + is_64bit for use in cg units instead of is_64bitint
  1157. * removed cgmessage from n386add, replace with internalerrors
  1158. Revision 1.22 2003/04/23 11:37:33 peter
  1159. * po_comp for proc to procvar fixed
  1160. Revision 1.21 2003/04/10 17:57:52 peter
  1161. * vs_hidden released
  1162. Revision 1.20 2003/03/20 17:52:18 peter
  1163. * fix compare for unique types, they are allowed when they match
  1164. exact
  1165. Revision 1.19 2003/01/16 22:13:51 peter
  1166. * convert_l3 convertlevel added. This level is used for conversions
  1167. where information can be lost like converting widestring->ansistring
  1168. or dword->byte
  1169. Revision 1.18 2003/01/15 01:44:32 peter
  1170. * merged methodpointer fixes from 1.0.x
  1171. Revision 1.17 2003/01/09 21:43:39 peter
  1172. * constant string conversion fixed, it's now equal to both
  1173. shortstring, ansistring and the typeconvnode will return
  1174. te_equal but still return convtype to change the constnode
  1175. Revision 1.16 2003/01/05 22:42:13 peter
  1176. * use int_to_int conversion for pointer/procvar/classref to int
  1177. Revision 1.15 2003/01/05 15:54:15 florian
  1178. + added proper support of type = type <type>; for simple types
  1179. Revision 1.14 2003/01/03 17:16:04 peter
  1180. * fixed assignment operator checking for typecast
  1181. Revision 1.13 2002/12/29 18:15:19 peter
  1182. * varargs is not checked in proc->procvar for delphi
  1183. Revision 1.12 2002/12/29 14:57:50 peter
  1184. * unit loading changed to first register units and load them
  1185. afterwards. This is needed to support uses xxx in yyy correctly
  1186. * unit dependency check fixed
  1187. Revision 1.11 2002/12/27 15:26:12 peter
  1188. * procvar compare with 2 ints did not check the integer size
  1189. Revision 1.10 2002/12/23 22:22:16 peter
  1190. * don't allow implicit bool->int conversion
  1191. Revision 1.9 2002/12/18 21:37:36 peter
  1192. * allow classref-classref always when explicit
  1193. Revision 1.8 2002/12/15 22:37:53 peter
  1194. * give conversions from pointer to pwidechar a penalty (=prefer pchar)
  1195. Revision 1.7 2002/12/11 22:40:12 peter
  1196. * proc->procvar is never an exact match, convert exact parameters
  1197. to equal for the whole proc to procvar conversion level
  1198. Revision 1.6 2002/12/06 17:49:44 peter
  1199. * prefer string-shortstring over other string-string conversions
  1200. Revision 1.5 2002/12/05 14:27:26 florian
  1201. * some variant <-> dyn. array stuff
  1202. Revision 1.4 2002/12/01 22:07:41 carl
  1203. * warning of portabilitiy problems with parasize / localsize
  1204. + some added documentation
  1205. Revision 1.3 2002/11/27 15:33:46 peter
  1206. * the never ending story of tp procvar hacks
  1207. Revision 1.2 2002/11/27 02:32:14 peter
  1208. * fix cp_procvar compare
  1209. Revision 1.1 2002/11/25 17:43:16 peter
  1210. * splitted defbase in defutil,symutil,defcmp
  1211. * merged isconvertable and is_equal into compare_defs(_ext)
  1212. * made operator search faster by walking the list only once
  1213. }