defcmp.pas 58 KB

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