defcmp.pas 55 KB

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