defcmp.pas 46 KB

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