defcmp.pas 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244
  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_not_possible),
  143. (tc_not_possible,tc_not_possible,tc_not_possible,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. subeq,eq : 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. eq:=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. eq:=te_equal
  188. else
  189. eq:=te_convert_l1;
  190. end;
  191. uvoid,uchar,uwidechar,
  192. bool8bit,bool16bit,bool32bit:
  193. eq:=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. eq:=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. eq:=te_convert_l2
  211. else
  212. eq:=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. eq:=te_convert_l1;
  222. end;
  223. end;
  224. classrefdef,
  225. procvardef,
  226. pointerdef :
  227. begin
  228. if explicit then
  229. begin
  230. eq:=te_convert_l1;
  231. if (fromtreetype=niln) then
  232. begin
  233. { will be handled by the constant folding }
  234. doconv:=tc_equal;
  235. end
  236. else
  237. doconv:=tc_int_2_int;
  238. end;
  239. end;
  240. end;
  241. end;
  242. stringdef :
  243. begin
  244. case def_from.deftype of
  245. stringdef :
  246. begin
  247. { Constant string }
  248. if (fromtreetype=stringconstn) then
  249. begin
  250. if (tstringdef(def_from).string_typ=tstringdef(def_to).string_typ) then
  251. eq:=te_equal
  252. else
  253. begin
  254. doconv:=tc_string_2_string;
  255. { Don't prefer conversions from widestring to a
  256. normal string as we can loose information }
  257. if is_widestring(def_from) then
  258. eq:=te_convert_l1
  259. else
  260. eq:=te_convert_l2;
  261. end;
  262. end
  263. else
  264. { Same string type, for shortstrings also the length must match }
  265. if (tstringdef(def_from).string_typ=tstringdef(def_to).string_typ) and
  266. ((tstringdef(def_from).string_typ<>st_shortstring) or
  267. (tstringdef(def_from).len=tstringdef(def_to).len)) then
  268. eq:=te_equal
  269. else
  270. begin
  271. doconv:=tc_string_2_string;
  272. { Prefer conversions to shortstring over other
  273. conversions. This is compatible with Delphi (PFV) }
  274. if tstringdef(def_to).string_typ=st_shortstring then
  275. eq:=te_convert_l1
  276. else
  277. eq:=te_convert_l2;
  278. end;
  279. end;
  280. orddef :
  281. begin
  282. { char to string}
  283. if is_char(def_from) or
  284. is_widechar(def_from) then
  285. begin
  286. doconv:=tc_char_2_string;
  287. eq:=te_convert_l1;
  288. end;
  289. end;
  290. arraydef :
  291. begin
  292. { array of char to string, the length check is done by the firstpass of this node }
  293. if is_chararray(def_from) or
  294. (is_char(tarraydef(def_from).elementtype.def) and
  295. is_open_array(def_from)) then
  296. begin
  297. doconv:=tc_chararray_2_string;
  298. if is_open_array(def_from) or
  299. (is_shortstring(def_to) and
  300. (def_from.size <= 255)) or
  301. (is_ansistring(def_to) and
  302. (def_from.size > 255)) then
  303. eq:=te_convert_l1
  304. else
  305. eq:=te_convert_l2;
  306. end;
  307. end;
  308. pointerdef :
  309. begin
  310. { pchar can be assigned to short/ansistrings,
  311. but not in tp7 compatible mode }
  312. if not(m_tp7 in aktmodeswitches) then
  313. begin
  314. if is_pchar(def_from) then
  315. begin
  316. doconv:=tc_pchar_2_string;
  317. { trefer ansistrings because pchars can overflow shortstrings, }
  318. { but only if ansistrings are the default (JM) }
  319. if (is_shortstring(def_to) and
  320. not(cs_ansistrings in aktlocalswitches)) or
  321. (is_ansistring(def_to) and
  322. (cs_ansistrings in aktlocalswitches)) then
  323. eq:=te_convert_l1
  324. else
  325. eq:=te_convert_l2;
  326. end
  327. else if is_pwidechar(def_from) then
  328. begin
  329. doconv:=tc_pwchar_2_string;
  330. { trefer ansistrings because pchars can overflow shortstrings, }
  331. { but only if ansistrings are the default (JM) }
  332. if is_widestring(def_to) then
  333. eq:=te_convert_l1
  334. else
  335. eq:=te_convert_l2;
  336. end;
  337. end;
  338. end;
  339. end;
  340. end;
  341. floatdef :
  342. begin
  343. case def_from.deftype of
  344. orddef :
  345. begin { ordinal to real }
  346. if is_integer(def_from) then
  347. begin
  348. doconv:=tc_int_2_real;
  349. eq:=te_convert_l1;
  350. end;
  351. end;
  352. floatdef :
  353. begin
  354. if tfloatdef(def_from).typ=tfloatdef(def_to).typ then
  355. eq:=te_equal
  356. else
  357. begin
  358. doconv:=tc_real_2_real;
  359. eq:=te_convert_l1;
  360. end;
  361. end;
  362. end;
  363. end;
  364. enumdef :
  365. begin
  366. case def_from.deftype of
  367. enumdef :
  368. begin
  369. if explicit then
  370. begin
  371. eq:=te_convert_l1;
  372. doconv:=tc_int_2_int;
  373. end
  374. else
  375. begin
  376. hd1:=def_from;
  377. while assigned(tenumdef(hd1).basedef) do
  378. hd1:=tenumdef(hd1).basedef;
  379. hd2:=def_to;
  380. while assigned(tenumdef(hd2).basedef) do
  381. hd2:=tenumdef(hd2).basedef;
  382. if (hd1=hd2) then
  383. begin
  384. eq:=te_convert_l1;
  385. { because of packenum they can have different sizes! (JM) }
  386. doconv:=tc_int_2_int;
  387. end;
  388. end;
  389. end;
  390. orddef :
  391. begin
  392. if explicit then
  393. begin
  394. eq:=te_convert_l1;
  395. doconv:=tc_int_2_int;
  396. end;
  397. end;
  398. end;
  399. end;
  400. arraydef :
  401. begin
  402. { open array is also compatible with a single element of its base type }
  403. if is_open_array(def_to) and
  404. equal_defs(def_from,tarraydef(def_to).elementtype.def) then
  405. begin
  406. doconv:=tc_equal;
  407. eq:=te_convert_l1;
  408. end
  409. else
  410. begin
  411. case def_from.deftype of
  412. arraydef :
  413. begin
  414. { to dynamic array }
  415. if is_dynamic_array(def_to) then
  416. begin
  417. { dynamic array -> dynamic array }
  418. if is_dynamic_array(def_from) and
  419. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  420. eq:=te_equal;
  421. end
  422. else
  423. { to open array }
  424. if is_open_array(def_to) then
  425. begin
  426. { array constructor -> open array }
  427. if is_array_constructor(def_from) then
  428. begin
  429. if is_void(tarraydef(def_from).elementtype.def) then
  430. begin
  431. doconv:=tc_equal;
  432. eq:=te_convert_l1;
  433. end
  434. else
  435. begin
  436. subeq:=compare_defs_ext(tarraydef(def_from).elementtype.def,
  437. tarraydef(def_to).elementtype.def,
  438. arrayconstructorn,false,true,hct,hpd);
  439. if (subeq>=te_equal) then
  440. begin
  441. doconv:=tc_equal;
  442. eq:=te_convert_l1;
  443. end
  444. else
  445. if (subeq>te_incompatible) then
  446. begin
  447. doconv:=hct;
  448. eq:=te_convert_l2;
  449. end;
  450. end;
  451. end
  452. else
  453. { dynamic array -> open array }
  454. if is_dynamic_array(def_from) and
  455. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  456. begin
  457. doconv:=tc_dynarray_2_openarray;
  458. eq:=te_convert_l2;
  459. end
  460. else
  461. { array -> open array }
  462. if equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  463. eq:=te_equal;
  464. end
  465. else
  466. { to array of const }
  467. if is_array_of_const(def_to) then
  468. begin
  469. if is_array_of_const(def_from) or
  470. is_array_constructor(def_from) then
  471. begin
  472. eq:=te_equal;
  473. end
  474. else
  475. { array of tvarrec -> array of const }
  476. if equal_defs(tarraydef(def_to).elementtype.def,tarraydef(def_from).elementtype.def) then
  477. begin
  478. doconv:=tc_equal;
  479. eq:=te_convert_l1;
  480. end;
  481. end
  482. else
  483. { other arrays }
  484. begin
  485. { open array -> array }
  486. if is_open_array(def_from) and
  487. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) then
  488. begin
  489. eq:=te_equal
  490. end
  491. else
  492. { array -> array }
  493. if not(m_tp7 in aktmodeswitches) and
  494. not(m_delphi in aktmodeswitches) and
  495. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  496. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  497. equal_defs(tarraydef(def_from).elementtype.def,tarraydef(def_to).elementtype.def) and
  498. equal_defs(tarraydef(def_from).rangetype.def,tarraydef(def_to).rangetype.def) then
  499. begin
  500. eq:=te_equal
  501. end;
  502. end;
  503. end;
  504. pointerdef :
  505. begin
  506. { nil is compatible with dyn. arrays }
  507. if is_dynamic_array(def_to) and
  508. (fromtreetype=niln) then
  509. begin
  510. doconv:=tc_equal;
  511. eq:=te_convert_l1;
  512. end
  513. else
  514. if is_zero_based_array(def_to) and
  515. equal_defs(tpointerdef(def_from).pointertype.def,tarraydef(def_to).elementtype.def) then
  516. begin
  517. doconv:=tc_pointer_2_array;
  518. eq:=te_convert_l1;
  519. end;
  520. end;
  521. stringdef :
  522. begin
  523. { string to char array }
  524. if (not is_special_array(def_to)) and
  525. is_char(tarraydef(def_to).elementtype.def) then
  526. begin
  527. doconv:=tc_string_2_chararray;
  528. eq:=te_convert_l1;
  529. end;
  530. end;
  531. orddef:
  532. begin
  533. if is_chararray(def_to) and
  534. is_char(def_from) then
  535. begin
  536. doconv:=tc_char_2_chararray;
  537. eq:=te_convert_l2;
  538. end;
  539. end;
  540. recorddef :
  541. begin
  542. { tvarrec -> array of const }
  543. if is_array_of_const(def_to) and
  544. equal_defs(def_from,tarraydef(def_to).elementtype.def) then
  545. begin
  546. doconv:=tc_equal;
  547. eq:=te_convert_l1;
  548. end;
  549. end;
  550. variantdef :
  551. begin
  552. if is_dynamic_array(def_to) then
  553. begin
  554. doconv:=tc_variant_2_dynarray;
  555. eq:=te_convert_l1;
  556. end;
  557. end;
  558. end;
  559. end;
  560. end;
  561. pointerdef :
  562. begin
  563. case def_from.deftype of
  564. stringdef :
  565. begin
  566. { string constant (which can be part of array constructor)
  567. to zero terminated string constant }
  568. if (fromtreetype in [arrayconstructorn,stringconstn]) and
  569. (is_pchar(def_to) or is_pwidechar(def_to)) then
  570. begin
  571. doconv:=tc_cstring_2_pchar;
  572. eq:=te_convert_l1;
  573. end
  574. else
  575. if explicit then
  576. begin
  577. { pchar(ansistring) }
  578. if is_pchar(def_to) and
  579. is_ansistring(def_from) then
  580. begin
  581. doconv:=tc_ansistring_2_pchar;
  582. eq:=te_convert_l1;
  583. end
  584. else
  585. { pwidechar(ansistring) }
  586. if is_pwidechar(def_to) and
  587. is_widestring(def_from) then
  588. begin
  589. doconv:=tc_ansistring_2_pchar;
  590. eq:=te_convert_l1;
  591. end;
  592. end;
  593. end;
  594. orddef :
  595. begin
  596. { char constant to zero terminated string constant }
  597. if (fromtreetype=ordconstn) then
  598. begin
  599. if is_char(def_from) and
  600. is_pchar(def_to) then
  601. begin
  602. doconv:=tc_cchar_2_pchar;
  603. eq:=te_convert_l1;
  604. end
  605. else
  606. if is_integer(def_from) then
  607. begin
  608. doconv:=tc_cord_2_pointer;
  609. eq:=te_convert_l1;
  610. end;
  611. end;
  612. if (eq=te_incompatible) and
  613. explicit and
  614. (m_delphi in aktmodeswitches) then
  615. begin
  616. doconv:=tc_int_2_int;
  617. eq:=te_convert_l1;
  618. end;
  619. end;
  620. arraydef :
  621. begin
  622. { chararray to pointer }
  623. if is_zero_based_array(def_from) and
  624. equal_defs(tarraydef(def_from).elementtype.def,tpointerdef(def_to).pointertype.def) then
  625. begin
  626. doconv:=tc_array_2_pointer;
  627. eq:=te_convert_l1;
  628. end;
  629. end;
  630. pointerdef :
  631. begin
  632. { check for far pointers }
  633. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  634. begin
  635. eq:=te_incompatible;
  636. end
  637. else
  638. { the types can be forward type, handle before normal type check !! }
  639. if assigned(def_to.typesym) and
  640. (tpointerdef(def_to).pointertype.def.deftype=forwarddef) then
  641. begin
  642. if (def_from.typesym=def_to.typesym) then
  643. eq:=te_equal
  644. end
  645. else
  646. { same types }
  647. if (tpointerdef(def_from).pointertype.def=tpointerdef(def_to).pointertype.def) then
  648. begin
  649. eq:=te_equal
  650. end
  651. else
  652. { child class pointer can be assigned to anchestor pointers }
  653. if (
  654. (tpointerdef(def_from).pointertype.def.deftype=objectdef) and
  655. (tpointerdef(def_to).pointertype.def.deftype=objectdef) and
  656. tobjectdef(tpointerdef(def_from).pointertype.def).is_related(
  657. tobjectdef(tpointerdef(def_to).pointertype.def))
  658. ) or
  659. { all pointers can be assigned to/from void-pointer }
  660. is_void(tpointerdef(def_to).pointertype.def) or
  661. is_void(tpointerdef(def_from).pointertype.def) then
  662. begin
  663. doconv:=tc_equal;
  664. { give pwidechar a small penalty }
  665. if is_pwidechar(def_to) then
  666. eq:=te_convert_l2
  667. else
  668. eq:=te_convert_l1;
  669. end;
  670. end;
  671. procvardef :
  672. begin
  673. { procedure variable can be assigned to an void pointer }
  674. { Not anymore. Use the @ operator now.}
  675. if not(m_tp_procvar in aktmodeswitches) and
  676. (tpointerdef(def_to).pointertype.def.deftype=orddef) and
  677. (torddef(tpointerdef(def_to).pointertype.def).typ=uvoid) then
  678. begin
  679. doconv:=tc_equal;
  680. eq:=te_convert_l1;
  681. end;
  682. end;
  683. classrefdef,
  684. objectdef :
  685. begin
  686. { class types and class reference type
  687. can be assigned to void pointers }
  688. if (
  689. is_class_or_interface(def_from) or
  690. (def_from.deftype=classrefdef)
  691. ) and
  692. (tpointerdef(def_to).pointertype.def.deftype=orddef) and
  693. (torddef(tpointerdef(def_to).pointertype.def).typ=uvoid) then
  694. begin
  695. doconv:=tc_equal;
  696. eq:=te_convert_l1;
  697. end;
  698. end;
  699. end;
  700. end;
  701. setdef :
  702. begin
  703. case def_from.deftype of
  704. setdef :
  705. begin
  706. if assigned(tsetdef(def_from).elementtype.def) and
  707. assigned(tsetdef(def_to).elementtype.def) then
  708. begin
  709. { sets with the same element base type are equal }
  710. if is_subequal(tsetdef(def_from).elementtype.def,tsetdef(def_to).elementtype.def) then
  711. eq:=te_equal;
  712. end
  713. else
  714. { empty set is compatible with everything }
  715. eq:=te_equal;
  716. end;
  717. arraydef :
  718. begin
  719. { automatic arrayconstructor -> set conversion }
  720. if is_array_constructor(def_from) then
  721. begin
  722. doconv:=tc_arrayconstructor_2_set;
  723. eq:=te_convert_l1;
  724. end;
  725. end;
  726. end;
  727. end;
  728. procvardef :
  729. begin
  730. case def_from.deftype of
  731. procdef :
  732. begin
  733. { proc -> procvar }
  734. if (m_tp_procvar in aktmodeswitches) then
  735. begin
  736. subeq:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to));
  737. if subeq>te_incompatible then
  738. begin
  739. doconv:=tc_proc_2_procvar;
  740. eq:=te_convert_l1;
  741. end;
  742. end;
  743. end;
  744. procvardef :
  745. begin
  746. { procvar -> procvar }
  747. eq:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to));
  748. end;
  749. pointerdef :
  750. begin
  751. { nil is compatible with procvars }
  752. if (fromtreetype=niln) then
  753. begin
  754. doconv:=tc_equal;
  755. eq:=te_convert_l1;
  756. end
  757. else
  758. { for example delphi allows the assignement from pointers }
  759. { to procedure variables }
  760. if (m_pointer_2_procedure in aktmodeswitches) and
  761. (tpointerdef(def_from).pointertype.def.deftype=orddef) and
  762. (torddef(tpointerdef(def_from).pointertype.def).typ=uvoid) then
  763. begin
  764. doconv:=tc_equal;
  765. eq:=te_convert_l1;
  766. end;
  767. end;
  768. end;
  769. end;
  770. objectdef :
  771. begin
  772. { object pascal objects }
  773. if (def_from.deftype=objectdef) and
  774. tobjectdef(def_from).is_related(tobjectdef(def_to)) then
  775. begin
  776. doconv:=tc_equal;
  777. eq:=te_convert_l1;
  778. end
  779. else
  780. { Class/interface specific }
  781. if is_class_or_interface(def_to) then
  782. begin
  783. { void pointer also for delphi mode }
  784. if (m_delphi in aktmodeswitches) and
  785. is_voidpointer(def_from) then
  786. begin
  787. doconv:=tc_equal;
  788. eq:=te_convert_l1;
  789. end
  790. else
  791. { nil is compatible with class instances and interfaces }
  792. if (fromtreetype=niln) then
  793. begin
  794. doconv:=tc_equal;
  795. eq:=te_convert_l1;
  796. end
  797. { classes can be assigned to interfaces }
  798. else if is_interface(def_to) and
  799. is_class(def_from) and
  800. assigned(tobjectdef(def_from).implementedinterfaces) then
  801. begin
  802. { we've to search in parent classes as well }
  803. hd3:=tobjectdef(def_from);
  804. while assigned(hd3) do
  805. begin
  806. if hd3.implementedinterfaces.searchintf(def_to)<>-1 then
  807. begin
  808. doconv:=tc_class_2_intf;
  809. eq:=te_convert_l1;
  810. break;
  811. end;
  812. hd3:=hd3.childof;
  813. end;
  814. end
  815. { Interface 2 GUID handling }
  816. else if (def_to=tdef(rec_tguid)) and
  817. (fromtreetype=typen) and
  818. is_interface(def_from) and
  819. assigned(tobjectdef(def_from).iidguid) then
  820. begin
  821. eq:=te_convert_l1;
  822. doconv:=tc_equal;
  823. end;
  824. end;
  825. end;
  826. classrefdef :
  827. begin
  828. { similar to pointerdef wrt forwards }
  829. if assigned(def_to.typesym) and
  830. (tclassrefdef(def_to).pointertype.def.deftype=forwarddef) then
  831. begin
  832. if (def_from.typesym=def_to.typesym) then
  833. eq:=te_equal;
  834. end
  835. else
  836. { class reference types }
  837. if (def_from.deftype=classrefdef) then
  838. begin
  839. if equal_defs(tclassrefdef(def_from).pointertype.def,tclassrefdef(def_to).pointertype.def) then
  840. begin
  841. eq:=te_equal;
  842. end
  843. else
  844. begin
  845. doconv:=tc_equal;
  846. if explicit or
  847. tobjectdef(tclassrefdef(def_from).pointertype.def).is_related(
  848. tobjectdef(tclassrefdef(def_to).pointertype.def)) then
  849. eq:=te_convert_l1;
  850. end;
  851. end
  852. else
  853. { nil is compatible with class references }
  854. if (fromtreetype=niln) then
  855. begin
  856. doconv:=tc_equal;
  857. eq:=te_convert_l1;
  858. end;
  859. end;
  860. filedef :
  861. begin
  862. { typed files are all equal to the abstract file type
  863. name TYPEDFILE in system.pp in is_equal in types.pas
  864. the problem is that it sholud be also compatible to FILE
  865. but this would leed to a problem for ASSIGN RESET and REWRITE
  866. when trying to find the good overloaded function !!
  867. so all file function are doubled in system.pp
  868. this is not very beautiful !!}
  869. if (def_from.deftype=filedef) then
  870. begin
  871. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  872. begin
  873. if
  874. (
  875. (tfiledef(def_from).typedfiletype.def=nil) and
  876. (tfiledef(def_to).typedfiletype.def=nil)
  877. ) or
  878. (
  879. (tfiledef(def_from).typedfiletype.def<>nil) and
  880. (tfiledef(def_to).typedfiletype.def<>nil) and
  881. equal_defs(tfiledef(def_from).typedfiletype.def,tfiledef(def_to).typedfiletype.def)
  882. ) or
  883. (
  884. (tfiledef(def_from).filetyp = ft_typed) and
  885. (tfiledef(def_to).filetyp = ft_typed) and
  886. (
  887. (tfiledef(def_from).typedfiletype.def = tdef(voidtype.def)) or
  888. (tfiledef(def_to).typedfiletype.def = tdef(voidtype.def))
  889. )
  890. ) then
  891. begin
  892. eq:=te_equal;
  893. end;
  894. end
  895. else
  896. if ((tfiledef(def_from).filetyp = ft_untyped) and
  897. (tfiledef(def_to).filetyp = ft_typed)) or
  898. ((tfiledef(def_from).filetyp = ft_typed) and
  899. (tfiledef(def_to).filetyp = ft_untyped)) then
  900. begin
  901. doconv:=tc_equal;
  902. eq:=te_convert_l1;
  903. end;
  904. end;
  905. end;
  906. recorddef :
  907. begin
  908. { interface -> guid }
  909. if is_interface(def_from) and
  910. (def_to=rec_tguid) then
  911. begin
  912. doconv:=tc_intf_2_guid;
  913. eq:=te_convert_l1;
  914. end;
  915. end;
  916. formaldef :
  917. begin
  918. if (def_from.deftype=formaldef) then
  919. eq:=te_equal
  920. else
  921. { Just about everything can be converted to a formaldef...}
  922. if not (def_from.deftype in [abstractdef,errordef]) then
  923. eq:=te_convert_l1;
  924. end;
  925. end;
  926. { if we didn't find an appropriate type conversion yet and
  927. there is a variant involved then we search also the := operator }
  928. if (eq=te_incompatible) and
  929. check_operator and
  930. ((def_from.deftype in [objectdef,recorddef,arraydef,stringdef,variantdef]) or
  931. (def_to.deftype in [objectdef,recorddef,arraydef,stringdef,variantdef])) then
  932. begin
  933. operatorpd:=assignment_overloaded(def_from,def_to);
  934. if assigned(operatorpd) then
  935. eq:=te_convert_operator;
  936. end;
  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.last);
  1007. def2:=TParaItem(paralist2.last);
  1008. while (assigned(def1)) and (assigned(def2)) do
  1009. begin
  1010. eq:=te_incompatible;
  1011. if (df_unique in def1.paratype.def.defoptions) or (df_unique in def2.paratype.def.defoptions) then
  1012. exit;
  1013. case acp of
  1014. cp_value_equal_const :
  1015. begin
  1016. if (
  1017. (def1.paratyp<>def2.paratyp) and
  1018. ((def1.paratyp in [vs_var,vs_out]) or
  1019. (def2.paratyp in [vs_var,vs_out]))
  1020. ) then
  1021. exit;
  1022. eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
  1023. end;
  1024. cp_all :
  1025. begin
  1026. if (def1.paratyp<>def2.paratyp) then
  1027. exit;
  1028. eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
  1029. end;
  1030. cp_procvar :
  1031. begin
  1032. if (def1.paratyp<>def2.paratyp) then
  1033. exit;
  1034. eq:=compare_defs_ext(def1.paratype.def,def2.paratype.def,nothingn,
  1035. false,true,convtype,hpd);
  1036. if (eq>te_incompatible) and
  1037. (eq<te_equal) and
  1038. not(
  1039. (convtype in [tc_equal,tc_int_2_int]) and
  1040. (def1.paratype.def.size=def2.paratype.def.size)
  1041. ) then
  1042. begin
  1043. eq:=te_incompatible;
  1044. end;
  1045. end;
  1046. else
  1047. eq:=compare_defs(def1.paratype.def,def2.paratype.def,nothingn);
  1048. end;
  1049. { check type }
  1050. if eq=te_incompatible then
  1051. exit;
  1052. if eq<lowesteq then
  1053. lowesteq:=eq;
  1054. { also check default value if both have it declared }
  1055. if assigned(def1.defaultvalue) and
  1056. assigned(def2.defaultvalue) then
  1057. begin
  1058. if not equal_constsym(tconstsym(def1.defaultvalue),tconstsym(def2.defaultvalue)) then
  1059. exit;
  1060. end;
  1061. def1:=TParaItem(def1.previous);
  1062. def2:=TParaItem(def2.previous);
  1063. end;
  1064. { when both lists are empty then the parameters are equal. Also
  1065. when one list is empty and the other has a parameter with default
  1066. value assigned then the parameters are also equal }
  1067. if ((def1=nil) and (def2=nil)) or
  1068. (allowdefaults and
  1069. ((assigned(def1) and assigned(def1.defaultvalue)) or
  1070. (assigned(def2) and assigned(def2.defaultvalue)))) then
  1071. compare_paras:=lowesteq;
  1072. end;
  1073. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  1074. var
  1075. ismethod : boolean;
  1076. eq : tequaltype;
  1077. po_comp : tprocoptions;
  1078. begin
  1079. proc_to_procvar_equal:=te_incompatible;
  1080. if not(assigned(def1)) or not(assigned(def2)) then
  1081. exit;
  1082. { check for method pointer }
  1083. if def1.deftype=procvardef then
  1084. begin
  1085. ismethod:=(po_methodpointer in def1.procoptions);
  1086. end
  1087. else
  1088. begin
  1089. ismethod:=assigned(def1.owner) and
  1090. (def1.owner.symtabletype=objectsymtable);
  1091. end;
  1092. if (ismethod and not (po_methodpointer in def2.procoptions)) or
  1093. (not(ismethod) and (po_methodpointer in def2.procoptions)) then
  1094. begin
  1095. Message(type_e_no_method_and_procedure_not_compatible);
  1096. exit;
  1097. end;
  1098. { check return value and options, methodpointer is already checked }
  1099. po_comp:=po_compatibility_options-[po_methodpointer];
  1100. if (m_delphi in aktmodeswitches) then
  1101. exclude(po_comp,po_varargs);
  1102. if ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1103. equal_defs(def1.rettype.def,def2.rettype.def) and
  1104. (def1.para_size(target_info.alignment.paraalign)=def2.para_size(target_info.alignment.paraalign)) then
  1105. begin
  1106. { return equal type based on the parameters, but a proc->procvar
  1107. is never exact, so map an exact match of the parameters to
  1108. te_equal }
  1109. eq:=compare_paras(def1.para,def2.para,cp_procvar,false);
  1110. if eq=te_exact then
  1111. eq:=te_equal;
  1112. proc_to_procvar_equal:=eq;
  1113. end;
  1114. end;
  1115. function is_equal(def1,def2 : tdef) : boolean;
  1116. var
  1117. doconv : tconverttype;
  1118. hpd : tprocdef;
  1119. begin
  1120. is_equal:=(compare_defs_ext(def1,def2,nothingn,false,true,doconv,hpd)>=te_equal);
  1121. end;
  1122. function equal_paras(paralist1,paralist2 : TLinkedList; acp : compare_type;allowdefaults:boolean) : boolean;
  1123. begin
  1124. equal_paras:=(compare_paras(paralist1,paralist2,acp,allowdefaults)>=te_equal);
  1125. end;
  1126. end.
  1127. {
  1128. $Log$
  1129. Revision 1.16 2003-01-05 22:42:13 peter
  1130. * use int_to_int conversion for pointer/procvar/classref to int
  1131. Revision 1.15 2003/01/05 15:54:15 florian
  1132. + added proper support of type = type <type>; for simple types
  1133. Revision 1.14 2003/01/03 17:16:04 peter
  1134. * fixed assignment operator checking for typecast
  1135. Revision 1.13 2002/12/29 18:15:19 peter
  1136. * varargs is not checked in proc->procvar for delphi
  1137. Revision 1.12 2002/12/29 14:57:50 peter
  1138. * unit loading changed to first register units and load them
  1139. afterwards. This is needed to support uses xxx in yyy correctly
  1140. * unit dependency check fixed
  1141. Revision 1.11 2002/12/27 15:26:12 peter
  1142. * procvar compare with 2 ints did not check the integer size
  1143. Revision 1.10 2002/12/23 22:22:16 peter
  1144. * don't allow implicit bool->int conversion
  1145. Revision 1.9 2002/12/18 21:37:36 peter
  1146. * allow classref-classref always when explicit
  1147. Revision 1.8 2002/12/15 22:37:53 peter
  1148. * give conversions from pointer to pwidechar a penalty (=prefer pchar)
  1149. Revision 1.7 2002/12/11 22:40:12 peter
  1150. * proc->procvar is never an exact match, convert exact parameters
  1151. to equal for the whole proc to procvar conversion level
  1152. Revision 1.6 2002/12/06 17:49:44 peter
  1153. * prefer string-shortstring over other string-string conversions
  1154. Revision 1.5 2002/12/05 14:27:26 florian
  1155. * some variant <-> dyn. array stuff
  1156. Revision 1.4 2002/12/01 22:07:41 carl
  1157. * warning of portabilitiy problems with parasize / localsize
  1158. + some added documentation
  1159. Revision 1.3 2002/11/27 15:33:46 peter
  1160. * the never ending story of tp procvar hacks
  1161. Revision 1.2 2002/11/27 02:32:14 peter
  1162. * fix cp_procvar compare
  1163. Revision 1.1 2002/11/25 17:43:16 peter
  1164. * splitted defbase in defutil,symutil,defcmp
  1165. * merged isconvertable and is_equal into compare_defs(_ext)
  1166. * made operator search faster by walking the list only once
  1167. }