defcmp.pas 59 KB

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