defcmp.pas 49 KB

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