defcmp.pas 49 KB

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