defcmp.pas 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Compare definitions and parameter lists
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit defcmp;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,
  22. globtype,globals,
  23. node,
  24. symconst,symtype,symdef;
  25. type
  26. { if acp is cp_all the var const or nothing are considered equal }
  27. tcompare_paras_type = ( cp_none, cp_value_equal_const, cp_all,cp_procvar);
  28. tcompare_paras_option = (cpo_allowdefaults,cpo_ignorehidden,cpo_allowconvert,cpo_comparedefaultvalue);
  29. tcompare_paras_options = set of tcompare_paras_option;
  30. tcompare_defs_option = (cdo_internal,cdo_explicit,cdo_check_operator,cdo_allow_variant,cdo_parameter);
  31. tcompare_defs_options = set of tcompare_defs_option;
  32. tconverttype = (tc_none,
  33. tc_equal,
  34. tc_not_possible,
  35. tc_string_2_string,
  36. tc_char_2_string,
  37. tc_char_2_chararray,
  38. tc_pchar_2_string,
  39. tc_cchar_2_pchar,
  40. tc_cstring_2_pchar,
  41. tc_cstring_2_int,
  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_nil_2_methodprocvar,
  56. tc_arrayconstructor_2_set,
  57. tc_set_to_set,
  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_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. tc_interface_2_variant,
  70. tc_variant_2_interface,
  71. tc_array_2_dynarray
  72. );
  73. function compare_defs_ext(def_from,def_to : tdef;
  74. fromtreetype : tnodetype;
  75. var doconv : tconverttype;
  76. var operatorpd : tprocdef;
  77. cdoptions:tcompare_defs_options):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. {# true, if two parameter lists are equal
  87. if acp is cp_none, all have to match exactly
  88. if acp is cp_value_equal_const call by value
  89. and call by const parameter are assumed as
  90. equal
  91. allowdefaults indicates if default value parameters
  92. are allowed (in this case, the search order will first
  93. search for a routine with default parameters, before
  94. searching for the same definition with no parameters)
  95. }
  96. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  97. { True if a function can be assigned to a procvar }
  98. { changed first argument type to pabstractprocdef so that it can also be }
  99. { used to test compatibility between two pprocvardefs (JM) }
  100. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  101. { Parentdef is the definition of a method defined in a parent class or interface }
  102. { Childdef is the definition of a method defined in a child class, interface or }
  103. { a class implementing an interface with parentdef. }
  104. { Returns true if the resultdef of childdef can be used to implement/override }
  105. { parentdef's resultdef }
  106. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  107. implementation
  108. uses
  109. verbose,systems,constexp,
  110. symtable,symsym,
  111. defutil,symutil;
  112. function compare_defs_ext(def_from,def_to : tdef;
  113. fromtreetype : tnodetype;
  114. var doconv : tconverttype;
  115. var operatorpd : tprocdef;
  116. cdoptions:tcompare_defs_options):tequaltype;
  117. { tordtype:
  118. uvoid,
  119. u8bit,u16bit,u32bit,u64bit,
  120. s8bit,s16bit,s32bit,s64bit,
  121. bool8bit,bool16bit,bool32bit,bool64bit,
  122. uchar,uwidechar }
  123. type
  124. tbasedef=(bvoid,bchar,bint,bbool);
  125. const
  126. basedeftbl:array[tordtype] of tbasedef =
  127. (bvoid,
  128. bint,bint,bint,bint,
  129. bint,bint,bint,bint,
  130. bbool,bbool,bbool,bbool,
  131. bchar,bchar,bint);
  132. basedefconvertsimplicit : array[tbasedef,tbasedef] of tconverttype =
  133. { void, char, int, bool }
  134. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  135. (tc_not_possible,tc_char_2_char,tc_not_possible,tc_not_possible),
  136. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_not_possible),
  137. (tc_not_possible,tc_not_possible,tc_not_possible,tc_bool_2_bool));
  138. basedefconvertsexplicit : array[tbasedef,tbasedef] of tconverttype =
  139. { void, char, int, bool }
  140. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  141. (tc_not_possible,tc_char_2_char,tc_int_2_int,tc_int_2_bool),
  142. (tc_not_possible,tc_int_2_int,tc_int_2_int,tc_int_2_bool),
  143. (tc_not_possible,tc_bool_2_int,tc_bool_2_int,tc_bool_2_bool));
  144. var
  145. subeq,eq : tequaltype;
  146. hd1,hd2 : tdef;
  147. hct : tconverttype;
  148. hobjdef : tobjectdef;
  149. hpd : tprocdef;
  150. begin
  151. eq:=te_incompatible;
  152. doconv:=tc_not_possible;
  153. { safety check }
  154. if not(assigned(def_from) and assigned(def_to)) then
  155. begin
  156. compare_defs_ext:=te_incompatible;
  157. exit;
  158. end;
  159. { same def? then we've an exact match }
  160. if def_from=def_to then
  161. begin
  162. doconv:=tc_equal;
  163. compare_defs_ext:=te_exact;
  164. exit;
  165. end;
  166. { undefined def? then mark it as equal }
  167. if (def_from.typ=undefineddef) or
  168. (def_to.typ=undefineddef) then
  169. begin
  170. doconv:=tc_equal;
  171. compare_defs_ext:=te_equal;
  172. exit;
  173. end;
  174. { undefined def? then mark it as equal }
  175. if (def_from.typ=undefineddef) or
  176. (def_to.typ=undefineddef) then
  177. begin
  178. doconv:=tc_equal;
  179. compare_defs_ext:=te_equal;
  180. exit;
  181. end;
  182. { we walk the wanted (def_to) types and check then the def_from
  183. types if there is a conversion possible }
  184. case def_to.typ of
  185. orddef :
  186. begin
  187. case def_from.typ of
  188. orddef :
  189. begin
  190. if (torddef(def_from).ordtype=torddef(def_to).ordtype) then
  191. begin
  192. case torddef(def_from).ordtype of
  193. uchar,uwidechar,
  194. u8bit,u16bit,u32bit,u64bit,
  195. s8bit,s16bit,s32bit,s64bit:
  196. begin
  197. if (torddef(def_from).low>=torddef(def_to).low) and
  198. (torddef(def_from).high<=torddef(def_to).high) then
  199. eq:=te_equal
  200. else
  201. begin
  202. doconv:=tc_int_2_int;
  203. eq:=te_convert_l1;
  204. end;
  205. end;
  206. uvoid,
  207. bool8bit,bool16bit,bool32bit,bool64bit:
  208. eq:=te_equal;
  209. else
  210. internalerror(200210061);
  211. end;
  212. end
  213. else
  214. begin
  215. if cdo_explicit in cdoptions then
  216. doconv:=basedefconvertsexplicit[basedeftbl[torddef(def_from).ordtype],basedeftbl[torddef(def_to).ordtype]]
  217. else
  218. doconv:=basedefconvertsimplicit[basedeftbl[torddef(def_from).ordtype],basedeftbl[torddef(def_to).ordtype]];
  219. if (doconv=tc_not_possible) then
  220. eq:=te_incompatible
  221. else
  222. { "punish" bad type conversions :) (JM) }
  223. if (not is_in_limit(def_from,def_to)) and
  224. (def_from.size > def_to.size) then
  225. eq:=te_convert_l3
  226. else
  227. eq:=te_convert_l1;
  228. end;
  229. end;
  230. enumdef :
  231. begin
  232. { needed for char(enum) }
  233. if cdo_explicit in cdoptions then
  234. begin
  235. doconv:=tc_int_2_int;
  236. eq:=te_convert_l1;
  237. end;
  238. end;
  239. floatdef :
  240. begin
  241. if is_currency(def_to) then
  242. begin
  243. doconv:=tc_real_2_currency;
  244. eq:=te_convert_l2;
  245. end;
  246. end;
  247. objectdef:
  248. begin
  249. if is_class_or_interface_or_dispinterface(def_from) and (cdo_explicit in cdoptions) then
  250. begin
  251. eq:=te_convert_l1;
  252. if (fromtreetype=niln) then
  253. begin
  254. { will be handled by the constant folding }
  255. doconv:=tc_equal;
  256. end
  257. else
  258. doconv:=tc_int_2_int;
  259. end;
  260. end;
  261. classrefdef,
  262. procvardef,
  263. pointerdef :
  264. begin
  265. if cdo_explicit in cdoptions then
  266. begin
  267. eq:=te_convert_l1;
  268. if (fromtreetype=niln) then
  269. begin
  270. { will be handled by the constant folding }
  271. doconv:=tc_equal;
  272. end
  273. else
  274. doconv:=tc_int_2_int;
  275. end;
  276. end;
  277. arraydef :
  278. begin
  279. if (m_mac in current_settings.modeswitches) and
  280. (fromtreetype=stringconstn) then
  281. begin
  282. eq:=te_convert_l3;
  283. doconv:=tc_cstring_2_int;
  284. end;
  285. end;
  286. end;
  287. end;
  288. stringdef :
  289. begin
  290. case def_from.typ of
  291. stringdef :
  292. begin
  293. { Constant string }
  294. if (fromtreetype=stringconstn) then
  295. begin
  296. if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) then
  297. eq:=te_equal
  298. else
  299. begin
  300. doconv:=tc_string_2_string;
  301. { Don't prefer conversions from widestring to a
  302. normal string as we can loose information }
  303. if tstringdef(def_from).stringtype=st_widestring then
  304. eq:=te_convert_l3
  305. else if tstringdef(def_to).stringtype=st_widestring then
  306. eq:=te_convert_l2
  307. else
  308. eq:=te_equal;
  309. end;
  310. end
  311. else
  312. { Same string type, for shortstrings also the length must match }
  313. if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) and
  314. ((tstringdef(def_from).stringtype<>st_shortstring) or
  315. (tstringdef(def_from).len=tstringdef(def_to).len)) then
  316. eq:=te_equal
  317. else
  318. begin
  319. doconv:=tc_string_2_string;
  320. case tstringdef(def_from).stringtype of
  321. st_widestring :
  322. begin
  323. { Prefer conversions to ansistring }
  324. if tstringdef(def_to).stringtype=st_ansistring then
  325. eq:=te_convert_l2
  326. else
  327. eq:=te_convert_l3;
  328. end;
  329. st_shortstring :
  330. begin
  331. { Prefer shortstrings of different length or conversions
  332. from shortstring to ansistring }
  333. if (tstringdef(def_to).stringtype=st_shortstring) then
  334. eq:=te_convert_l1
  335. else if tstringdef(def_to).stringtype=st_ansistring then
  336. eq:=te_convert_l2
  337. else
  338. eq:=te_convert_l3;
  339. end;
  340. st_ansistring :
  341. begin
  342. { Prefer conversion to widestrings }
  343. if (tstringdef(def_to).stringtype=st_widestring) then
  344. eq:=te_convert_l2
  345. else
  346. eq:=te_convert_l3;
  347. end;
  348. end;
  349. end;
  350. end;
  351. orddef :
  352. begin
  353. { char to string}
  354. if is_char(def_from) or
  355. is_widechar(def_from) then
  356. begin
  357. doconv:=tc_char_2_string;
  358. eq:=te_convert_l1;
  359. end;
  360. end;
  361. arraydef :
  362. begin
  363. { array of char to string, the length check is done by the firstpass of this node }
  364. if is_chararray(def_from) or is_open_chararray(def_from) then
  365. begin
  366. { "Untyped" stringconstn is an array of char }
  367. if fromtreetype=stringconstn then
  368. begin
  369. doconv:=tc_string_2_string;
  370. { prefered string type depends on the $H switch }
  371. if not(cs_ansistrings in current_settings.localswitches) and
  372. (tstringdef(def_to).stringtype=st_shortstring) then
  373. eq:=te_equal
  374. else if (cs_ansistrings in current_settings.localswitches) and
  375. (tstringdef(def_to).stringtype=st_ansistring) then
  376. eq:=te_equal
  377. else if tstringdef(def_to).stringtype=st_widestring then
  378. eq:=te_convert_l3
  379. else
  380. eq:=te_convert_l1;
  381. end
  382. else
  383. begin
  384. doconv:=tc_chararray_2_string;
  385. if is_open_array(def_from) then
  386. begin
  387. if is_ansistring(def_to) then
  388. eq:=te_convert_l1
  389. else if is_widestring(def_to) then
  390. eq:=te_convert_l3
  391. else
  392. eq:=te_convert_l2;
  393. end
  394. else
  395. begin
  396. if is_shortstring(def_to) then
  397. begin
  398. { Only compatible with arrays that fit
  399. smaller than 255 chars }
  400. if (def_from.size <= 255) then
  401. eq:=te_convert_l1;
  402. end
  403. else if is_ansistring(def_to) then
  404. begin
  405. if (def_from.size > 255) then
  406. eq:=te_convert_l1
  407. else
  408. eq:=te_convert_l2;
  409. end
  410. else if is_widestring(def_to) then
  411. eq:=te_convert_l3
  412. else
  413. eq:=te_convert_l2;
  414. end;
  415. end;
  416. end
  417. else
  418. { array of widechar to string, the length check is done by the firstpass of this node }
  419. if is_widechararray(def_from) or is_open_widechararray(def_from) then
  420. begin
  421. doconv:=tc_chararray_2_string;
  422. if is_widestring(def_to) then
  423. eq:=te_convert_l1
  424. else
  425. { size of widechar array is double due the sizeof a widechar }
  426. if not(is_shortstring(def_to) and (def_from.size>255*sizeof(widechar))) then
  427. eq:=te_convert_l3
  428. else
  429. eq:=te_convert_l2;
  430. end;
  431. end;
  432. pointerdef :
  433. begin
  434. { pchar can be assigned to short/ansistrings,
  435. but not in tp7 compatible mode }
  436. if not(m_tp7 in current_settings.modeswitches) then
  437. begin
  438. if is_pchar(def_from) then
  439. begin
  440. doconv:=tc_pchar_2_string;
  441. { prefer ansistrings because pchars can overflow shortstrings, }
  442. { but only if ansistrings are the default (JM) }
  443. if (is_shortstring(def_to) and
  444. not(cs_ansistrings in current_settings.localswitches)) or
  445. (is_ansistring(def_to) and
  446. (cs_ansistrings in current_settings.localswitches)) then
  447. eq:=te_convert_l1
  448. else
  449. eq:=te_convert_l2;
  450. end
  451. else if is_pwidechar(def_from) then
  452. begin
  453. doconv:=tc_pwchar_2_string;
  454. if is_widestring(def_to) then
  455. eq:=te_convert_l1
  456. else
  457. eq:=te_convert_l3;
  458. end;
  459. end;
  460. end;
  461. end;
  462. end;
  463. floatdef :
  464. begin
  465. case def_from.typ of
  466. orddef :
  467. begin { ordinal to real }
  468. { only for implicit and internal typecasts in tp/delphi }
  469. if (([cdo_explicit,cdo_internal] * cdoptions <> [cdo_explicit]) or
  470. ([m_tp7,m_delphi] * current_settings.modeswitches = [])) and
  471. (is_integer(def_from) or
  472. (is_currency(def_from) and
  473. (s64currencytype.typ = floatdef))) then
  474. begin
  475. doconv:=tc_int_2_real;
  476. eq:=te_convert_l1;
  477. end
  478. else if is_currency(def_from)
  479. { and (s64currencytype.typ = orddef)) } then
  480. begin
  481. { prefer conversion to orddef in this case, unless }
  482. { the orddef < currency (then it will get convert l3, }
  483. { and conversion to float is favoured) }
  484. doconv:=tc_int_2_real;
  485. eq:=te_convert_l2;
  486. end;
  487. end;
  488. floatdef :
  489. begin
  490. if tfloatdef(def_from).floattype=tfloatdef(def_to).floattype then
  491. eq:=te_equal
  492. else
  493. begin
  494. if (fromtreetype=realconstn) or
  495. not((cdo_explicit in cdoptions) and
  496. (m_delphi in current_settings.modeswitches)) then
  497. begin
  498. doconv:=tc_real_2_real;
  499. { do we loose precision? }
  500. if def_to.size<def_from.size then
  501. eq:=te_convert_l2
  502. else
  503. eq:=te_convert_l1;
  504. end;
  505. end;
  506. end;
  507. end;
  508. end;
  509. enumdef :
  510. begin
  511. case def_from.typ of
  512. enumdef :
  513. begin
  514. if cdo_explicit in cdoptions then
  515. begin
  516. eq:=te_convert_l1;
  517. doconv:=tc_int_2_int;
  518. end
  519. else
  520. begin
  521. hd1:=def_from;
  522. while assigned(tenumdef(hd1).basedef) do
  523. hd1:=tenumdef(hd1).basedef;
  524. hd2:=def_to;
  525. while assigned(tenumdef(hd2).basedef) do
  526. hd2:=tenumdef(hd2).basedef;
  527. if (hd1=hd2) then
  528. begin
  529. eq:=te_convert_l1;
  530. { because of packenum they can have different sizes! (JM) }
  531. doconv:=tc_int_2_int;
  532. end
  533. else
  534. begin
  535. { assignment of an enum symbol to an unique type? }
  536. if (fromtreetype=ordconstn) and
  537. (tenumsym(tenumdef(hd1).firstenum)=tenumsym(tenumdef(hd2).firstenum)) then
  538. begin
  539. { because of packenum they can have different sizes! (JM) }
  540. eq:=te_convert_l1;
  541. doconv:=tc_int_2_int;
  542. end;
  543. end;
  544. end;
  545. end;
  546. orddef :
  547. begin
  548. if cdo_explicit in cdoptions then
  549. begin
  550. eq:=te_convert_l1;
  551. doconv:=tc_int_2_int;
  552. end;
  553. end;
  554. variantdef :
  555. begin
  556. eq:=te_convert_l1;
  557. doconv:=tc_variant_2_enum;
  558. end;
  559. pointerdef :
  560. begin
  561. { ugly, but delphi allows it }
  562. if (cdo_explicit in cdoptions) and
  563. (m_delphi in current_settings.modeswitches) and
  564. (eq=te_incompatible) then
  565. begin
  566. doconv:=tc_int_2_int;
  567. eq:=te_convert_l1;
  568. end;
  569. end;
  570. end;
  571. end;
  572. arraydef :
  573. begin
  574. { open array is also compatible with a single element of its base type.
  575. the extra check for deftyp is needed because equal defs can also return
  576. true if the def types are not the same, for example with dynarray to pointer. }
  577. if is_open_array(def_to) and
  578. (def_from.typ=tarraydef(def_to).elementdef.typ) and
  579. equal_defs(def_from,tarraydef(def_to).elementdef) then
  580. begin
  581. doconv:=tc_equal;
  582. eq:=te_convert_l1;
  583. end
  584. else
  585. begin
  586. case def_from.typ of
  587. arraydef :
  588. begin
  589. { from/to packed array -- packed chararrays are }
  590. { strings in ISO Pascal (at least if the lower bound }
  591. { is 1, but GPC makes all equal-length chararrays }
  592. { compatible), so treat those the same as regular }
  593. { char arrays }
  594. if (is_packed_array(def_from) and
  595. not is_chararray(def_from) and
  596. not is_widechararray(def_from)) xor
  597. (is_packed_array(def_to) and
  598. not is_chararray(def_to) and
  599. not is_widechararray(def_to)) then
  600. { both must be packed }
  601. begin
  602. compare_defs_ext:=te_incompatible;
  603. exit;
  604. end
  605. { to dynamic array }
  606. else if is_dynamic_array(def_to) then
  607. begin
  608. if equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  609. begin
  610. { dynamic array -> dynamic array }
  611. if is_dynamic_array(def_from) then
  612. eq:=te_equal
  613. { fpc modes only: array -> dyn. array }
  614. else if (current_settings.modeswitches*[m_objfpc,m_fpc]<>[]) and
  615. not(is_special_array(def_from)) and
  616. is_zero_based_array(def_from) then
  617. begin
  618. eq:=te_convert_l2;
  619. doconv:=tc_array_2_dynarray;
  620. end;
  621. end
  622. end
  623. else
  624. { to open array }
  625. if is_open_array(def_to) then
  626. begin
  627. { array constructor -> open array }
  628. if is_array_constructor(def_from) then
  629. begin
  630. if is_void(tarraydef(def_from).elementdef) then
  631. begin
  632. doconv:=tc_equal;
  633. eq:=te_convert_l1;
  634. end
  635. else
  636. begin
  637. subeq:=compare_defs_ext(tarraydef(def_from).elementdef,
  638. tarraydef(def_to).elementdef,
  639. { reason for cdo_allow_variant: see webtbs/tw7070a and webtbs/tw7070b }
  640. arrayconstructorn,hct,hpd,[cdo_check_operator,cdo_allow_variant]);
  641. if (subeq>=te_equal) then
  642. begin
  643. doconv:=tc_equal;
  644. eq:=te_convert_l1;
  645. end
  646. else
  647. if (subeq>te_incompatible) then
  648. begin
  649. doconv:=hct;
  650. eq:=te_convert_l2;
  651. end;
  652. end;
  653. end
  654. else
  655. { dynamic array -> open array }
  656. if is_dynamic_array(def_from) and
  657. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  658. begin
  659. doconv:=tc_dynarray_2_openarray;
  660. eq:=te_convert_l2;
  661. end
  662. else
  663. { open array -> open array }
  664. if is_open_array(def_from) and
  665. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  666. eq:=te_equal
  667. else
  668. { array -> open array }
  669. if not(cdo_parameter in cdoptions) and
  670. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  671. eq:=te_equal;
  672. end
  673. else
  674. { to array of const }
  675. if is_array_of_const(def_to) then
  676. begin
  677. if is_array_of_const(def_from) or
  678. is_array_constructor(def_from) then
  679. begin
  680. eq:=te_equal;
  681. end
  682. else
  683. { array of tvarrec -> array of const }
  684. if equal_defs(tarraydef(def_to).elementdef,tarraydef(def_from).elementdef) then
  685. begin
  686. doconv:=tc_equal;
  687. eq:=te_convert_l1;
  688. end;
  689. end
  690. else
  691. { to array of char, from "Untyped" stringconstn (array of char) }
  692. if (fromtreetype=stringconstn) and
  693. (is_chararray(def_to) or
  694. is_widechararray(def_to)) then
  695. begin
  696. eq:=te_convert_l1;
  697. doconv:=tc_string_2_chararray;
  698. end
  699. else
  700. { other arrays }
  701. begin
  702. { open array -> array }
  703. if not(cdo_parameter in cdoptions) and
  704. is_open_array(def_from) and
  705. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  706. begin
  707. eq:=te_equal
  708. end
  709. else
  710. { array -> array }
  711. if not(m_tp7 in current_settings.modeswitches) and
  712. not(m_delphi in current_settings.modeswitches) and
  713. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  714. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  715. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) and
  716. equal_defs(tarraydef(def_from).rangedef,tarraydef(def_to).rangedef) then
  717. begin
  718. eq:=te_equal
  719. end;
  720. end;
  721. end;
  722. pointerdef :
  723. begin
  724. { nil and voidpointers are compatible with dyn. arrays }
  725. if is_dynamic_array(def_to) and
  726. ((fromtreetype=niln) or
  727. is_voidpointer(def_from)) then
  728. begin
  729. doconv:=tc_equal;
  730. eq:=te_convert_l1;
  731. end
  732. else
  733. if is_zero_based_array(def_to) and
  734. equal_defs(tpointerdef(def_from).pointeddef,tarraydef(def_to).elementdef) then
  735. begin
  736. doconv:=tc_pointer_2_array;
  737. eq:=te_convert_l1;
  738. end;
  739. end;
  740. stringdef :
  741. begin
  742. { string to char array }
  743. if (not is_special_array(def_to)) and
  744. (is_char(tarraydef(def_to).elementdef)or
  745. is_widechar(tarraydef(def_to).elementdef)) then
  746. begin
  747. doconv:=tc_string_2_chararray;
  748. eq:=te_convert_l1;
  749. end;
  750. end;
  751. orddef:
  752. begin
  753. if is_chararray(def_to) and
  754. is_char(def_from) then
  755. begin
  756. doconv:=tc_char_2_chararray;
  757. eq:=te_convert_l2;
  758. end;
  759. end;
  760. recorddef :
  761. begin
  762. { tvarrec -> array of const }
  763. if is_array_of_const(def_to) and
  764. equal_defs(def_from,tarraydef(def_to).elementdef) then
  765. begin
  766. doconv:=tc_equal;
  767. eq:=te_convert_l1;
  768. end;
  769. end;
  770. variantdef :
  771. begin
  772. if is_dynamic_array(def_to) then
  773. begin
  774. doconv:=tc_variant_2_dynarray;
  775. eq:=te_convert_l1;
  776. end;
  777. end;
  778. end;
  779. end;
  780. end;
  781. variantdef :
  782. begin
  783. if (cdo_allow_variant in cdoptions) then
  784. begin
  785. case def_from.typ of
  786. enumdef :
  787. begin
  788. doconv:=tc_enum_2_variant;
  789. eq:=te_convert_l1;
  790. end;
  791. arraydef :
  792. begin
  793. if is_dynamic_array(def_from) then
  794. begin
  795. doconv:=tc_dynarray_2_variant;
  796. eq:=te_convert_l1;
  797. end;
  798. end;
  799. objectdef :
  800. begin
  801. if is_interface(def_from) then
  802. begin
  803. doconv:=tc_interface_2_variant;
  804. eq:=te_convert_l1;
  805. end;
  806. end;
  807. variantdef :
  808. begin
  809. { doing this in the compiler avoids a lot of unncessary
  810. copying }
  811. if (tvariantdef(def_from).varianttype=vt_olevariant) and
  812. (tvariantdef(def_to).varianttype=vt_normalvariant) then
  813. begin
  814. doconv:=tc_equal;
  815. eq:=te_convert_l1;
  816. end;
  817. end;
  818. end;
  819. end;
  820. end;
  821. pointerdef :
  822. begin
  823. case def_from.typ of
  824. stringdef :
  825. begin
  826. { string constant (which can be part of array constructor)
  827. to zero terminated string constant }
  828. if (((fromtreetype = arrayconstructorn) and
  829. { can't use is_chararray, because returns false for }
  830. { array constructors }
  831. is_char(tarraydef(def_from).elementdef)) or
  832. (fromtreetype = stringconstn)) and
  833. (is_pchar(def_to) or is_pwidechar(def_to)) then
  834. begin
  835. doconv:=tc_cstring_2_pchar;
  836. eq:=te_convert_l2;
  837. end
  838. else
  839. if cdo_explicit in cdoptions then
  840. begin
  841. { pchar(ansistring) }
  842. if is_pchar(def_to) and
  843. is_ansistring(def_from) then
  844. begin
  845. doconv:=tc_ansistring_2_pchar;
  846. eq:=te_convert_l1;
  847. end
  848. else
  849. { pwidechar(widestring) }
  850. if is_pwidechar(def_to) and
  851. is_widestring(def_from) then
  852. begin
  853. doconv:=tc_ansistring_2_pchar;
  854. eq:=te_convert_l1;
  855. end;
  856. end;
  857. end;
  858. orddef :
  859. begin
  860. { char constant to zero terminated string constant }
  861. if (fromtreetype in [ordconstn,arrayconstructorn]) then
  862. begin
  863. if (is_char(def_from) or is_widechar(def_from)) and
  864. (is_pchar(def_to) or is_pwidechar(def_to)) then
  865. begin
  866. doconv:=tc_cchar_2_pchar;
  867. eq:=te_convert_l1;
  868. end
  869. else
  870. if (m_delphi in current_settings.modeswitches) and is_integer(def_from) then
  871. begin
  872. doconv:=tc_cord_2_pointer;
  873. eq:=te_convert_l2;
  874. end;
  875. end;
  876. { allow explicit typecasts from ordinals to pointer.
  877. Support for delphi compatibility
  878. Support constructs like pointer(cardinal-cardinal) or pointer(longint+cardinal) where
  879. the result of the ordinal operation is int64 also on 32 bit platforms.
  880. It is also used by the compiler internally for inc(pointer,ordinal) }
  881. if (eq=te_incompatible) and
  882. not is_void(def_from) and
  883. (
  884. (
  885. (cdo_explicit in cdoptions) and
  886. (
  887. (m_delphi in current_settings.modeswitches) or
  888. { Don't allow pchar(char) in fpc modes }
  889. is_integer(def_from)
  890. )
  891. ) or
  892. (cdo_internal in cdoptions)
  893. ) then
  894. begin
  895. doconv:=tc_int_2_int;
  896. eq:=te_convert_l1;
  897. end;
  898. end;
  899. enumdef :
  900. begin
  901. { allow explicit typecasts from enums to pointer.
  902. Support for delphi compatibility
  903. }
  904. if (eq=te_incompatible) and
  905. (((cdo_explicit in cdoptions) and
  906. (m_delphi in current_settings.modeswitches)
  907. ) or
  908. (cdo_internal in cdoptions)
  909. ) then
  910. begin
  911. doconv:=tc_int_2_int;
  912. eq:=te_convert_l1;
  913. end;
  914. end;
  915. arraydef :
  916. begin
  917. { string constant (which can be part of array constructor)
  918. to zero terminated string constant }
  919. if (((fromtreetype = arrayconstructorn) and
  920. { can't use is_chararray, because returns false for }
  921. { array constructors }
  922. is_char(tarraydef(def_from).elementdef)) or
  923. (fromtreetype = stringconstn)) and
  924. (is_pchar(def_to) or is_pwidechar(def_to)) then
  925. begin
  926. doconv:=tc_cstring_2_pchar;
  927. eq:=te_convert_l2;
  928. end
  929. else
  930. { chararray to pointer }
  931. if (is_zero_based_array(def_from) or
  932. is_open_array(def_from)) and
  933. equal_defs(tarraydef(def_from).elementdef,tpointerdef(def_to).pointeddef) then
  934. begin
  935. doconv:=tc_array_2_pointer;
  936. { don't prefer the pchar overload when a constant
  937. string was passed }
  938. if fromtreetype=stringconstn then
  939. eq:=te_convert_l2
  940. else
  941. eq:=te_convert_l1;
  942. end
  943. else
  944. { dynamic array to pointer, delphi only }
  945. if (m_delphi in current_settings.modeswitches) and
  946. is_dynamic_array(def_from) then
  947. begin
  948. eq:=te_equal;
  949. end;
  950. end;
  951. pointerdef :
  952. begin
  953. { check for far pointers }
  954. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  955. begin
  956. eq:=te_incompatible;
  957. end
  958. else
  959. { the types can be forward type, handle before normal type check !! }
  960. if assigned(def_to.typesym) and
  961. (tpointerdef(def_to).pointeddef.typ=forwarddef) then
  962. begin
  963. if (def_from.typesym=def_to.typesym) then
  964. eq:=te_equal
  965. end
  966. else
  967. { same types }
  968. if equal_defs(tpointerdef(def_from).pointeddef,tpointerdef(def_to).pointeddef) then
  969. begin
  970. eq:=te_equal
  971. end
  972. else
  973. { child class pointer can be assigned to anchestor pointers }
  974. if (
  975. (tpointerdef(def_from).pointeddef.typ=objectdef) and
  976. (tpointerdef(def_to).pointeddef.typ=objectdef) and
  977. tobjectdef(tpointerdef(def_from).pointeddef).is_related(
  978. tobjectdef(tpointerdef(def_to).pointeddef))
  979. ) then
  980. begin
  981. doconv:=tc_equal;
  982. eq:=te_convert_l1;
  983. end
  984. else
  985. { all pointers can be assigned to void-pointer }
  986. if is_void(tpointerdef(def_to).pointeddef) then
  987. begin
  988. doconv:=tc_equal;
  989. { give pwidechar,pchar a penalty so it prefers
  990. conversion to ansistring }
  991. if is_pchar(def_from) or
  992. is_pwidechar(def_from) then
  993. eq:=te_convert_l2
  994. else
  995. eq:=te_convert_l1;
  996. end
  997. else
  998. { all pointers can be assigned from void-pointer }
  999. if is_void(tpointerdef(def_from).pointeddef) or
  1000. { all pointers can be assigned from void-pointer or formaldef pointer, check
  1001. tw3777.pp if you change this }
  1002. (tpointerdef(def_from).pointeddef.typ=formaldef) then
  1003. begin
  1004. doconv:=tc_equal;
  1005. { give pwidechar a penalty so it prefers
  1006. conversion to pchar }
  1007. if is_pwidechar(def_to) then
  1008. eq:=te_convert_l2
  1009. else
  1010. eq:=te_convert_l1;
  1011. end;
  1012. end;
  1013. procvardef :
  1014. begin
  1015. { procedure variable can be assigned to an void pointer,
  1016. this not allowed for methodpointers }
  1017. if (is_void(tpointerdef(def_to).pointeddef) or
  1018. (m_mac_procvar in current_settings.modeswitches)) and
  1019. tprocvardef(def_from).is_addressonly then
  1020. begin
  1021. doconv:=tc_equal;
  1022. eq:=te_convert_l1;
  1023. end;
  1024. end;
  1025. procdef :
  1026. begin
  1027. { procedure variable can be assigned to an void pointer,
  1028. this not allowed for methodpointers }
  1029. if (m_mac_procvar in current_settings.modeswitches) and
  1030. tprocdef(def_from).is_addressonly then
  1031. begin
  1032. doconv:=tc_proc_2_procvar;
  1033. eq:=te_convert_l2;
  1034. end;
  1035. end;
  1036. classrefdef,
  1037. objectdef :
  1038. begin
  1039. { class types and class reference type
  1040. can be assigned to void pointers, but it is less
  1041. preferred than assigning to a related objectdef }
  1042. if (
  1043. is_class_or_interface_or_dispinterface(def_from) or
  1044. (def_from.typ=classrefdef)
  1045. ) and
  1046. (tpointerdef(def_to).pointeddef.typ=orddef) and
  1047. (torddef(tpointerdef(def_to).pointeddef).ordtype=uvoid) then
  1048. begin
  1049. doconv:=tc_equal;
  1050. eq:=te_convert_l2;
  1051. end;
  1052. end;
  1053. end;
  1054. end;
  1055. setdef :
  1056. begin
  1057. case def_from.typ of
  1058. setdef :
  1059. begin
  1060. if assigned(tsetdef(def_from).elementdef) and
  1061. assigned(tsetdef(def_to).elementdef) then
  1062. begin
  1063. { sets with the same element base type and the same range are equal }
  1064. if equal_defs(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) and
  1065. (tsetdef(def_from).setbase=tsetdef(def_to).setbase) and
  1066. (tsetdef(def_from).setmax=tsetdef(def_to).setmax) then
  1067. eq:=te_equal
  1068. else if is_subequal(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) then
  1069. begin
  1070. eq:=te_convert_l1;
  1071. doconv:=tc_set_to_set;
  1072. end;
  1073. end
  1074. else
  1075. begin
  1076. { empty set is compatible with everything }
  1077. eq:=te_convert_l1;
  1078. doconv:=tc_set_to_set;
  1079. end;
  1080. end;
  1081. arraydef :
  1082. begin
  1083. { automatic arrayconstructor -> set conversion }
  1084. if is_array_constructor(def_from) then
  1085. begin
  1086. doconv:=tc_arrayconstructor_2_set;
  1087. eq:=te_convert_l1;
  1088. end;
  1089. end;
  1090. end;
  1091. end;
  1092. procvardef :
  1093. begin
  1094. case def_from.typ of
  1095. procdef :
  1096. begin
  1097. { proc -> procvar }
  1098. if (m_tp_procvar in current_settings.modeswitches) or
  1099. (m_mac_procvar in current_settings.modeswitches) then
  1100. begin
  1101. subeq:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to));
  1102. if subeq>te_incompatible then
  1103. begin
  1104. doconv:=tc_proc_2_procvar;
  1105. eq:=te_convert_l1;
  1106. end;
  1107. end;
  1108. end;
  1109. procvardef :
  1110. begin
  1111. { procvar -> procvar }
  1112. eq:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to));
  1113. end;
  1114. pointerdef :
  1115. begin
  1116. { nil is compatible with procvars }
  1117. if (fromtreetype=niln) then
  1118. begin
  1119. if not Tprocvardef(def_to).is_addressonly then
  1120. {Nil to method pointers requires to convert a single
  1121. pointer nil value to a two pointer procvardef.}
  1122. doconv:=tc_nil_2_methodprocvar
  1123. else
  1124. doconv:=tc_equal;
  1125. eq:=te_convert_l1;
  1126. end
  1127. else
  1128. { for example delphi allows the assignement from pointers }
  1129. { to procedure variables }
  1130. if (m_pointer_2_procedure in current_settings.modeswitches) and
  1131. is_void(tpointerdef(def_from).pointeddef) and
  1132. tprocvardef(def_to).is_addressonly then
  1133. begin
  1134. doconv:=tc_equal;
  1135. eq:=te_convert_l1;
  1136. end;
  1137. end;
  1138. end;
  1139. end;
  1140. objectdef :
  1141. begin
  1142. { object pascal objects }
  1143. if (def_from.typ=objectdef) and
  1144. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  1145. begin
  1146. doconv:=tc_equal;
  1147. eq:=te_convert_l1;
  1148. end
  1149. else
  1150. { Class/interface specific }
  1151. if is_class_or_interface_or_dispinterface(def_to) then
  1152. begin
  1153. { void pointer also for delphi mode }
  1154. if (m_delphi in current_settings.modeswitches) and
  1155. is_voidpointer(def_from) then
  1156. begin
  1157. doconv:=tc_equal;
  1158. { prefer pointer-pointer assignments }
  1159. eq:=te_convert_l2;
  1160. end
  1161. else
  1162. { nil is compatible with class instances and interfaces }
  1163. if (fromtreetype=niln) then
  1164. begin
  1165. doconv:=tc_equal;
  1166. eq:=te_convert_l1;
  1167. end
  1168. { classes can be assigned to interfaces }
  1169. else if is_interface(def_to) and
  1170. is_class(def_from) and
  1171. assigned(tobjectdef(def_from).ImplementedInterfaces) then
  1172. begin
  1173. { we've to search in parent classes as well }
  1174. hobjdef:=tobjectdef(def_from);
  1175. while assigned(hobjdef) do
  1176. begin
  1177. if hobjdef.find_implemented_interface(tobjectdef(def_to))<>nil then
  1178. begin
  1179. doconv:=tc_class_2_intf;
  1180. { don't prefer this over objectdef->objectdef }
  1181. eq:=te_convert_l2;
  1182. break;
  1183. end;
  1184. hobjdef:=hobjdef.childof;
  1185. end;
  1186. end
  1187. { Interface 2 GUID handling }
  1188. else if (def_to=tdef(rec_tguid)) and
  1189. (fromtreetype=typen) and
  1190. is_interface(def_from) and
  1191. assigned(tobjectdef(def_from).iidguid) then
  1192. begin
  1193. eq:=te_convert_l1;
  1194. doconv:=tc_equal;
  1195. end
  1196. else if (def_from.typ=variantdef) and is_interface(def_to) then
  1197. begin
  1198. doconv:=tc_variant_2_interface;
  1199. eq:=te_convert_l2;
  1200. end
  1201. { ugly, but delphi allows it }
  1202. else if (eq=te_incompatible) and
  1203. (def_from.typ=orddef) and
  1204. (m_delphi in current_settings.modeswitches) and
  1205. (cdo_explicit in cdoptions) then
  1206. begin
  1207. doconv:=tc_int_2_int;
  1208. eq:=te_convert_l1;
  1209. end;
  1210. end;
  1211. end;
  1212. classrefdef :
  1213. begin
  1214. { similar to pointerdef wrt forwards }
  1215. if assigned(def_to.typesym) and
  1216. (tclassrefdef(def_to).pointeddef.typ=forwarddef) then
  1217. begin
  1218. if (def_from.typesym=def_to.typesym) then
  1219. eq:=te_equal;
  1220. end
  1221. else
  1222. { class reference types }
  1223. if (def_from.typ=classrefdef) then
  1224. begin
  1225. if equal_defs(tclassrefdef(def_from).pointeddef,tclassrefdef(def_to).pointeddef) then
  1226. begin
  1227. eq:=te_equal;
  1228. end
  1229. else
  1230. begin
  1231. doconv:=tc_equal;
  1232. if (cdo_explicit in cdoptions) or
  1233. tobjectdef(tclassrefdef(def_from).pointeddef).is_related(
  1234. tobjectdef(tclassrefdef(def_to).pointeddef)) then
  1235. eq:=te_convert_l1;
  1236. end;
  1237. end
  1238. else
  1239. if (m_delphi in current_settings.modeswitches) and
  1240. is_voidpointer(def_from) then
  1241. begin
  1242. doconv:=tc_equal;
  1243. { prefer pointer-pointer assignments }
  1244. eq:=te_convert_l2;
  1245. end
  1246. else
  1247. { nil is compatible with class references }
  1248. if (fromtreetype=niln) then
  1249. begin
  1250. doconv:=tc_equal;
  1251. eq:=te_convert_l1;
  1252. end;
  1253. end;
  1254. filedef :
  1255. begin
  1256. { typed files are all equal to the abstract file type
  1257. name TYPEDFILE in system.pp in is_equal in types.pas
  1258. the problem is that it sholud be also compatible to FILE
  1259. but this would leed to a problem for ASSIGN RESET and REWRITE
  1260. when trying to find the good overloaded function !!
  1261. so all file function are doubled in system.pp
  1262. this is not very beautiful !!}
  1263. if (def_from.typ=filedef) then
  1264. begin
  1265. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  1266. begin
  1267. if
  1268. (
  1269. (tfiledef(def_from).typedfiledef=nil) and
  1270. (tfiledef(def_to).typedfiledef=nil)
  1271. ) or
  1272. (
  1273. (tfiledef(def_from).typedfiledef<>nil) and
  1274. (tfiledef(def_to).typedfiledef<>nil) and
  1275. equal_defs(tfiledef(def_from).typedfiledef,tfiledef(def_to).typedfiledef)
  1276. ) or
  1277. (
  1278. (tfiledef(def_from).filetyp = ft_typed) and
  1279. (tfiledef(def_to).filetyp = ft_typed) and
  1280. (
  1281. (tfiledef(def_from).typedfiledef = tdef(voidtype)) or
  1282. (tfiledef(def_to).typedfiledef = tdef(voidtype))
  1283. )
  1284. ) then
  1285. begin
  1286. eq:=te_equal;
  1287. end;
  1288. end
  1289. else
  1290. if ((tfiledef(def_from).filetyp = ft_untyped) and
  1291. (tfiledef(def_to).filetyp = ft_typed)) or
  1292. ((tfiledef(def_from).filetyp = ft_typed) and
  1293. (tfiledef(def_to).filetyp = ft_untyped)) then
  1294. begin
  1295. doconv:=tc_equal;
  1296. eq:=te_convert_l1;
  1297. end;
  1298. end;
  1299. end;
  1300. recorddef :
  1301. begin
  1302. { interface -> guid }
  1303. if is_interface(def_from) and
  1304. (def_to=rec_tguid) then
  1305. begin
  1306. doconv:=tc_intf_2_guid;
  1307. eq:=te_convert_l1;
  1308. end;
  1309. end;
  1310. formaldef :
  1311. begin
  1312. doconv:=tc_equal;
  1313. if (def_from.typ=formaldef) then
  1314. eq:=te_equal
  1315. else
  1316. { Just about everything can be converted to a formaldef...}
  1317. if not (def_from.typ in [abstractdef,errordef]) then
  1318. eq:=te_convert_l2;
  1319. end;
  1320. end;
  1321. { if we didn't find an appropriate type conversion yet
  1322. then we search also the := operator }
  1323. if (eq=te_incompatible) and
  1324. { make sure there is not a single variant if variants }
  1325. { are not allowed (otherwise if only cdo_check_operator }
  1326. { and e.g. fromdef=stringdef and todef=variantdef, then }
  1327. { the test will still succeed }
  1328. ((cdo_allow_variant in cdoptions) or
  1329. ((def_from.typ<>variantdef) and (def_to.typ<>variantdef))
  1330. ) and
  1331. (
  1332. { Check for variants? }
  1333. (
  1334. (cdo_allow_variant in cdoptions) and
  1335. ((def_from.typ=variantdef) or (def_to.typ=variantdef))
  1336. ) or
  1337. { Check for operators? }
  1338. (
  1339. (cdo_check_operator in cdoptions) and
  1340. ((def_from.typ in [objectdef,recorddef,arraydef,stringdef]) or
  1341. (def_to.typ in [objectdef,recorddef,arraydef,stringdef]))
  1342. )
  1343. ) then
  1344. begin
  1345. operatorpd:=search_assignment_operator(def_from,def_to);
  1346. if assigned(operatorpd) then
  1347. eq:=te_convert_operator;
  1348. end;
  1349. { update convtype for te_equal when it is not yet set }
  1350. if (eq=te_equal) and
  1351. (doconv=tc_not_possible) then
  1352. doconv:=tc_equal;
  1353. compare_defs_ext:=eq;
  1354. end;
  1355. function equal_defs(def_from,def_to:tdef):boolean;
  1356. var
  1357. convtyp : tconverttype;
  1358. pd : tprocdef;
  1359. begin
  1360. { Compare defs with nothingn and no explicit typecasts and
  1361. searching for overloaded operators is not needed }
  1362. equal_defs:=(compare_defs_ext(def_from,def_to,nothingn,convtyp,pd,[])>=te_equal);
  1363. end;
  1364. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  1365. var
  1366. doconv : tconverttype;
  1367. pd : tprocdef;
  1368. begin
  1369. compare_defs:=compare_defs_ext(def_from,def_to,fromtreetype,doconv,pd,[cdo_check_operator,cdo_allow_variant]);
  1370. end;
  1371. function is_subequal(def1, def2: tdef): boolean;
  1372. var
  1373. basedef1,basedef2 : tenumdef;
  1374. Begin
  1375. is_subequal := false;
  1376. if assigned(def1) and assigned(def2) then
  1377. Begin
  1378. if (def1.typ = orddef) and (def2.typ = orddef) then
  1379. Begin
  1380. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  1381. { range checking for case statements is done with testrange }
  1382. case torddef(def1).ordtype of
  1383. u8bit,u16bit,u32bit,u64bit,
  1384. s8bit,s16bit,s32bit,s64bit :
  1385. is_subequal:=(torddef(def2).ordtype in [s64bit,u64bit,s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  1386. bool8bit,bool16bit,bool32bit,bool64bit :
  1387. is_subequal:=(torddef(def2).ordtype in [bool8bit,bool16bit,bool32bit,bool64bit]);
  1388. uchar :
  1389. is_subequal:=(torddef(def2).ordtype=uchar);
  1390. uwidechar :
  1391. is_subequal:=(torddef(def2).ordtype=uwidechar);
  1392. end;
  1393. end
  1394. else
  1395. Begin
  1396. { Check if both basedefs are equal }
  1397. if (def1.typ=enumdef) and (def2.typ=enumdef) then
  1398. Begin
  1399. { get both basedefs }
  1400. basedef1:=tenumdef(def1);
  1401. while assigned(basedef1.basedef) do
  1402. basedef1:=basedef1.basedef;
  1403. basedef2:=tenumdef(def2);
  1404. while assigned(basedef2.basedef) do
  1405. basedef2:=basedef2.basedef;
  1406. is_subequal:=(basedef1=basedef2);
  1407. end;
  1408. end;
  1409. end;
  1410. end;
  1411. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  1412. var
  1413. currpara1,
  1414. currpara2 : tparavarsym;
  1415. eq,lowesteq : tequaltype;
  1416. hpd : tprocdef;
  1417. convtype : tconverttype;
  1418. cdoptions : tcompare_defs_options;
  1419. i1,i2 : byte;
  1420. begin
  1421. compare_paras:=te_incompatible;
  1422. cdoptions:=[cdo_parameter,cdo_check_operator,cdo_allow_variant];
  1423. { we need to parse the list from left-right so the
  1424. not-default parameters are checked first }
  1425. lowesteq:=high(tequaltype);
  1426. i1:=0;
  1427. i2:=0;
  1428. if cpo_ignorehidden in cpoptions then
  1429. begin
  1430. while (i1<para1.count) and
  1431. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1432. inc(i1);
  1433. while (i2<para2.count) and
  1434. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1435. inc(i2);
  1436. end;
  1437. while (i1<para1.count) and (i2<para2.count) do
  1438. begin
  1439. eq:=te_incompatible;
  1440. currpara1:=tparavarsym(para1[i1]);
  1441. currpara2:=tparavarsym(para2[i2]);
  1442. { Unique types must match exact }
  1443. if ((df_unique in currpara1.vardef.defoptions) or (df_unique in currpara2.vardef.defoptions)) and
  1444. (currpara1.vardef<>currpara2.vardef) then
  1445. exit;
  1446. { Handle hidden parameters separately, because self is
  1447. defined as voidpointer for methodpointers }
  1448. if (vo_is_hidden_para in currpara1.varoptions) or
  1449. (vo_is_hidden_para in currpara2.varoptions) then
  1450. begin
  1451. { both must be hidden }
  1452. if (vo_is_hidden_para in currpara1.varoptions)<>(vo_is_hidden_para in currpara2.varoptions) then
  1453. exit;
  1454. eq:=te_equal;
  1455. if not(vo_is_self in currpara1.varoptions) and
  1456. not(vo_is_self in currpara2.varoptions) then
  1457. begin
  1458. if (currpara1.varspez<>currpara2.varspez) then
  1459. exit;
  1460. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1461. convtype,hpd,cdoptions);
  1462. end;
  1463. end
  1464. else
  1465. begin
  1466. case acp of
  1467. cp_value_equal_const :
  1468. begin
  1469. if (
  1470. (currpara1.varspez<>currpara2.varspez) and
  1471. ((currpara1.varspez in [vs_var,vs_out]) or
  1472. (currpara2.varspez in [vs_var,vs_out]))
  1473. ) then
  1474. exit;
  1475. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1476. convtype,hpd,cdoptions);
  1477. end;
  1478. cp_all :
  1479. begin
  1480. if (currpara1.varspez<>currpara2.varspez) then
  1481. exit;
  1482. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1483. convtype,hpd,cdoptions);
  1484. end;
  1485. cp_procvar :
  1486. begin
  1487. if (currpara1.varspez<>currpara2.varspez) then
  1488. exit;
  1489. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1490. convtype,hpd,cdoptions);
  1491. { Parameters must be at least equal otherwise the are incompatible }
  1492. if (eq<te_equal) then
  1493. eq:=te_incompatible;
  1494. end;
  1495. else
  1496. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1497. convtype,hpd,cdoptions);
  1498. end;
  1499. end;
  1500. { check type }
  1501. if eq=te_incompatible then
  1502. exit;
  1503. if eq<lowesteq then
  1504. lowesteq:=eq;
  1505. { also check default value if both have it declared }
  1506. if (cpo_comparedefaultvalue in cpoptions) and
  1507. assigned(currpara1.defaultconstsym) and
  1508. assigned(currpara2.defaultconstsym) then
  1509. begin
  1510. if not equal_constsym(tconstsym(currpara1.defaultconstsym),tconstsym(currpara2.defaultconstsym)) then
  1511. exit;
  1512. end;
  1513. inc(i1);
  1514. inc(i2);
  1515. if cpo_ignorehidden in cpoptions then
  1516. begin
  1517. while (i1<para1.count) and
  1518. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1519. inc(i1);
  1520. while (i2<para2.count) and
  1521. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1522. inc(i2);
  1523. end;
  1524. end;
  1525. { when both lists are empty then the parameters are equal. Also
  1526. when one list is empty and the other has a parameter with default
  1527. value assigned then the parameters are also equal }
  1528. if ((i1>=para1.count) and (i2>=para2.count)) or
  1529. ((cpo_allowdefaults in cpoptions) and
  1530. (((i1<para1.count) and assigned(tparavarsym(para1[i1]).defaultconstsym)) or
  1531. ((i2<para2.count) and assigned(tparavarsym(para2[i2]).defaultconstsym)))) then
  1532. compare_paras:=lowesteq;
  1533. end;
  1534. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  1535. var
  1536. eq : tequaltype;
  1537. po_comp : tprocoptions;
  1538. begin
  1539. proc_to_procvar_equal:=te_incompatible;
  1540. if not(assigned(def1)) or not(assigned(def2)) then
  1541. exit;
  1542. { check for method pointer }
  1543. if (def1.is_methodpointer xor def2.is_methodpointer) or
  1544. (def1.is_addressonly xor def2.is_addressonly) then
  1545. exit;
  1546. { check return value and options, methodpointer is already checked }
  1547. po_comp:=[po_staticmethod,po_interrupt,
  1548. po_iocheck,po_varargs];
  1549. if (m_delphi in current_settings.modeswitches) then
  1550. exclude(po_comp,po_varargs);
  1551. if (def1.proccalloption=def2.proccalloption) and
  1552. ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1553. equal_defs(def1.returndef,def2.returndef) then
  1554. begin
  1555. { return equal type based on the parameters, but a proc->procvar
  1556. is never exact, so map an exact match of the parameters to
  1557. te_equal }
  1558. eq:=compare_paras(def1.paras,def2.paras,cp_procvar,[]);
  1559. if eq=te_exact then
  1560. eq:=te_equal;
  1561. proc_to_procvar_equal:=eq;
  1562. end;
  1563. end;
  1564. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  1565. begin
  1566. compatible_childmethod_resultdef :=
  1567. (equal_defs(parentretdef,childretdef)) or
  1568. ((parentretdef.typ=objectdef) and
  1569. (childretdef.typ=objectdef) and
  1570. is_class_or_interface(parentretdef) and
  1571. is_class_or_interface(childretdef) and
  1572. (tobjectdef(childretdef).is_related(tobjectdef(parentretdef))))
  1573. end;
  1574. end.