defcmp.pas 54 KB

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