defcmp.pas 59 KB

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