defcmp.pas 58 KB

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