defcmp.pas 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Compare definitions and parameter lists
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit defcmp;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,
  22. globtype,globals,
  23. node,
  24. symconst,symtype,symdef;
  25. type
  26. { if acp is cp_all the var const or nothing are considered equal }
  27. tcompare_paras_type = ( cp_none, cp_value_equal_const, cp_all,cp_procvar);
  28. tcompare_paras_option = (cpo_allowdefaults,cpo_ignorehidden,cpo_allowconvert,cpo_comparedefaultvalue);
  29. tcompare_paras_options = set of tcompare_paras_option;
  30. tcompare_defs_option = (cdo_internal,cdo_explicit,cdo_check_operator,cdo_allow_variant,cdo_parameter);
  31. tcompare_defs_options = set of tcompare_defs_option;
  32. tconverttype = (tc_none,
  33. tc_equal,
  34. tc_not_possible,
  35. tc_string_2_string,
  36. tc_char_2_string,
  37. tc_char_2_chararray,
  38. tc_pchar_2_string,
  39. tc_cchar_2_pchar,
  40. tc_cstring_2_pchar,
  41. tc_cstring_2_int,
  42. tc_ansistring_2_pchar,
  43. tc_string_2_chararray,
  44. tc_chararray_2_string,
  45. tc_array_2_pointer,
  46. tc_pointer_2_array,
  47. tc_int_2_int,
  48. tc_int_2_bool,
  49. tc_bool_2_bool,
  50. tc_bool_2_int,
  51. tc_real_2_real,
  52. tc_int_2_real,
  53. tc_real_2_currency,
  54. tc_proc_2_procvar,
  55. tc_arrayconstructor_2_set,
  56. tc_set_to_set,
  57. tc_cord_2_pointer,
  58. tc_intf_2_string,
  59. tc_intf_2_guid,
  60. tc_class_2_intf,
  61. tc_char_2_char,
  62. tc_dynarray_2_openarray,
  63. tc_pwchar_2_string,
  64. tc_variant_2_dynarray,
  65. tc_dynarray_2_variant,
  66. tc_variant_2_enum,
  67. tc_enum_2_variant,
  68. tc_interface_2_variant,
  69. tc_variant_2_interface,
  70. tc_array_2_dynarray
  71. );
  72. function compare_defs_ext(def_from,def_to : tdef;
  73. fromtreetype : tnodetype;
  74. var doconv : tconverttype;
  75. var operatorpd : tprocdef;
  76. cdoptions:tcompare_defs_options):tequaltype;
  77. { Returns if the type def_from can be converted to def_to or if both types are equal }
  78. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  79. { Returns true, if def1 and def2 are semantically the same }
  80. function equal_defs(def_from,def_to:tdef):boolean;
  81. { Checks for type compatibility (subgroups of type)
  82. used for case statements... probably missing stuff
  83. to use on other types }
  84. function is_subequal(def1, def2: tdef): boolean;
  85. {# true, if two parameter lists are equal
  86. if acp is cp_none, all have to match exactly
  87. if acp is cp_value_equal_const call by value
  88. and call by const parameter are assumed as
  89. equal
  90. allowdefaults indicates if default value parameters
  91. are allowed (in this case, the search order will first
  92. search for a routine with default parameters, before
  93. searching for the same definition with no parameters)
  94. }
  95. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  96. { True if a function can be assigned to a procvar }
  97. { changed first argument type to pabstractprocdef so that it can also be }
  98. { used to test compatibility between two pprocvardefs (JM) }
  99. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  100. { Parentdef is the definition of a method defined in a parent class or interface }
  101. { Childdef is the definition of a method defined in a child class, interface or }
  102. { a class implementing an interface with parentdef. }
  103. { Returns true if the resultdef of childdef can be used to implement/override }
  104. { parentdef's resultdef }
  105. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  106. implementation
  107. uses
  108. verbose,systems,constexp,
  109. symtable,symsym,
  110. defutil,symutil;
  111. function compare_defs_ext(def_from,def_to : tdef;
  112. fromtreetype : tnodetype;
  113. var doconv : tconverttype;
  114. var operatorpd : tprocdef;
  115. cdoptions:tcompare_defs_options):tequaltype;
  116. { tordtype:
  117. uvoid,
  118. u8bit,u16bit,u32bit,u64bit,
  119. s8bit,s16bit,s32bit,s64bit,
  120. bool8bit,bool16bit,bool32bit,bool64bit,
  121. uchar,uwidechar }
  122. type
  123. tbasedef=(bvoid,bchar,bint,bbool);
  124. const
  125. basedeftbl:array[tordtype] of tbasedef =
  126. (bvoid,
  127. bint,bint,bint,bint,
  128. bint,bint,bint,bint,
  129. bbool,bbool,bbool,bbool,
  130. bchar,bchar,bint);
  131. basedefconvertsimplicit : array[tbasedef,tbasedef] of tconverttype =
  132. { void, char, int, bool }
  133. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  134. (tc_not_possible,tc_char_2_char,tc_not_possible,tc_not_possible),
  135. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_not_possible),
  136. (tc_not_possible,tc_not_possible,tc_not_possible,tc_bool_2_bool));
  137. basedefconvertsexplicit : array[tbasedef,tbasedef] of tconverttype =
  138. { void, char, int, bool }
  139. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  140. (tc_not_possible,tc_char_2_char,tc_int_2_int,tc_int_2_bool),
  141. (tc_not_possible,tc_int_2_int,tc_int_2_int,tc_int_2_bool),
  142. (tc_not_possible,tc_bool_2_int,tc_bool_2_int,tc_bool_2_bool));
  143. var
  144. subeq,eq : tequaltype;
  145. hd1,hd2 : tdef;
  146. hct : tconverttype;
  147. hobjdef : tobjectdef;
  148. hpd : tprocdef;
  149. begin
  150. eq:=te_incompatible;
  151. doconv:=tc_not_possible;
  152. { safety check }
  153. if not(assigned(def_from) and assigned(def_to)) then
  154. begin
  155. compare_defs_ext:=te_incompatible;
  156. exit;
  157. end;
  158. { same def? then we've an exact match }
  159. if def_from=def_to then
  160. begin
  161. doconv:=tc_equal;
  162. compare_defs_ext:=te_exact;
  163. exit;
  164. end;
  165. { undefined def? then mark it as equal }
  166. if (def_from.typ=undefineddef) or
  167. (def_to.typ=undefineddef) then
  168. begin
  169. doconv:=tc_equal;
  170. compare_defs_ext:=te_equal;
  171. exit;
  172. end;
  173. { undefined def? then mark it as equal }
  174. if (def_from.typ=undefineddef) or
  175. (def_to.typ=undefineddef) then
  176. begin
  177. doconv:=tc_equal;
  178. compare_defs_ext:=te_equal;
  179. exit;
  180. end;
  181. { we walk the wanted (def_to) types and check then the def_from
  182. types if there is a conversion possible }
  183. case def_to.typ of
  184. orddef :
  185. begin
  186. case def_from.typ of
  187. orddef :
  188. begin
  189. if (torddef(def_from).ordtype=torddef(def_to).ordtype) then
  190. begin
  191. case torddef(def_from).ordtype of
  192. uchar,uwidechar,
  193. u8bit,u16bit,u32bit,u64bit,
  194. s8bit,s16bit,s32bit,s64bit:
  195. begin
  196. if (torddef(def_from).low>=torddef(def_to).low) and
  197. (torddef(def_from).high<=torddef(def_to).high) then
  198. eq:=te_equal
  199. else
  200. begin
  201. doconv:=tc_int_2_int;
  202. eq:=te_convert_l1;
  203. end;
  204. end;
  205. uvoid,
  206. bool8bit,bool16bit,bool32bit,bool64bit:
  207. eq:=te_equal;
  208. else
  209. internalerror(200210061);
  210. end;
  211. end
  212. else
  213. begin
  214. if cdo_explicit in cdoptions then
  215. doconv:=basedefconvertsexplicit[basedeftbl[torddef(def_from).ordtype],basedeftbl[torddef(def_to).ordtype]]
  216. else
  217. doconv:=basedefconvertsimplicit[basedeftbl[torddef(def_from).ordtype],basedeftbl[torddef(def_to).ordtype]];
  218. if (doconv=tc_not_possible) then
  219. eq:=te_incompatible
  220. else
  221. { "punish" bad type conversions :) (JM) }
  222. if (not is_in_limit(def_from,def_to)) and
  223. (def_from.size > def_to.size) then
  224. eq:=te_convert_l3
  225. else
  226. eq:=te_convert_l1;
  227. end;
  228. end;
  229. enumdef :
  230. begin
  231. { needed for char(enum) }
  232. if cdo_explicit in cdoptions then
  233. begin
  234. doconv:=tc_int_2_int;
  235. eq:=te_convert_l1;
  236. end;
  237. end;
  238. floatdef :
  239. begin
  240. if is_currency(def_to) then
  241. begin
  242. doconv:=tc_real_2_currency;
  243. eq:=te_convert_l2;
  244. end;
  245. end;
  246. objectdef:
  247. begin
  248. if is_class_or_interface_or_dispinterface(def_from) and (cdo_explicit in cdoptions) then
  249. begin
  250. eq:=te_convert_l1;
  251. if (fromtreetype=niln) then
  252. begin
  253. { will be handled by the constant folding }
  254. doconv:=tc_equal;
  255. end
  256. else
  257. doconv:=tc_int_2_int;
  258. end;
  259. end;
  260. classrefdef,
  261. procvardef,
  262. pointerdef :
  263. begin
  264. if cdo_explicit in cdoptions then
  265. begin
  266. eq:=te_convert_l1;
  267. if (fromtreetype=niln) then
  268. begin
  269. { will be handled by the constant folding }
  270. doconv:=tc_equal;
  271. end
  272. else
  273. doconv:=tc_int_2_int;
  274. end;
  275. end;
  276. arraydef :
  277. begin
  278. if (m_mac in current_settings.modeswitches) and
  279. (fromtreetype=stringconstn) then
  280. begin
  281. eq:=te_convert_l3;
  282. doconv:=tc_cstring_2_int;
  283. end;
  284. end;
  285. end;
  286. end;
  287. stringdef :
  288. begin
  289. case def_from.typ of
  290. stringdef :
  291. begin
  292. { Constant string }
  293. if (fromtreetype=stringconstn) then
  294. begin
  295. if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) then
  296. eq:=te_equal
  297. else
  298. begin
  299. doconv:=tc_string_2_string;
  300. { Don't prefer conversions from widestring to a
  301. normal string as we can loose information }
  302. if tstringdef(def_from).stringtype=st_widestring then
  303. eq:=te_convert_l3
  304. else if tstringdef(def_to).stringtype=st_widestring then
  305. eq:=te_convert_l2
  306. else
  307. eq:=te_equal;
  308. end;
  309. end
  310. else
  311. { Same string type, for shortstrings also the length must match }
  312. if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) and
  313. ((tstringdef(def_from).stringtype<>st_shortstring) or
  314. (tstringdef(def_from).len=tstringdef(def_to).len)) then
  315. eq:=te_equal
  316. else
  317. begin
  318. doconv:=tc_string_2_string;
  319. case tstringdef(def_from).stringtype of
  320. st_widestring :
  321. begin
  322. { Prefer conversions to ansistring }
  323. if tstringdef(def_to).stringtype=st_ansistring then
  324. eq:=te_convert_l2
  325. else
  326. eq:=te_convert_l3;
  327. end;
  328. st_shortstring :
  329. begin
  330. { Prefer shortstrings of different length or conversions
  331. from shortstring to ansistring }
  332. if (tstringdef(def_to).stringtype=st_shortstring) then
  333. eq:=te_convert_l1
  334. else if tstringdef(def_to).stringtype=st_ansistring then
  335. eq:=te_convert_l2
  336. else
  337. eq:=te_convert_l3;
  338. end;
  339. st_ansistring :
  340. begin
  341. { Prefer conversion to widestrings }
  342. if (tstringdef(def_to).stringtype=st_widestring) then
  343. eq:=te_convert_l2
  344. else
  345. eq:=te_convert_l3;
  346. end;
  347. end;
  348. end;
  349. end;
  350. orddef :
  351. begin
  352. { char to string}
  353. if is_char(def_from) or
  354. is_widechar(def_from) then
  355. begin
  356. doconv:=tc_char_2_string;
  357. eq:=te_convert_l1;
  358. end;
  359. end;
  360. arraydef :
  361. begin
  362. { array of char to string, the length check is done by the firstpass of this node }
  363. if is_chararray(def_from) or is_open_chararray(def_from) then
  364. begin
  365. { "Untyped" stringconstn is an array of char }
  366. if fromtreetype=stringconstn then
  367. begin
  368. doconv:=tc_string_2_string;
  369. { prefered string type depends on the $H switch }
  370. if not(cs_ansistrings in current_settings.localswitches) and
  371. (tstringdef(def_to).stringtype=st_shortstring) then
  372. eq:=te_equal
  373. else if (cs_ansistrings in current_settings.localswitches) and
  374. (tstringdef(def_to).stringtype=st_ansistring) then
  375. eq:=te_equal
  376. else if tstringdef(def_to).stringtype=st_widestring then
  377. eq:=te_convert_l3
  378. else
  379. eq:=te_convert_l1;
  380. end
  381. else
  382. begin
  383. doconv:=tc_chararray_2_string;
  384. if is_open_array(def_from) then
  385. begin
  386. if is_ansistring(def_to) then
  387. eq:=te_convert_l1
  388. else if is_widestring(def_to) then
  389. eq:=te_convert_l3
  390. else
  391. eq:=te_convert_l2;
  392. end
  393. else
  394. begin
  395. if is_shortstring(def_to) then
  396. begin
  397. { Only compatible with arrays that fit
  398. smaller than 255 chars }
  399. if (def_from.size <= 255) then
  400. eq:=te_convert_l1;
  401. end
  402. else if is_ansistring(def_to) then
  403. begin
  404. if (def_from.size > 255) then
  405. eq:=te_convert_l1
  406. else
  407. eq:=te_convert_l2;
  408. end
  409. else if is_widestring(def_to) then
  410. eq:=te_convert_l3
  411. else
  412. eq:=te_convert_l2;
  413. end;
  414. end;
  415. end
  416. else
  417. { array of widechar to string, the length check is done by the firstpass of this node }
  418. if is_widechararray(def_from) or is_open_widechararray(def_from) then
  419. begin
  420. doconv:=tc_chararray_2_string;
  421. if is_widestring(def_to) then
  422. eq:=te_convert_l1
  423. else
  424. { size of widechar array is double due the sizeof a widechar }
  425. if not(is_shortstring(def_to) and (def_from.size>255*sizeof(widechar))) then
  426. eq:=te_convert_l3
  427. else
  428. eq:=te_convert_l2;
  429. end;
  430. end;
  431. pointerdef :
  432. begin
  433. { pchar can be assigned to short/ansistrings,
  434. but not in tp7 compatible mode }
  435. if not(m_tp7 in current_settings.modeswitches) then
  436. begin
  437. if is_pchar(def_from) then
  438. begin
  439. doconv:=tc_pchar_2_string;
  440. { prefer ansistrings because pchars can overflow shortstrings, }
  441. { but only if ansistrings are the default (JM) }
  442. if (is_shortstring(def_to) and
  443. not(cs_ansistrings in current_settings.localswitches)) or
  444. (is_ansistring(def_to) and
  445. (cs_ansistrings in current_settings.localswitches)) then
  446. eq:=te_convert_l1
  447. else
  448. eq:=te_convert_l2;
  449. end
  450. else if is_pwidechar(def_from) then
  451. begin
  452. doconv:=tc_pwchar_2_string;
  453. if is_widestring(def_to) then
  454. eq:=te_convert_l1
  455. else
  456. eq:=te_convert_l3;
  457. end;
  458. end;
  459. end;
  460. end;
  461. end;
  462. floatdef :
  463. begin
  464. case def_from.typ of
  465. orddef :
  466. begin { ordinal to real }
  467. { only for implicit and internal typecasts in tp/delphi }
  468. if (([cdo_explicit,cdo_internal] * cdoptions <> [cdo_explicit]) or
  469. ([m_tp7,m_delphi] * current_settings.modeswitches = [])) and
  470. (is_integer(def_from) or
  471. (is_currency(def_from) and
  472. (s64currencytype.typ = floatdef))) then
  473. begin
  474. doconv:=tc_int_2_real;
  475. eq:=te_convert_l1;
  476. end
  477. else if is_currency(def_from)
  478. { and (s64currencytype.typ = orddef)) } then
  479. begin
  480. { prefer conversion to orddef in this case, unless }
  481. { the orddef < currency (then it will get convert l3, }
  482. { and conversion to float is favoured) }
  483. doconv:=tc_int_2_real;
  484. eq:=te_convert_l2;
  485. end;
  486. end;
  487. floatdef :
  488. begin
  489. if tfloatdef(def_from).floattype=tfloatdef(def_to).floattype then
  490. eq:=te_equal
  491. else
  492. begin
  493. if (fromtreetype=realconstn) or
  494. not((cdo_explicit in cdoptions) and
  495. (m_delphi in current_settings.modeswitches)) then
  496. begin
  497. doconv:=tc_real_2_real;
  498. { do we loose precision? }
  499. if def_to.size<def_from.size then
  500. eq:=te_convert_l2
  501. else
  502. eq:=te_convert_l1;
  503. end;
  504. end;
  505. end;
  506. end;
  507. end;
  508. enumdef :
  509. begin
  510. case def_from.typ of
  511. enumdef :
  512. begin
  513. if cdo_explicit in cdoptions then
  514. begin
  515. eq:=te_convert_l1;
  516. doconv:=tc_int_2_int;
  517. end
  518. else
  519. begin
  520. hd1:=def_from;
  521. while assigned(tenumdef(hd1).basedef) do
  522. hd1:=tenumdef(hd1).basedef;
  523. hd2:=def_to;
  524. while assigned(tenumdef(hd2).basedef) do
  525. hd2:=tenumdef(hd2).basedef;
  526. if (hd1=hd2) then
  527. begin
  528. eq:=te_convert_l1;
  529. { because of packenum they can have different sizes! (JM) }
  530. doconv:=tc_int_2_int;
  531. end
  532. else
  533. begin
  534. { assignment of an enum symbol to an unique type? }
  535. if (fromtreetype=ordconstn) and
  536. (tenumsym(tenumdef(hd1).firstenum)=tenumsym(tenumdef(hd2).firstenum)) then
  537. begin
  538. { because of packenum they can have different sizes! (JM) }
  539. eq:=te_convert_l1;
  540. doconv:=tc_int_2_int;
  541. end;
  542. end;
  543. end;
  544. end;
  545. orddef :
  546. begin
  547. if cdo_explicit in cdoptions then
  548. begin
  549. eq:=te_convert_l1;
  550. doconv:=tc_int_2_int;
  551. end;
  552. end;
  553. variantdef :
  554. begin
  555. eq:=te_convert_l1;
  556. doconv:=tc_variant_2_enum;
  557. end;
  558. pointerdef :
  559. begin
  560. { ugly, but delphi allows it }
  561. if (cdo_explicit in cdoptions) and
  562. (m_delphi in current_settings.modeswitches) and
  563. (eq=te_incompatible) then
  564. begin
  565. doconv:=tc_int_2_int;
  566. eq:=te_convert_l1;
  567. end;
  568. end;
  569. end;
  570. end;
  571. arraydef :
  572. begin
  573. { open array is also compatible with a single element of its base type.
  574. the extra check for deftyp is needed because equal defs can also return
  575. true if the def types are not the same, for example with dynarray to pointer. }
  576. if is_open_array(def_to) and
  577. (def_from.typ=tarraydef(def_to).elementdef.typ) and
  578. equal_defs(def_from,tarraydef(def_to).elementdef) then
  579. begin
  580. doconv:=tc_equal;
  581. eq:=te_convert_l1;
  582. end
  583. else
  584. begin
  585. case def_from.typ of
  586. arraydef :
  587. begin
  588. { from/to packed array -- packed chararrays are }
  589. { strings in ISO Pascal (at least if the lower bound }
  590. { is 1, but GPC makes all equal-length chararrays }
  591. { compatible), so treat those the same as regular }
  592. { char arrays }
  593. if (is_packed_array(def_from) and
  594. not is_chararray(def_from) and
  595. not is_widechararray(def_from)) xor
  596. (is_packed_array(def_to) and
  597. not is_chararray(def_to) and
  598. not is_widechararray(def_to)) then
  599. { both must be packed }
  600. begin
  601. compare_defs_ext:=te_incompatible;
  602. exit;
  603. end
  604. { to dynamic array }
  605. else if is_dynamic_array(def_to) then
  606. begin
  607. if equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  608. begin
  609. { dynamic array -> dynamic array }
  610. if is_dynamic_array(def_from) then
  611. eq:=te_equal
  612. { fpc modes only: array -> dyn. array }
  613. else if (current_settings.modeswitches*[m_objfpc,m_fpc]<>[]) and
  614. not(is_special_array(def_from)) and
  615. is_zero_based_array(def_from) then
  616. begin
  617. eq:=te_convert_l2;
  618. doconv:=tc_array_2_dynarray;
  619. end;
  620. end
  621. end
  622. else
  623. { to open array }
  624. if is_open_array(def_to) then
  625. begin
  626. { array constructor -> open array }
  627. if is_array_constructor(def_from) then
  628. begin
  629. if is_void(tarraydef(def_from).elementdef) then
  630. begin
  631. doconv:=tc_equal;
  632. eq:=te_convert_l1;
  633. end
  634. else
  635. begin
  636. subeq:=compare_defs_ext(tarraydef(def_from).elementdef,
  637. tarraydef(def_to).elementdef,
  638. { reason for cdo_allow_variant: see webtbs/tw7070a and webtbs/tw7070b }
  639. arrayconstructorn,hct,hpd,[cdo_check_operator,cdo_allow_variant]);
  640. if (subeq>=te_equal) then
  641. begin
  642. doconv:=tc_equal;
  643. eq:=te_convert_l1;
  644. end
  645. else
  646. if (subeq>te_incompatible) then
  647. begin
  648. doconv:=hct;
  649. eq:=te_convert_l2;
  650. end;
  651. end;
  652. end
  653. else
  654. { dynamic array -> open array }
  655. if is_dynamic_array(def_from) and
  656. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  657. begin
  658. doconv:=tc_dynarray_2_openarray;
  659. eq:=te_convert_l2;
  660. end
  661. else
  662. { open array -> open array }
  663. if is_open_array(def_from) and
  664. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  665. eq:=te_equal
  666. else
  667. { array -> open array }
  668. if not(cdo_parameter in cdoptions) and
  669. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  670. eq:=te_equal;
  671. end
  672. else
  673. { to array of const }
  674. if is_array_of_const(def_to) then
  675. begin
  676. if is_array_of_const(def_from) or
  677. is_array_constructor(def_from) then
  678. begin
  679. eq:=te_equal;
  680. end
  681. else
  682. { array of tvarrec -> array of const }
  683. if equal_defs(tarraydef(def_to).elementdef,tarraydef(def_from).elementdef) then
  684. begin
  685. doconv:=tc_equal;
  686. eq:=te_convert_l1;
  687. end;
  688. end
  689. else
  690. { to array of char, from "Untyped" stringconstn (array of char) }
  691. if (fromtreetype=stringconstn) and
  692. (is_chararray(def_to) or
  693. is_widechararray(def_to)) then
  694. begin
  695. eq:=te_convert_l1;
  696. doconv:=tc_string_2_chararray;
  697. end
  698. else
  699. { other arrays }
  700. begin
  701. { open array -> array }
  702. if not(cdo_parameter in cdoptions) and
  703. is_open_array(def_from) and
  704. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  705. begin
  706. eq:=te_equal
  707. end
  708. else
  709. { array -> array }
  710. if not(m_tp7 in current_settings.modeswitches) and
  711. not(m_delphi in current_settings.modeswitches) and
  712. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  713. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  714. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) and
  715. equal_defs(tarraydef(def_from).rangedef,tarraydef(def_to).rangedef) then
  716. begin
  717. eq:=te_equal
  718. end;
  719. end;
  720. end;
  721. pointerdef :
  722. begin
  723. { nil and voidpointers are compatible with dyn. arrays }
  724. if is_dynamic_array(def_to) and
  725. ((fromtreetype=niln) or
  726. is_voidpointer(def_from)) then
  727. begin
  728. doconv:=tc_equal;
  729. eq:=te_convert_l1;
  730. end
  731. else
  732. if is_zero_based_array(def_to) and
  733. equal_defs(tpointerdef(def_from).pointeddef,tarraydef(def_to).elementdef) then
  734. begin
  735. doconv:=tc_pointer_2_array;
  736. eq:=te_convert_l1;
  737. end;
  738. end;
  739. stringdef :
  740. begin
  741. { string to char array }
  742. if (not is_special_array(def_to)) and
  743. (is_char(tarraydef(def_to).elementdef)or
  744. is_widechar(tarraydef(def_to).elementdef)) then
  745. begin
  746. doconv:=tc_string_2_chararray;
  747. eq:=te_convert_l1;
  748. end;
  749. end;
  750. orddef:
  751. begin
  752. if is_chararray(def_to) and
  753. is_char(def_from) then
  754. begin
  755. doconv:=tc_char_2_chararray;
  756. eq:=te_convert_l2;
  757. end;
  758. end;
  759. recorddef :
  760. begin
  761. { tvarrec -> array of const }
  762. if is_array_of_const(def_to) and
  763. equal_defs(def_from,tarraydef(def_to).elementdef) then
  764. begin
  765. doconv:=tc_equal;
  766. eq:=te_convert_l1;
  767. end;
  768. end;
  769. variantdef :
  770. begin
  771. if is_dynamic_array(def_to) then
  772. begin
  773. doconv:=tc_variant_2_dynarray;
  774. eq:=te_convert_l1;
  775. end;
  776. end;
  777. end;
  778. end;
  779. end;
  780. variantdef :
  781. begin
  782. if (cdo_allow_variant in cdoptions) then
  783. begin
  784. case def_from.typ of
  785. enumdef :
  786. begin
  787. doconv:=tc_enum_2_variant;
  788. eq:=te_convert_l1;
  789. end;
  790. arraydef :
  791. begin
  792. if is_dynamic_array(def_from) then
  793. begin
  794. doconv:=tc_dynarray_2_variant;
  795. eq:=te_convert_l1;
  796. end;
  797. end;
  798. objectdef :
  799. begin
  800. if is_interface(def_from) then
  801. begin
  802. doconv:=tc_interface_2_variant;
  803. eq:=te_convert_l1;
  804. end;
  805. end;
  806. variantdef :
  807. begin
  808. { doing this in the compiler avoids a lot of unncessary
  809. copying }
  810. if (tvariantdef(def_from).varianttype=vt_olevariant) and
  811. (tvariantdef(def_to).varianttype=vt_normalvariant) then
  812. begin
  813. doconv:=tc_equal;
  814. eq:=te_convert_l1;
  815. end;
  816. end;
  817. end;
  818. end;
  819. end;
  820. pointerdef :
  821. begin
  822. case def_from.typ of
  823. stringdef :
  824. begin
  825. { string constant (which can be part of array constructor)
  826. to zero terminated string constant }
  827. if (((fromtreetype = arrayconstructorn) and
  828. { can't use is_chararray, because returns false for }
  829. { array constructors }
  830. is_char(tarraydef(def_from).elementdef)) or
  831. (fromtreetype = stringconstn)) and
  832. (is_pchar(def_to) or is_pwidechar(def_to)) then
  833. begin
  834. doconv:=tc_cstring_2_pchar;
  835. eq:=te_convert_l2;
  836. end
  837. else
  838. if cdo_explicit in cdoptions then
  839. begin
  840. { pchar(ansistring) }
  841. if is_pchar(def_to) and
  842. is_ansistring(def_from) then
  843. begin
  844. doconv:=tc_ansistring_2_pchar;
  845. eq:=te_convert_l1;
  846. end
  847. else
  848. { pwidechar(widestring) }
  849. if is_pwidechar(def_to) and
  850. is_widestring(def_from) then
  851. begin
  852. doconv:=tc_ansistring_2_pchar;
  853. eq:=te_convert_l1;
  854. end;
  855. end;
  856. end;
  857. orddef :
  858. begin
  859. { char constant to zero terminated string constant }
  860. if (fromtreetype in [ordconstn,arrayconstructorn]) then
  861. begin
  862. if (is_char(def_from) or is_widechar(def_from)) and
  863. (is_pchar(def_to) or is_pwidechar(def_to)) then
  864. begin
  865. doconv:=tc_cchar_2_pchar;
  866. eq:=te_convert_l1;
  867. end
  868. else
  869. if (m_delphi in current_settings.modeswitches) and is_integer(def_from) then
  870. begin
  871. doconv:=tc_cord_2_pointer;
  872. eq:=te_convert_l2;
  873. end;
  874. end;
  875. { allow explicit typecasts from ordinals to pointer.
  876. Support for delphi compatibility
  877. Support constructs like pointer(cardinal-cardinal) or pointer(longint+cardinal) where
  878. the result of the ordinal operation is int64 also on 32 bit platforms.
  879. It is also used by the compiler internally for inc(pointer,ordinal) }
  880. if (eq=te_incompatible) and
  881. not is_void(def_from) and
  882. (
  883. (
  884. (cdo_explicit in cdoptions) and
  885. (
  886. (m_delphi in current_settings.modeswitches) or
  887. { Don't allow pchar(char) in fpc modes }
  888. is_integer(def_from)
  889. )
  890. ) or
  891. (cdo_internal in cdoptions)
  892. ) then
  893. begin
  894. doconv:=tc_int_2_int;
  895. eq:=te_convert_l1;
  896. end;
  897. end;
  898. {
  899. enumdef :
  900. begin
  901. { allow explicit typecasts from enums to pointer.
  902. Support for delphi compatibility
  903. }
  904. if (eq=te_incompatible) and
  905. (((cdo_explicit in cdoptions) and
  906. (m_delphi in current_settings.modeswitches)
  907. ) or
  908. (cdo_internal in cdoptions)
  909. ) then
  910. begin
  911. doconv:=tc_int_2_int;
  912. eq:=te_convert_l1;
  913. end;
  914. end;
  915. }
  916. arraydef :
  917. begin
  918. { string constant (which can be part of array constructor)
  919. to zero terminated string constant }
  920. if (((fromtreetype = arrayconstructorn) and
  921. { can't use is_chararray, because returns false for }
  922. { array constructors }
  923. is_char(tarraydef(def_from).elementdef)) or
  924. (fromtreetype = stringconstn)) and
  925. (is_pchar(def_to) or is_pwidechar(def_to)) then
  926. begin
  927. doconv:=tc_cstring_2_pchar;
  928. eq:=te_convert_l2;
  929. end
  930. else
  931. { chararray to pointer }
  932. if (is_zero_based_array(def_from) or
  933. is_open_array(def_from)) and
  934. equal_defs(tarraydef(def_from).elementdef,tpointerdef(def_to).pointeddef) then
  935. begin
  936. doconv:=tc_array_2_pointer;
  937. { don't prefer the pchar overload when a constant
  938. string was passed }
  939. if fromtreetype=stringconstn then
  940. eq:=te_convert_l2
  941. else
  942. eq:=te_convert_l1;
  943. end
  944. else
  945. { dynamic array to pointer, delphi only }
  946. if (m_delphi in current_settings.modeswitches) and
  947. is_dynamic_array(def_from) then
  948. begin
  949. eq:=te_equal;
  950. end;
  951. end;
  952. pointerdef :
  953. begin
  954. { check for far pointers }
  955. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  956. begin
  957. eq:=te_incompatible;
  958. end
  959. else
  960. { the types can be forward type, handle before normal type check !! }
  961. if assigned(def_to.typesym) and
  962. (tpointerdef(def_to).pointeddef.typ=forwarddef) then
  963. begin
  964. if (def_from.typesym=def_to.typesym) then
  965. eq:=te_equal
  966. end
  967. else
  968. { same types }
  969. if equal_defs(tpointerdef(def_from).pointeddef,tpointerdef(def_to).pointeddef) then
  970. begin
  971. eq:=te_equal
  972. end
  973. else
  974. { child class pointer can be assigned to anchestor pointers }
  975. if (
  976. (tpointerdef(def_from).pointeddef.typ=objectdef) and
  977. (tpointerdef(def_to).pointeddef.typ=objectdef) and
  978. tobjectdef(tpointerdef(def_from).pointeddef).is_related(
  979. tobjectdef(tpointerdef(def_to).pointeddef))
  980. ) then
  981. begin
  982. doconv:=tc_equal;
  983. eq:=te_convert_l1;
  984. end
  985. else
  986. { all pointers can be assigned to void-pointer }
  987. if is_void(tpointerdef(def_to).pointeddef) then
  988. begin
  989. doconv:=tc_equal;
  990. { give pwidechar,pchar a penalty so it prefers
  991. conversion to ansistring }
  992. if is_pchar(def_from) or
  993. is_pwidechar(def_from) then
  994. eq:=te_convert_l2
  995. else
  996. eq:=te_convert_l1;
  997. end
  998. else
  999. { all pointers can be assigned from void-pointer }
  1000. if is_void(tpointerdef(def_from).pointeddef) or
  1001. { all pointers can be assigned from void-pointer or formaldef pointer, check
  1002. tw3777.pp if you change this }
  1003. (tpointerdef(def_from).pointeddef.typ=formaldef) then
  1004. begin
  1005. doconv:=tc_equal;
  1006. { give pwidechar a penalty so it prefers
  1007. conversion to pchar }
  1008. if is_pwidechar(def_to) then
  1009. eq:=te_convert_l2
  1010. else
  1011. eq:=te_convert_l1;
  1012. end;
  1013. end;
  1014. procvardef :
  1015. begin
  1016. { procedure variable can be assigned to an void pointer,
  1017. this not allowed for methodpointers }
  1018. if (is_void(tpointerdef(def_to).pointeddef) or
  1019. (m_mac_procvar in current_settings.modeswitches)) and
  1020. tprocvardef(def_from).is_addressonly then
  1021. begin
  1022. doconv:=tc_equal;
  1023. eq:=te_convert_l1;
  1024. end;
  1025. end;
  1026. procdef :
  1027. begin
  1028. { procedure variable can be assigned to an void pointer,
  1029. this not allowed for methodpointers }
  1030. if (m_mac_procvar in current_settings.modeswitches) and
  1031. tprocdef(def_from).is_addressonly then
  1032. begin
  1033. doconv:=tc_proc_2_procvar;
  1034. eq:=te_convert_l2;
  1035. end;
  1036. end;
  1037. classrefdef,
  1038. objectdef :
  1039. begin
  1040. { class types and class reference type
  1041. can be assigned to void pointers, but it is less
  1042. preferred than assigning to a related objectdef }
  1043. if (
  1044. is_class_or_interface_or_dispinterface(def_from) or
  1045. (def_from.typ=classrefdef)
  1046. ) and
  1047. (tpointerdef(def_to).pointeddef.typ=orddef) and
  1048. (torddef(tpointerdef(def_to).pointeddef).ordtype=uvoid) then
  1049. begin
  1050. doconv:=tc_equal;
  1051. eq:=te_convert_l2;
  1052. end;
  1053. end;
  1054. end;
  1055. end;
  1056. setdef :
  1057. begin
  1058. case def_from.typ of
  1059. setdef :
  1060. begin
  1061. if assigned(tsetdef(def_from).elementdef) and
  1062. assigned(tsetdef(def_to).elementdef) then
  1063. begin
  1064. { sets with the same element base type and the same range are equal }
  1065. if equal_defs(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) and
  1066. (tsetdef(def_from).setbase=tsetdef(def_to).setbase) and
  1067. (tsetdef(def_from).setmax=tsetdef(def_to).setmax) then
  1068. eq:=te_equal
  1069. else if is_subequal(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) then
  1070. begin
  1071. eq:=te_convert_l1;
  1072. doconv:=tc_set_to_set;
  1073. end;
  1074. end
  1075. else
  1076. begin
  1077. { empty set is compatible with everything }
  1078. eq:=te_convert_l1;
  1079. doconv:=tc_set_to_set;
  1080. end;
  1081. end;
  1082. arraydef :
  1083. begin
  1084. { automatic arrayconstructor -> set conversion }
  1085. if is_array_constructor(def_from) then
  1086. begin
  1087. doconv:=tc_arrayconstructor_2_set;
  1088. eq:=te_convert_l1;
  1089. end;
  1090. end;
  1091. end;
  1092. end;
  1093. procvardef :
  1094. begin
  1095. case def_from.typ of
  1096. procdef :
  1097. begin
  1098. { proc -> procvar }
  1099. if (m_tp_procvar in current_settings.modeswitches) or
  1100. (m_mac_procvar in current_settings.modeswitches) then
  1101. begin
  1102. subeq:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to));
  1103. if subeq>te_incompatible then
  1104. begin
  1105. doconv:=tc_proc_2_procvar;
  1106. eq:=te_convert_l1;
  1107. end;
  1108. end;
  1109. end;
  1110. procvardef :
  1111. begin
  1112. { procvar -> procvar }
  1113. eq:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to));
  1114. end;
  1115. pointerdef :
  1116. begin
  1117. { nil is compatible with procvars }
  1118. if (fromtreetype=niln) then
  1119. begin
  1120. doconv:=tc_equal;
  1121. eq:=te_convert_l1;
  1122. end
  1123. else
  1124. { for example delphi allows the assignement from pointers }
  1125. { to procedure variables }
  1126. if (m_pointer_2_procedure in current_settings.modeswitches) and
  1127. is_void(tpointerdef(def_from).pointeddef) and
  1128. tprocvardef(def_to).is_addressonly then
  1129. begin
  1130. doconv:=tc_equal;
  1131. eq:=te_convert_l1;
  1132. end;
  1133. end;
  1134. end;
  1135. end;
  1136. objectdef :
  1137. begin
  1138. { object pascal objects }
  1139. if (def_from.typ=objectdef) and
  1140. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  1141. begin
  1142. doconv:=tc_equal;
  1143. eq:=te_convert_l1;
  1144. end
  1145. else
  1146. { Class/interface specific }
  1147. if is_class_or_interface_or_dispinterface(def_to) then
  1148. begin
  1149. { void pointer also for delphi mode }
  1150. if (m_delphi in current_settings.modeswitches) and
  1151. is_voidpointer(def_from) then
  1152. begin
  1153. doconv:=tc_equal;
  1154. { prefer pointer-pointer assignments }
  1155. eq:=te_convert_l2;
  1156. end
  1157. else
  1158. { nil is compatible with class instances and interfaces }
  1159. if (fromtreetype=niln) then
  1160. begin
  1161. doconv:=tc_equal;
  1162. eq:=te_convert_l1;
  1163. end
  1164. { classes can be assigned to interfaces }
  1165. else if is_interface(def_to) and
  1166. is_class(def_from) and
  1167. assigned(tobjectdef(def_from).ImplementedInterfaces) then
  1168. begin
  1169. { we've to search in parent classes as well }
  1170. hobjdef:=tobjectdef(def_from);
  1171. while assigned(hobjdef) do
  1172. begin
  1173. if hobjdef.find_implemented_interface(tobjectdef(def_to))<>nil then
  1174. begin
  1175. doconv:=tc_class_2_intf;
  1176. { don't prefer this over objectdef->objectdef }
  1177. eq:=te_convert_l2;
  1178. break;
  1179. end;
  1180. hobjdef:=hobjdef.childof;
  1181. end;
  1182. end
  1183. { Interface 2 GUID handling }
  1184. else if (def_to=tdef(rec_tguid)) and
  1185. (fromtreetype=typen) and
  1186. is_interface(def_from) and
  1187. assigned(tobjectdef(def_from).iidguid) then
  1188. begin
  1189. eq:=te_convert_l1;
  1190. doconv:=tc_equal;
  1191. end
  1192. else if (def_from.typ=variantdef) and is_interface(def_to) then
  1193. begin
  1194. doconv:=tc_variant_2_interface;
  1195. eq:=te_convert_l2;
  1196. end
  1197. { ugly, but delphi allows it }
  1198. else if (eq=te_incompatible) and
  1199. (def_from.typ=orddef) and
  1200. (m_delphi in current_settings.modeswitches) and
  1201. (cdo_explicit in cdoptions) then
  1202. begin
  1203. doconv:=tc_int_2_int;
  1204. eq:=te_convert_l1;
  1205. end;
  1206. end;
  1207. end;
  1208. classrefdef :
  1209. begin
  1210. { similar to pointerdef wrt forwards }
  1211. if assigned(def_to.typesym) and
  1212. (tclassrefdef(def_to).pointeddef.typ=forwarddef) then
  1213. begin
  1214. if (def_from.typesym=def_to.typesym) then
  1215. eq:=te_equal;
  1216. end
  1217. else
  1218. { class reference types }
  1219. if (def_from.typ=classrefdef) then
  1220. begin
  1221. if equal_defs(tclassrefdef(def_from).pointeddef,tclassrefdef(def_to).pointeddef) then
  1222. begin
  1223. eq:=te_equal;
  1224. end
  1225. else
  1226. begin
  1227. doconv:=tc_equal;
  1228. if (cdo_explicit in cdoptions) or
  1229. tobjectdef(tclassrefdef(def_from).pointeddef).is_related(
  1230. tobjectdef(tclassrefdef(def_to).pointeddef)) then
  1231. eq:=te_convert_l1;
  1232. end;
  1233. end
  1234. else
  1235. if (m_delphi in current_settings.modeswitches) and
  1236. is_voidpointer(def_from) then
  1237. begin
  1238. doconv:=tc_equal;
  1239. { prefer pointer-pointer assignments }
  1240. eq:=te_convert_l2;
  1241. end
  1242. else
  1243. { nil is compatible with class references }
  1244. if (fromtreetype=niln) then
  1245. begin
  1246. doconv:=tc_equal;
  1247. eq:=te_convert_l1;
  1248. end;
  1249. end;
  1250. filedef :
  1251. begin
  1252. { typed files are all equal to the abstract file type
  1253. name TYPEDFILE in system.pp in is_equal in types.pas
  1254. the problem is that it sholud be also compatible to FILE
  1255. but this would leed to a problem for ASSIGN RESET and REWRITE
  1256. when trying to find the good overloaded function !!
  1257. so all file function are doubled in system.pp
  1258. this is not very beautiful !!}
  1259. if (def_from.typ=filedef) then
  1260. begin
  1261. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  1262. begin
  1263. if
  1264. (
  1265. (tfiledef(def_from).typedfiledef=nil) and
  1266. (tfiledef(def_to).typedfiledef=nil)
  1267. ) or
  1268. (
  1269. (tfiledef(def_from).typedfiledef<>nil) and
  1270. (tfiledef(def_to).typedfiledef<>nil) and
  1271. equal_defs(tfiledef(def_from).typedfiledef,tfiledef(def_to).typedfiledef)
  1272. ) or
  1273. (
  1274. (tfiledef(def_from).filetyp = ft_typed) and
  1275. (tfiledef(def_to).filetyp = ft_typed) and
  1276. (
  1277. (tfiledef(def_from).typedfiledef = tdef(voidtype)) or
  1278. (tfiledef(def_to).typedfiledef = tdef(voidtype))
  1279. )
  1280. ) then
  1281. begin
  1282. eq:=te_equal;
  1283. end;
  1284. end
  1285. else
  1286. if ((tfiledef(def_from).filetyp = ft_untyped) and
  1287. (tfiledef(def_to).filetyp = ft_typed)) or
  1288. ((tfiledef(def_from).filetyp = ft_typed) and
  1289. (tfiledef(def_to).filetyp = ft_untyped)) then
  1290. begin
  1291. doconv:=tc_equal;
  1292. eq:=te_convert_l1;
  1293. end;
  1294. end;
  1295. end;
  1296. recorddef :
  1297. begin
  1298. { interface -> guid }
  1299. if is_interface(def_from) and
  1300. (def_to=rec_tguid) then
  1301. begin
  1302. doconv:=tc_intf_2_guid;
  1303. eq:=te_convert_l1;
  1304. end;
  1305. end;
  1306. formaldef :
  1307. begin
  1308. doconv:=tc_equal;
  1309. if (def_from.typ=formaldef) then
  1310. eq:=te_equal
  1311. else
  1312. { Just about everything can be converted to a formaldef...}
  1313. if not (def_from.typ in [abstractdef,errordef]) then
  1314. eq:=te_convert_l2;
  1315. end;
  1316. end;
  1317. { if we didn't find an appropriate type conversion yet
  1318. then we search also the := operator }
  1319. if (eq=te_incompatible) and
  1320. { make sure there is not a single variant if variants }
  1321. { are not allowed (otherwise if only cdo_check_operator }
  1322. { and e.g. fromdef=stringdef and todef=variantdef, then }
  1323. { the test will still succeed }
  1324. ((cdo_allow_variant in cdoptions) or
  1325. ((def_from.typ<>variantdef) and (def_to.typ<>variantdef))
  1326. ) and
  1327. (
  1328. { Check for variants? }
  1329. (
  1330. (cdo_allow_variant in cdoptions) and
  1331. ((def_from.typ=variantdef) or (def_to.typ=variantdef))
  1332. ) or
  1333. { Check for operators? }
  1334. (
  1335. (cdo_check_operator in cdoptions) and
  1336. ((def_from.typ in [objectdef,recorddef,arraydef,stringdef]) or
  1337. (def_to.typ in [objectdef,recorddef,arraydef,stringdef]))
  1338. )
  1339. ) then
  1340. begin
  1341. operatorpd:=search_assignment_operator(def_from,def_to);
  1342. if assigned(operatorpd) then
  1343. eq:=te_convert_operator;
  1344. end;
  1345. { update convtype for te_equal when it is not yet set }
  1346. if (eq=te_equal) and
  1347. (doconv=tc_not_possible) then
  1348. doconv:=tc_equal;
  1349. compare_defs_ext:=eq;
  1350. end;
  1351. function equal_defs(def_from,def_to:tdef):boolean;
  1352. var
  1353. convtyp : tconverttype;
  1354. pd : tprocdef;
  1355. begin
  1356. { Compare defs with nothingn and no explicit typecasts and
  1357. searching for overloaded operators is not needed }
  1358. equal_defs:=(compare_defs_ext(def_from,def_to,nothingn,convtyp,pd,[])>=te_equal);
  1359. end;
  1360. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  1361. var
  1362. doconv : tconverttype;
  1363. pd : tprocdef;
  1364. begin
  1365. compare_defs:=compare_defs_ext(def_from,def_to,fromtreetype,doconv,pd,[cdo_check_operator,cdo_allow_variant]);
  1366. end;
  1367. function is_subequal(def1, def2: tdef): boolean;
  1368. var
  1369. basedef1,basedef2 : tenumdef;
  1370. Begin
  1371. is_subequal := false;
  1372. if assigned(def1) and assigned(def2) then
  1373. Begin
  1374. if (def1.typ = orddef) and (def2.typ = orddef) then
  1375. Begin
  1376. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  1377. { range checking for case statements is done with testrange }
  1378. case torddef(def1).ordtype of
  1379. u8bit,u16bit,u32bit,u64bit,
  1380. s8bit,s16bit,s32bit,s64bit :
  1381. is_subequal:=(torddef(def2).ordtype in [s64bit,u64bit,s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  1382. bool8bit,bool16bit,bool32bit,bool64bit :
  1383. is_subequal:=(torddef(def2).ordtype in [bool8bit,bool16bit,bool32bit,bool64bit]);
  1384. uchar :
  1385. is_subequal:=(torddef(def2).ordtype=uchar);
  1386. uwidechar :
  1387. is_subequal:=(torddef(def2).ordtype=uwidechar);
  1388. end;
  1389. end
  1390. else
  1391. Begin
  1392. { Check if both basedefs are equal }
  1393. if (def1.typ=enumdef) and (def2.typ=enumdef) then
  1394. Begin
  1395. { get both basedefs }
  1396. basedef1:=tenumdef(def1);
  1397. while assigned(basedef1.basedef) do
  1398. basedef1:=basedef1.basedef;
  1399. basedef2:=tenumdef(def2);
  1400. while assigned(basedef2.basedef) do
  1401. basedef2:=basedef2.basedef;
  1402. is_subequal:=(basedef1=basedef2);
  1403. end;
  1404. end;
  1405. end;
  1406. end;
  1407. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  1408. var
  1409. currpara1,
  1410. currpara2 : tparavarsym;
  1411. eq,lowesteq : tequaltype;
  1412. hpd : tprocdef;
  1413. convtype : tconverttype;
  1414. cdoptions : tcompare_defs_options;
  1415. i1,i2 : byte;
  1416. begin
  1417. compare_paras:=te_incompatible;
  1418. cdoptions:=[cdo_parameter,cdo_check_operator,cdo_allow_variant];
  1419. { we need to parse the list from left-right so the
  1420. not-default parameters are checked first }
  1421. lowesteq:=high(tequaltype);
  1422. i1:=0;
  1423. i2:=0;
  1424. if cpo_ignorehidden in cpoptions then
  1425. begin
  1426. while (i1<para1.count) and
  1427. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1428. inc(i1);
  1429. while (i2<para2.count) and
  1430. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1431. inc(i2);
  1432. end;
  1433. while (i1<para1.count) and (i2<para2.count) do
  1434. begin
  1435. eq:=te_incompatible;
  1436. currpara1:=tparavarsym(para1[i1]);
  1437. currpara2:=tparavarsym(para2[i2]);
  1438. { Unique types must match exact }
  1439. if ((df_unique in currpara1.vardef.defoptions) or (df_unique in currpara2.vardef.defoptions)) and
  1440. (currpara1.vardef<>currpara2.vardef) then
  1441. exit;
  1442. { Handle hidden parameters separately, because self is
  1443. defined as voidpointer for methodpointers }
  1444. if (vo_is_hidden_para in currpara1.varoptions) or
  1445. (vo_is_hidden_para in currpara2.varoptions) then
  1446. begin
  1447. { both must be hidden }
  1448. if (vo_is_hidden_para in currpara1.varoptions)<>(vo_is_hidden_para in currpara2.varoptions) then
  1449. exit;
  1450. eq:=te_equal;
  1451. if not(vo_is_self in currpara1.varoptions) and
  1452. not(vo_is_self in currpara2.varoptions) then
  1453. begin
  1454. if (currpara1.varspez<>currpara2.varspez) then
  1455. exit;
  1456. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1457. convtype,hpd,cdoptions);
  1458. end;
  1459. end
  1460. else
  1461. begin
  1462. case acp of
  1463. cp_value_equal_const :
  1464. begin
  1465. if (
  1466. (currpara1.varspez<>currpara2.varspez) and
  1467. ((currpara1.varspez in [vs_var,vs_out]) or
  1468. (currpara2.varspez in [vs_var,vs_out]))
  1469. ) then
  1470. exit;
  1471. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1472. convtype,hpd,cdoptions);
  1473. end;
  1474. cp_all :
  1475. begin
  1476. if (currpara1.varspez<>currpara2.varspez) then
  1477. exit;
  1478. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1479. convtype,hpd,cdoptions);
  1480. end;
  1481. cp_procvar :
  1482. begin
  1483. if (currpara1.varspez<>currpara2.varspez) then
  1484. exit;
  1485. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1486. convtype,hpd,cdoptions);
  1487. { Parameters must be at least equal otherwise the are incompatible }
  1488. if (eq<te_equal) then
  1489. eq:=te_incompatible;
  1490. end;
  1491. else
  1492. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1493. convtype,hpd,cdoptions);
  1494. end;
  1495. end;
  1496. { check type }
  1497. if eq=te_incompatible then
  1498. exit;
  1499. if eq<lowesteq then
  1500. lowesteq:=eq;
  1501. { also check default value if both have it declared }
  1502. if (cpo_comparedefaultvalue in cpoptions) and
  1503. assigned(currpara1.defaultconstsym) and
  1504. assigned(currpara2.defaultconstsym) then
  1505. begin
  1506. if not equal_constsym(tconstsym(currpara1.defaultconstsym),tconstsym(currpara2.defaultconstsym)) then
  1507. exit;
  1508. end;
  1509. inc(i1);
  1510. inc(i2);
  1511. if cpo_ignorehidden in cpoptions then
  1512. begin
  1513. while (i1<para1.count) and
  1514. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1515. inc(i1);
  1516. while (i2<para2.count) and
  1517. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1518. inc(i2);
  1519. end;
  1520. end;
  1521. { when both lists are empty then the parameters are equal. Also
  1522. when one list is empty and the other has a parameter with default
  1523. value assigned then the parameters are also equal }
  1524. if ((i1>=para1.count) and (i2>=para2.count)) or
  1525. ((cpo_allowdefaults in cpoptions) and
  1526. (((i1<para1.count) and assigned(tparavarsym(para1[i1]).defaultconstsym)) or
  1527. ((i2<para2.count) and assigned(tparavarsym(para2[i2]).defaultconstsym)))) then
  1528. compare_paras:=lowesteq;
  1529. end;
  1530. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  1531. var
  1532. eq : tequaltype;
  1533. po_comp : tprocoptions;
  1534. begin
  1535. proc_to_procvar_equal:=te_incompatible;
  1536. if not(assigned(def1)) or not(assigned(def2)) then
  1537. exit;
  1538. { check for method pointer }
  1539. if (def1.is_methodpointer xor def2.is_methodpointer) or
  1540. (def1.is_addressonly xor def2.is_addressonly) then
  1541. exit;
  1542. { check return value and options, methodpointer is already checked }
  1543. po_comp:=[po_staticmethod,po_interrupt,
  1544. po_iocheck,po_varargs];
  1545. if (m_delphi in current_settings.modeswitches) then
  1546. exclude(po_comp,po_varargs);
  1547. if (def1.proccalloption=def2.proccalloption) and
  1548. ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1549. equal_defs(def1.returndef,def2.returndef) then
  1550. begin
  1551. { return equal type based on the parameters, but a proc->procvar
  1552. is never exact, so map an exact match of the parameters to
  1553. te_equal }
  1554. eq:=compare_paras(def1.paras,def2.paras,cp_procvar,[]);
  1555. if eq=te_exact then
  1556. eq:=te_equal;
  1557. proc_to_procvar_equal:=eq;
  1558. end;
  1559. end;
  1560. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  1561. begin
  1562. compatible_childmethod_resultdef :=
  1563. (equal_defs(parentretdef,childretdef)) or
  1564. ((parentretdef.typ=objectdef) and
  1565. (childretdef.typ=objectdef) and
  1566. is_class_or_interface(parentretdef) and
  1567. is_class_or_interface(childretdef) and
  1568. (tobjectdef(childretdef).is_related(tobjectdef(parentretdef))))
  1569. end;
  1570. end.