defcmp.pas 57 KB

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