defcmp.pas 59 KB

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