defcmp.pas 56 KB

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