defcmp.pas 50 KB

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