defcmp.pas 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  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. cpuinfo,
  24. globals,
  25. node,
  26. symconst,symbase,symtype,symdef;
  27. type
  28. { The order is from low priority to high priority,
  29. Note: the operators > and < are used on this list }
  30. tequaltype = (
  31. te_incompatible,
  32. te_convert_operator,
  33. te_convert_l2, { compatible conversion with possible loss of data }
  34. te_convert_l1, { compatible conversion }
  35. te_equal, { the definitions are equal }
  36. te_exact
  37. );
  38. { if acp is cp_all the var const or nothing are considered equal }
  39. compare_type = ( cp_none, cp_value_equal_const, cp_all,cp_procvar);
  40. tconverttype = (
  41. tc_equal,
  42. tc_not_possible,
  43. tc_string_2_string,
  44. tc_char_2_string,
  45. tc_char_2_chararray,
  46. tc_pchar_2_string,
  47. tc_cchar_2_pchar,
  48. tc_cstring_2_pchar,
  49. tc_ansistring_2_pchar,
  50. tc_string_2_chararray,
  51. tc_chararray_2_string,
  52. tc_array_2_pointer,
  53. tc_pointer_2_array,
  54. tc_int_2_int,
  55. tc_int_2_bool,
  56. tc_bool_2_bool,
  57. tc_bool_2_int,
  58. tc_real_2_real,
  59. tc_int_2_real,
  60. tc_proc_2_procvar,
  61. tc_arrayconstructor_2_set,
  62. tc_load_smallset,
  63. tc_cord_2_pointer,
  64. tc_intf_2_string,
  65. tc_intf_2_guid,
  66. tc_class_2_intf,
  67. tc_char_2_char,
  68. tc_normal_2_smallset,
  69. tc_dynarray_2_openarray,
  70. tc_pwchar_2_string,
  71. tc_variant_2_dynarray,
  72. tc_dynarray_2_variant
  73. );
  74. function compare_defs_ext(def_from,def_to : tdef;
  75. fromtreetype : tnodetype;
  76. explicit : boolean;
  77. check_operator : boolean;
  78. var doconv : tconverttype;
  79. var operatorpd : tprocdef):tequaltype;
  80. { Returns if the type def_from can be converted to def_to or if both types are equal }
  81. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  82. { Returns true, if def1 and def2 are semantically the same }
  83. function equal_defs(def_from,def_to:tdef):boolean;
  84. { Checks for type compatibility (subgroups of type)
  85. used for case statements... probably missing stuff
  86. to use on other types }
  87. function is_subequal(def1, def2: tdef): boolean;
  88. function assignment_overloaded(from_def,to_def : tdef) : tprocdef;
  89. {# true, if two parameter lists are equal
  90. if acp is cp_none, all have to match exactly
  91. if acp is cp_value_equal_const call by value
  92. and call by const parameter are assumed as
  93. equal
  94. allowdefaults indicates if default value parameters
  95. are allowed (in this case, the search order will first
  96. search for a routine with default parameters, before
  97. searching for the same definition with no parameters)
  98. }
  99. function compare_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean):tequaltype;
  100. { True if a function can be assigned to a procvar }
  101. { changed first argument type to pabstractprocdef so that it can also be }
  102. { used to test compatibility between two pprocvardefs (JM) }
  103. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  104. implementation
  105. uses
  106. globtype,tokens,
  107. verbose,systems,
  108. symsym,symtable,
  109. defutil,symutil;
  110. function assignment_overloaded(from_def,to_def:tdef):tprocdef;
  111. begin
  112. if assigned(overloaded_operators[_ASSIGNMENT]) then
  113. assignment_overloaded:=overloaded_operators[_ASSIGNMENT].search_procdef_assignment_operator(from_def,to_def)
  114. else
  115. assignment_overloaded:=nil;
  116. end;
  117. function compare_defs_ext(def_from,def_to : tdef;
  118. fromtreetype : tnodetype;
  119. explicit : boolean;
  120. check_operator : boolean;
  121. var doconv : tconverttype;
  122. var operatorpd : tprocdef):tequaltype;
  123. { Tbasetype:
  124. uvoid,
  125. u8bit,u16bit,u32bit,u64bit,
  126. s8bit,s16bit,s32bit,s64bit,
  127. bool8bit,bool16bit,bool32bit,
  128. uchar,uwidechar }
  129. type
  130. tbasedef=(bvoid,bchar,bint,bbool);
  131. const
  132. basedeftbl:array[tbasetype] of tbasedef =
  133. (bvoid,
  134. bint,bint,bint,bint,
  135. bint,bint,bint,bint,
  136. bbool,bbool,bbool,
  137. bchar,bchar);
  138. basedefconvertsimplicit : array[tbasedef,tbasedef] of tconverttype =
  139. { void, char, int, bool }
  140. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  141. (tc_not_possible,tc_char_2_char,tc_not_possible,tc_not_possible),
  142. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_int_2_bool),
  143. (tc_not_possible,tc_not_possible,tc_bool_2_int,tc_bool_2_bool));
  144. basedefconvertsexplicit : array[tbasedef,tbasedef] of tconverttype =
  145. { void, char, int, bool }
  146. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  147. (tc_not_possible,tc_char_2_char,tc_int_2_int,tc_int_2_bool),
  148. (tc_not_possible,tc_int_2_int,tc_int_2_int,tc_int_2_bool),
  149. (tc_not_possible,tc_bool_2_int,tc_bool_2_int,tc_bool_2_bool));
  150. var
  151. eq,b : tequaltype;
  152. hd1,hd2 : tdef;
  153. hct : tconverttype;
  154. hd3 : tobjectdef;
  155. hpd : tprocdef;
  156. begin
  157. { safety check }
  158. if not(assigned(def_from) and assigned(def_to)) then
  159. begin
  160. compare_defs_ext:=te_incompatible;
  161. exit;
  162. end;
  163. { same def? then we've an exact match }
  164. if def_from=def_to then
  165. begin
  166. compare_defs_ext:=te_exact;
  167. exit;
  168. end;
  169. { we walk the wanted (def_to) types and check then the def_from
  170. types if there is a conversion possible }
  171. b:=te_incompatible;
  172. doconv:=tc_not_possible;
  173. case def_to.deftype of
  174. orddef :
  175. begin
  176. case def_from.deftype of
  177. orddef :
  178. begin
  179. if (torddef(def_from).typ=torddef(def_to).typ) then
  180. begin
  181. case torddef(def_from).typ of
  182. u8bit,u16bit,u32bit,u64bit,
  183. s8bit,s16bit,s32bit,s64bit:
  184. begin
  185. if (torddef(def_from).low=torddef(def_to).low) and
  186. (torddef(def_from).high=torddef(def_to).high) then
  187. b:=te_equal
  188. else
  189. b:=te_convert_l1;
  190. end;
  191. uvoid,uchar,uwidechar,
  192. bool8bit,bool16bit,bool32bit:
  193. b:=te_equal;
  194. else
  195. internalerror(200210061);
  196. end;
  197. end
  198. else
  199. begin
  200. if explicit then
  201. doconv:=basedefconvertsexplicit[basedeftbl[torddef(def_from).typ],basedeftbl[torddef(def_to).typ]]
  202. else
  203. doconv:=basedefconvertsimplicit[basedeftbl[torddef(def_from).typ],basedeftbl[torddef(def_to).typ]];
  204. if (doconv=tc_not_possible) then
  205. b:=te_incompatible
  206. else
  207. { "punish" bad type conversions :) (JM) }
  208. if (not is_in_limit(def_from,def_to)) and
  209. (def_from.size > def_to.size) then
  210. b:=te_convert_l2
  211. else
  212. b:=te_convert_l1;
  213. end;
  214. end;
  215. enumdef :
  216. begin
  217. { needed for char(enum) }
  218. if explicit then
  219. begin
  220. doconv:=tc_int_2_int;
  221. b:=te_convert_l1;
  222. end;
  223. end;
  224. pointerdef :
  225. begin
  226. if explicit and
  227. (fromtreetype=niln) then
  228. begin
  229. { will be handled by the constant folding }
  230. doconv:=tc_equal;
  231. b:=te_convert_l1;
  232. end;
  233. end;
  234. end;
  235. end;
  236. stringdef :
  237. begin
  238. case def_from.deftype of
  239. stringdef :
  240. begin
  241. if (tstringdef(def_from).string_typ=tstringdef(def_to).string_typ) and
  242. ((tstringdef(def_from).string_typ<>st_shortstring) or
  243. (tstringdef(def_from).len=tstringdef(def_to).len)) then
  244. b:=te_equal
  245. else
  246. begin
  247. doconv:=tc_string_2_string;
  248. { Prefer conversions to shortstring over other
  249. conversions. This is compatible with Delphi (PFV) }
  250. if tstringdef(def_to).string_typ=st_shortstring then
  251. b:=te_convert_l1
  252. else
  253. b:=te_convert_l2;
  254. end;
  255. end;
  256. orddef :
  257. begin
  258. { char to string}
  259. if is_char(def_from) or
  260. is_widechar(def_from) then
  261. begin
  262. doconv:=tc_char_2_string;
  263. b:=te_convert_l1;
  264. end;
  265. end;
  266. arraydef :
  267. begin
  268. { array of char to string, the length check is done by the firstpass of this node }
  269. if is_chararray(def_from) or
  270. (is_char(tarraydef(def_from).elementtype.def) and
  271. is_open_array(def_from)) then
  272. begin
  273. doconv:=tc_chararray_2_string;
  274. if is_open_array(def_from) or
  275. (is_shortstring(def_to) and
  276. (def_from.size <= 255)) or
  277. (is_ansistring(def_to) and
  278. (def_from.size > 255)) then
  279. b:=te_convert_l1
  280. else
  281. b:=te_convert_l2;
  282. end;
  283. end;
  284. pointerdef :
  285. begin
  286. { pchar can be assigned to short/ansistrings,
  287. but not in tp7 compatible mode }
  288. if not(m_tp7 in aktmodeswitches) then
  289. begin
  290. if is_pchar(def_from) then
  291. begin
  292. doconv:=tc_pchar_2_string;
  293. { trefer ansistrings because pchars can overflow shortstrings, }
  294. { but only if ansistrings are the default (JM) }
  295. if (is_shortstring(def_to) and
  296. not(cs_ansistrings in aktlocalswitches)) or
  297. (is_ansistring(def_to) and
  298. (cs_ansistrings in aktlocalswitches)) then
  299. b:=te_convert_l1
  300. else
  301. b:=te_convert_l2;
  302. end
  303. else if is_pwidechar(def_from) then
  304. begin
  305. doconv:=tc_pwchar_2_string;
  306. { trefer ansistrings because pchars can overflow shortstrings, }
  307. { but only if ansistrings are the default (JM) }
  308. if is_widestring(def_to) then
  309. b:=te_convert_l1
  310. else
  311. b:=te_convert_l2;
  312. end;
  313. end;
  314. end;
  315. end;
  316. end;
  317. floatdef :
  318. begin
  319. case def_from.deftype of
  320. orddef :
  321. begin { ordinal to real }
  322. if is_integer(def_from) then
  323. begin
  324. doconv:=tc_int_2_real;
  325. b:=te_convert_l1;
  326. end;
  327. end;
  328. floatdef :
  329. begin
  330. if tfloatdef(def_from).typ=tfloatdef(def_to).typ then
  331. b:=te_equal
  332. else
  333. begin
  334. doconv:=tc_real_2_real;
  335. b:=te_convert_l1;
  336. end;
  337. end;
  338. end;
  339. end;
  340. enumdef :
  341. begin
  342. case def_from.deftype of
  343. enumdef :
  344. begin
  345. if explicit then
  346. begin
  347. b:=te_convert_l1;
  348. doconv:=tc_int_2_int;
  349. end
  350. else
  351. begin
  352. hd1:=def_from;
  353. while assigned(tenumdef(hd1).basedef) do
  354. hd1:=tenumdef(hd1).basedef;
  355. hd2:=def_to;
  356. while assigned(tenumdef(hd2).basedef) do
  357. hd2:=tenumdef(hd2).basedef;
  358. if (hd1=hd2) then
  359. begin
  360. b:=te_convert_l1;
  361. { because of packenum they can have different sizes! (JM) }
  362. doconv:=tc_int_2_int;
  363. end;
  364. end;
  365. end;
  366. orddef :
  367. begin
  368. if explicit then
  369. begin
  370. b:=te_convert_l1;
  371. doconv:=tc_int_2_int;
  372. end;
  373. end;
  374. end;
  375. end;
  376. arraydef :
  377. begin
  378. { open array is also compatible with a single element of its base type }
  379. if is_open_array(def_to) and
  380. equal_defs(def_from,tarraydef(def_to).elementtype.def) then
  381. begin
  382. doconv:=tc_equal;
  383. b:=te_convert_l1;
  384. end
  385. else
  386. begin
  387. case def_from.deftype of
  388. arraydef :
  389. begin
  390. { to dynamic array }
  391. if is_dynamic_array(def_to) then
  392. begin
  393. { dynamic array -> dynamic array }
  394. if is_dynamic_array(def_from) and
  395. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  396. b:=te_equal;
  397. end
  398. else
  399. { to open array }
  400. if is_open_array(def_to) then
  401. begin
  402. { array constructor -> open array }
  403. if is_array_constructor(def_from) then
  404. begin
  405. if is_void(tarraydef(def_from).elementtype.def) then
  406. begin
  407. doconv:=tc_equal;
  408. b:=te_convert_l1;
  409. end
  410. else
  411. begin
  412. eq:=compare_defs_ext(tarraydef(def_from).elementtype.def,
  413. tarraydef(def_to).elementtype.def,
  414. arrayconstructorn,false,true,hct,hpd);
  415. if (eq>=te_equal) then
  416. begin
  417. doconv:=tc_equal;
  418. b:=te_convert_l1;
  419. end
  420. else
  421. if (eq>te_incompatible) then
  422. begin
  423. doconv:=hct;
  424. b:=te_convert_l2;
  425. end;
  426. end;
  427. end
  428. else
  429. { dynamic array -> open array }
  430. if is_dynamic_array(def_from) and
  431. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  432. begin
  433. doconv:=tc_dynarray_2_openarray;
  434. b:=te_convert_l2;
  435. end
  436. else
  437. { array -> open array }
  438. if equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  439. b:=te_equal;
  440. end
  441. else
  442. { to array of const }
  443. if is_array_of_const(def_to) then
  444. begin
  445. if is_array_of_const(def_from) or
  446. is_array_constructor(def_from) then
  447. begin
  448. b:=te_equal;
  449. end
  450. else
  451. { array of tvarrec -> array of const }
  452. if equal_defs(tarraydef(def_to).elementtype.def,tarraydef(def_from).elementtype.def) then
  453. begin
  454. doconv:=tc_equal;
  455. b:=te_convert_l1;
  456. end;
  457. end
  458. else
  459. { other arrays }
  460. begin
  461. { open array -> array }
  462. if is_open_array(def_from) and
  463. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  464. begin
  465. b:=te_equal
  466. end
  467. else
  468. { array -> array }
  469. if not(m_tp7 in aktmodeswitches) and
  470. not(m_delphi in aktmodeswitches) and
  471. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  472. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  473. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) and
  474. equal_defs(tarraydef(def_from).rangetype.def,tarraydef(def_to).rangetype.def) then
  475. begin
  476. b:=te_equal
  477. end;
  478. end;
  479. end;
  480. pointerdef :
  481. begin
  482. { nil is compatible with dyn. arrays }
  483. if is_dynamic_array(def_to) and
  484. (fromtreetype=niln) then
  485. begin
  486. doconv:=tc_equal;
  487. b:=te_convert_l1;
  488. end
  489. else
  490. if is_zero_based_array(def_to) and
  491. equal_defs(tpointerdef(def_from).pointertype.def,tarraydef(def_to).elementtype.def) then
  492. begin
  493. doconv:=tc_pointer_2_array;
  494. b:=te_convert_l1;
  495. end;
  496. end;
  497. stringdef :
  498. begin
  499. { string to char array }
  500. if (not is_special_array(def_to)) and
  501. is_char(tarraydef(def_to).elementtype.def) then
  502. begin
  503. doconv:=tc_string_2_chararray;
  504. b:=te_convert_l1;
  505. end;
  506. end;
  507. orddef:
  508. begin
  509. if is_chararray(def_to) and
  510. is_char(def_from) then
  511. begin
  512. doconv:=tc_char_2_chararray;
  513. b:=te_convert_l2;
  514. end;
  515. end;
  516. recorddef :
  517. begin
  518. { tvarrec -> array of const }
  519. if is_array_of_const(def_to) and
  520. equal_defs(def_from,tarraydef(def_to).elementtype.def) then
  521. begin
  522. doconv:=tc_equal;
  523. b:=te_convert_l1;
  524. end;
  525. end;
  526. variantdef :
  527. begin
  528. if is_dynamic_array(def_to) then
  529. begin
  530. doconv:=tc_variant_2_dynarray;
  531. b:=te_convert_l1;
  532. end;
  533. end;
  534. end;
  535. end;
  536. end;
  537. pointerdef :
  538. begin
  539. case def_from.deftype of
  540. stringdef :
  541. begin
  542. { string constant (which can be part of array constructor)
  543. to zero terminated string constant }
  544. if (fromtreetype in [arrayconstructorn,stringconstn]) and
  545. (is_pchar(def_to) or is_pwidechar(def_to)) then
  546. begin
  547. doconv:=tc_cstring_2_pchar;
  548. b:=te_convert_l1;
  549. end
  550. else
  551. if explicit then
  552. begin
  553. { pchar(ansistring) }
  554. if is_pchar(def_to) and
  555. is_ansistring(def_from) then
  556. begin
  557. doconv:=tc_ansistring_2_pchar;
  558. b:=te_convert_l1;
  559. end
  560. else
  561. { pwidechar(ansistring) }
  562. if is_pwidechar(def_to) and
  563. is_widestring(def_from) then
  564. begin
  565. doconv:=tc_ansistring_2_pchar;
  566. b:=te_convert_l1;
  567. end;
  568. end;
  569. end;
  570. orddef :
  571. begin
  572. { char constant to zero terminated string constant }
  573. if (fromtreetype=ordconstn) then
  574. begin
  575. if is_char(def_from) and
  576. is_pchar(def_to) then
  577. begin
  578. doconv:=tc_cchar_2_pchar;
  579. b:=te_convert_l1;
  580. end
  581. else
  582. if is_integer(def_from) then
  583. begin
  584. doconv:=tc_cord_2_pointer;
  585. b:=te_convert_l1;
  586. end;
  587. end;
  588. if (b=te_incompatible) and
  589. explicit and
  590. (m_delphi in aktmodeswitches) then
  591. begin
  592. doconv:=tc_int_2_int;
  593. b:=te_convert_l1;
  594. end;
  595. end;
  596. arraydef :
  597. begin
  598. { chararray to pointer }
  599. if is_zero_based_array(def_from) and
  600. equal_defs(tarraydef(def_from).elementtype.def,tpointerdef(def_to).pointertype.def) then
  601. begin
  602. doconv:=tc_array_2_pointer;
  603. b:=te_convert_l1;
  604. end;
  605. end;
  606. pointerdef :
  607. begin
  608. { check for far pointers }
  609. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  610. begin
  611. b:=te_incompatible;
  612. end
  613. else
  614. { the types can be forward type, handle before normal type check !! }
  615. if assigned(def_to.typesym) and
  616. (tpointerdef(def_to).pointertype.def.deftype=forwarddef) then
  617. begin
  618. if (def_from.typesym=def_to.typesym) then
  619. b:=te_equal
  620. end
  621. else
  622. { same types }
  623. if (tpointerdef(def_from).pointertype.def=tpointerdef(def_to).pointertype.def) then
  624. begin
  625. b:=te_equal
  626. end
  627. else
  628. { child class pointer can be assigned to anchestor pointers }
  629. if (
  630. (tpointerdef(def_from).pointertype.def.deftype=objectdef) and
  631. (tpointerdef(def_to).pointertype.def.deftype=objectdef) and
  632. tobjectdef(tpointerdef(def_from).pointertype.def).is_related(
  633. tobjectdef(tpointerdef(def_to).pointertype.def))
  634. ) or
  635. { all pointers can be assigned to/from void-pointer }
  636. is_void(tpointerdef(def_to).pointertype.def) or
  637. is_void(tpointerdef(def_from).pointertype.def) then
  638. begin
  639. doconv:=tc_equal;
  640. b:=te_convert_l1;
  641. end;
  642. end;
  643. procvardef :
  644. begin
  645. { procedure variable can be assigned to an void pointer }
  646. { Not anymore. Use the @ operator now.}
  647. if not(m_tp_procvar in aktmodeswitches) and
  648. (tpointerdef(def_to).pointertype.def.deftype=orddef) and
  649. (torddef(tpointerdef(def_to).pointertype.def).typ=uvoid) then
  650. begin
  651. doconv:=tc_equal;
  652. b:=te_convert_l1;
  653. end;
  654. end;
  655. classrefdef,
  656. objectdef :
  657. begin
  658. { class types and class reference type
  659. can be assigned to void pointers }
  660. if (
  661. is_class_or_interface(def_from) or
  662. (def_from.deftype=classrefdef)
  663. ) and
  664. (tpointerdef(def_to).pointertype.def.deftype=orddef) and
  665. (torddef(tpointerdef(def_to).pointertype.def).typ=uvoid) then
  666. begin
  667. doconv:=tc_equal;
  668. b:=te_convert_l1;
  669. end;
  670. end;
  671. end;
  672. end;
  673. setdef :
  674. begin
  675. case def_from.deftype of
  676. setdef :
  677. begin
  678. if assigned(tsetdef(def_from).elementtype.def) and
  679. assigned(tsetdef(def_to).elementtype.def) then
  680. begin
  681. { sets with the same element base type are equal }
  682. if is_subequal(tsetdef(def_from).elementtype.def,tsetdef(def_to).elementtype.def) then
  683. b:=te_equal;
  684. end
  685. else
  686. { empty set is compatible with everything }
  687. b:=te_equal;
  688. end;
  689. arraydef :
  690. begin
  691. { automatic arrayconstructor -> set conversion }
  692. if is_array_constructor(def_from) then
  693. begin
  694. doconv:=tc_arrayconstructor_2_set;
  695. b:=te_convert_l1;
  696. end;
  697. end;
  698. end;
  699. end;
  700. procvardef :
  701. begin
  702. case def_from.deftype of
  703. procdef :
  704. begin
  705. { proc -> procvar }
  706. if (m_tp_procvar in aktmodeswitches) then
  707. begin
  708. b:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to));
  709. if b>te_incompatible then
  710. begin
  711. doconv:=tc_proc_2_procvar;
  712. b:=te_convert_l1;
  713. end;
  714. end;
  715. end;
  716. procvardef :
  717. begin
  718. { procvar -> procvar }
  719. b:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to));
  720. end;
  721. pointerdef :
  722. begin
  723. { nil is compatible with procvars }
  724. if (fromtreetype=niln) then
  725. begin
  726. doconv:=tc_equal;
  727. b:=te_convert_l1;
  728. end
  729. else
  730. { for example delphi allows the assignement from pointers }
  731. { to procedure variables }
  732. if (m_pointer_2_procedure in aktmodeswitches) and
  733. (tpointerdef(def_from).pointertype.def.deftype=orddef) and
  734. (torddef(tpointerdef(def_from).pointertype.def).typ=uvoid) then
  735. begin
  736. doconv:=tc_equal;
  737. b:=te_convert_l1;
  738. end;
  739. end;
  740. end;
  741. end;
  742. objectdef :
  743. begin
  744. { object pascal objects }
  745. if (def_from.deftype=objectdef) and
  746. tobjectdef(def_from).is_related(tobjectdef(def_to)) then
  747. begin
  748. doconv:=tc_equal;
  749. b:=te_convert_l1;
  750. end
  751. else
  752. { Class/interface specific }
  753. if is_class_or_interface(def_to) then
  754. begin
  755. { void pointer also for delphi mode }
  756. if (m_delphi in aktmodeswitches) and
  757. is_voidpointer(def_from) then
  758. begin
  759. doconv:=tc_equal;
  760. b:=te_convert_l1;
  761. end
  762. else
  763. { nil is compatible with class instances and interfaces }
  764. if (fromtreetype=niln) then
  765. begin
  766. doconv:=tc_equal;
  767. b:=te_convert_l1;
  768. end
  769. { classes can be assigned to interfaces }
  770. else if is_interface(def_to) and
  771. is_class(def_from) and
  772. assigned(tobjectdef(def_from).implementedinterfaces) then
  773. begin
  774. { we've to search in parent classes as well }
  775. hd3:=tobjectdef(def_from);
  776. while assigned(hd3) do
  777. begin
  778. if hd3.implementedinterfaces.searchintf(def_to)<>-1 then
  779. begin
  780. doconv:=tc_class_2_intf;
  781. b:=te_convert_l1;
  782. break;
  783. end;
  784. hd3:=hd3.childof;
  785. end;
  786. end
  787. { Interface 2 GUID handling }
  788. else if (def_to=tdef(rec_tguid)) and
  789. (fromtreetype=typen) and
  790. is_interface(def_from) and
  791. assigned(tobjectdef(def_from).iidguid) then
  792. begin
  793. b:=te_convert_l1;
  794. doconv:=tc_equal;
  795. end;
  796. end;
  797. end;
  798. classrefdef :
  799. begin
  800. { similar to pointerdef wrt forwards }
  801. if assigned(def_to.typesym) and
  802. (tclassrefdef(def_to).pointertype.def.deftype=forwarddef) then
  803. begin
  804. if (def_from.typesym=def_to.typesym) then
  805. b:=te_equal;
  806. end
  807. else
  808. { class reference types }
  809. if (def_from.deftype=classrefdef) then
  810. begin
  811. if equal_defs(tclassrefdef(def_from).pointertype.def,tclassrefdef(def_to).pointertype.def) then
  812. begin
  813. b:=te_equal;
  814. end
  815. else
  816. begin
  817. doconv:=tc_equal;
  818. if tobjectdef(tclassrefdef(def_from).pointertype.def).is_related(
  819. tobjectdef(tclassrefdef(def_to).pointertype.def)) then
  820. b:=te_convert_l1;
  821. end;
  822. end
  823. else
  824. { nil is compatible with class references }
  825. if (fromtreetype=niln) then
  826. begin
  827. doconv:=tc_equal;
  828. b:=te_convert_l1;
  829. end;
  830. end;
  831. filedef :
  832. begin
  833. { typed files are all equal to the abstract file type
  834. name TYPEDFILE in system.pp in is_equal in types.pas
  835. the problem is that it sholud be also compatible to FILE
  836. but this would leed to a problem for ASSIGN RESET and REWRITE
  837. when trying to find the good overloaded function !!
  838. so all file function are doubled in system.pp
  839. this is not very beautiful !!}
  840. if (def_from.deftype=filedef) then
  841. begin
  842. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  843. begin
  844. if
  845. (
  846. (tfiledef(def_from).typedfiletype.def=nil) and
  847. (tfiledef(def_to).typedfiletype.def=nil)
  848. ) or
  849. (
  850. (tfiledef(def_from).typedfiletype.def<>nil) and
  851. (tfiledef(def_to).typedfiletype.def<>nil) and
  852. equal_defs(tfiledef(def_from).typedfiletype.def,tfiledef(def_to).typedfiletype.def)
  853. ) or
  854. (
  855. (tfiledef(def_from).filetyp = ft_typed) and
  856. (tfiledef(def_to).filetyp = ft_typed) and
  857. (
  858. (tfiledef(def_from).typedfiletype.def = tdef(voidtype.def)) or
  859. (tfiledef(def_to).typedfiletype.def = tdef(voidtype.def))
  860. )
  861. ) then
  862. begin
  863. b:=te_equal;
  864. end;
  865. end
  866. else
  867. if ((tfiledef(def_from).filetyp = ft_untyped) and
  868. (tfiledef(def_to).filetyp = ft_typed)) or
  869. ((tfiledef(def_from).filetyp = ft_typed) and
  870. (tfiledef(def_to).filetyp = ft_untyped)) then
  871. begin
  872. doconv:=tc_equal;
  873. b:=te_convert_l1;
  874. end;
  875. end;
  876. end;
  877. recorddef :
  878. begin
  879. { interface -> guid }
  880. if is_interface(def_from) and
  881. (def_to=rec_tguid) then
  882. begin
  883. doconv:=tc_intf_2_guid;
  884. b:=te_convert_l1;
  885. end
  886. else
  887. begin
  888. { assignment overwritten ?? }
  889. if check_operator then
  890. begin
  891. operatorpd:=assignment_overloaded(def_from,def_to);
  892. if assigned(operatorpd) then
  893. b:=te_convert_operator;
  894. end;
  895. end;
  896. end;
  897. formaldef :
  898. begin
  899. if (def_from.deftype=formaldef) then
  900. b:=te_equal
  901. else
  902. { Just about everything can be converted to a formaldef...}
  903. if not (def_from.deftype in [abstractdef,errordef]) then
  904. b:=te_convert_l1
  905. else
  906. begin
  907. { assignment overwritten ?? }
  908. if check_operator then
  909. begin
  910. operatorpd:=assignment_overloaded(def_from,def_to);
  911. if assigned(operatorpd) then
  912. b:=te_convert_operator;
  913. end;
  914. end;
  915. end;
  916. end;
  917. { if we didn't find an appropriate type conversion yet, we try the overloaded := operator }
  918. { This is done for variants only yet, maybe we should do this for other types as well (FK) }
  919. if (b=te_incompatible) and
  920. check_operator and
  921. ((def_from.deftype in [variantdef]) or
  922. (def_to.deftype in [variantdef])) then
  923. begin
  924. operatorpd:=assignment_overloaded(def_from,def_to);
  925. if assigned(operatorpd) then
  926. b:=te_convert_operator;
  927. end;
  928. compare_defs_ext:=b;
  929. end;
  930. function equal_defs(def_from,def_to:tdef):boolean;
  931. var
  932. convtyp : tconverttype;
  933. pd : tprocdef;
  934. begin
  935. { Compare defs with nothingn and no explicit typecasts and
  936. searching for overloaded operators is not needed }
  937. equal_defs:=(compare_defs_ext(def_from,def_to,nothingn,false,false,convtyp,pd)>=te_equal);
  938. end;
  939. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  940. var
  941. doconv : tconverttype;
  942. pd : tprocdef;
  943. begin
  944. compare_defs:=compare_defs_ext(def_from,def_to,fromtreetype,false,true,doconv,pd);
  945. end;
  946. function is_subequal(def1, def2: tdef): boolean;
  947. var
  948. basedef1,basedef2 : tenumdef;
  949. Begin
  950. is_subequal := false;
  951. if assigned(def1) and assigned(def2) then
  952. Begin
  953. if (def1.deftype = orddef) and (def2.deftype = orddef) then
  954. Begin
  955. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  956. { range checking for case statements is done with testrange }
  957. case torddef(def1).typ of
  958. u8bit,u16bit,u32bit,u64bit,
  959. s8bit,s16bit,s32bit,s64bit :
  960. is_subequal:=(torddef(def2).typ in [s64bit,u64bit,s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  961. bool8bit,bool16bit,bool32bit :
  962. is_subequal:=(torddef(def2).typ in [bool8bit,bool16bit,bool32bit]);
  963. uchar :
  964. is_subequal:=(torddef(def2).typ=uchar);
  965. uwidechar :
  966. is_subequal:=(torddef(def2).typ=uwidechar);
  967. end;
  968. end
  969. else
  970. Begin
  971. { Check if both basedefs are equal }
  972. if (def1.deftype=enumdef) and (def2.deftype=enumdef) then
  973. Begin
  974. { get both basedefs }
  975. basedef1:=tenumdef(def1);
  976. while assigned(basedef1.basedef) do
  977. basedef1:=basedef1.basedef;
  978. basedef2:=tenumdef(def2);
  979. while assigned(basedef2.basedef) do
  980. basedef2:=basedef2.basedef;
  981. is_subequal:=(basedef1=basedef2);
  982. end;
  983. end;
  984. end;
  985. end;
  986. function compare_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean):tequaltype;
  987. var
  988. def1,def2 : TParaItem;
  989. eq,lowesteq : tequaltype;
  990. hpd : tprocdef;
  991. convtype : tconverttype;
  992. begin
  993. compare_paras:=te_incompatible;
  994. { we need to parse the list from left-right so the
  995. not-default parameters are checked first }
  996. lowesteq:=high(tequaltype);
  997. def1:=TParaItem(paralist1.last);
  998. def2:=TParaItem(paralist2.last);
  999. while (assigned(def1)) and (assigned(def2)) do
  1000. begin
  1001. eq:=te_incompatible;
  1002. case acp of
  1003. cp_value_equal_const :
  1004. begin
  1005. if (
  1006. (def1.paratyp<>def2.paratyp) and
  1007. ((def1.paratyp in [vs_var,vs_out]) or
  1008. (def2.paratyp in [vs_var,vs_out]))
  1009. ) then
  1010. exit;
  1011. eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
  1012. end;
  1013. cp_all :
  1014. begin
  1015. if (def1.paratyp<>def2.paratyp) then
  1016. exit;
  1017. eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
  1018. end;
  1019. cp_procvar :
  1020. begin
  1021. if (def1.paratyp<>def2.paratyp) then
  1022. exit;
  1023. eq:=compare_defs_ext(def1.paratype.def,def2.paratype.def,nothingn,
  1024. false,true,convtype,hpd);
  1025. if (eq>te_incompatible) and
  1026. (eq<te_equal) and
  1027. not(convtype in [tc_equal,tc_int_2_int]) then
  1028. begin
  1029. eq:=te_incompatible;
  1030. end;
  1031. end;
  1032. else
  1033. eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
  1034. end;
  1035. { check type }
  1036. if eq=te_incompatible then
  1037. exit;
  1038. if eq<lowesteq then
  1039. lowesteq:=eq;
  1040. { also check default value if both have it declared }
  1041. if assigned(def1.defaultvalue) and
  1042. assigned(def2.defaultvalue) then
  1043. begin
  1044. if not equal_constsym(tconstsym(def1.defaultvalue),tconstsym(def2.defaultvalue)) then
  1045. exit;
  1046. end;
  1047. def1:=TParaItem(def1.previous);
  1048. def2:=TParaItem(def2.previous);
  1049. end;
  1050. { when both lists are empty then the parameters are equal. Also
  1051. when one list is empty and the other has a parameter with default
  1052. value assigned then the parameters are also equal }
  1053. if ((def1=nil) and (def2=nil)) or
  1054. (allowdefaults and
  1055. ((assigned(def1) and assigned(def1.defaultvalue)) or
  1056. (assigned(def2) and assigned(def2.defaultvalue)))) then
  1057. compare_paras:=lowesteq;
  1058. end;
  1059. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  1060. const
  1061. po_comp = po_compatibility_options-[po_methodpointer,po_classmethod];
  1062. var
  1063. ismethod : boolean;
  1064. begin
  1065. proc_to_procvar_equal:=te_incompatible;
  1066. if not(assigned(def1)) or not(assigned(def2)) then
  1067. exit;
  1068. { check for method pointer }
  1069. if def1.deftype=procvardef then
  1070. begin
  1071. ismethod:=(po_methodpointer in def1.procoptions);
  1072. end
  1073. else
  1074. begin
  1075. ismethod:=assigned(def1.owner) and
  1076. (def1.owner.symtabletype=objectsymtable);
  1077. end;
  1078. if (ismethod and not (po_methodpointer in def2.procoptions)) or
  1079. (not(ismethod) and (po_methodpointer in def2.procoptions)) then
  1080. begin
  1081. Message(type_e_no_method_and_procedure_not_compatible);
  1082. exit;
  1083. end;
  1084. { check return value and options, methodpointer is already checked }
  1085. if ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1086. equal_defs(def1.rettype.def,def2.rettype.def) and
  1087. (def1.para_size(target_info.alignment.paraalign)=def2.para_size(target_info.alignment.paraalign)) then
  1088. begin
  1089. { return equal type based on the parameters }
  1090. proc_to_procvar_equal:=compare_paras(def1.para,def2.para,cp_procvar,false);
  1091. end;
  1092. end;
  1093. function is_equal(def1,def2 : tdef) : boolean;
  1094. var
  1095. doconv : tconverttype;
  1096. hpd : tprocdef;
  1097. begin
  1098. is_equal:=(compare_defs_ext(def1,def2,nothingn,false,true,doconv,hpd)>=te_equal);
  1099. end;
  1100. function equal_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean) : boolean;
  1101. begin
  1102. equal_paras:=(compare_paras(paralist1,paralist2,acp,allowdefaults)>=te_equal);
  1103. end;
  1104. end.
  1105. {
  1106. $Log$
  1107. Revision 1.6 2002-12-06 17:49:44 peter
  1108. * prefer string-shortstring over other string-string conversions
  1109. Revision 1.5 2002/12/05 14:27:26 florian
  1110. * some variant <-> dyn. array stuff
  1111. Revision 1.4 2002/12/01 22:07:41 carl
  1112. * warning of portabilitiy problems with parasize / localsize
  1113. + some added documentation
  1114. Revision 1.3 2002/11/27 15:33:46 peter
  1115. * the never ending story of tp procvar hacks
  1116. Revision 1.2 2002/11/27 02:32:14 peter
  1117. * fix cp_procvar compare
  1118. Revision 1.1 2002/11/25 17:43:16 peter
  1119. * splitted defbase in defutil,symutil,defcmp
  1120. * merged isconvertable and is_equal into compare_defs(_ext)
  1121. * made operator search faster by walking the list only once
  1122. }