defcmp.pas 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942
  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 = (
  29. cpo_allowdefaults,
  30. cpo_ignorehidden, // ignore hidden parameters
  31. cpo_allowconvert,
  32. cpo_comparedefaultvalue,
  33. cpo_openequalisexact,
  34. cpo_ignoreuniv,
  35. cpo_warn_incompatible_univ,
  36. cpo_ignorevarspez, // ignore parameter access type
  37. cpo_ignoreframepointer, // ignore frame pointer parameter (for assignment-compatibility of global procedures to nested procvars)
  38. cpo_compilerproc,
  39. cpo_rtlproc
  40. );
  41. tcompare_paras_options = set of tcompare_paras_option;
  42. tcompare_defs_option = (cdo_internal,cdo_explicit,cdo_check_operator,cdo_allow_variant,cdo_parameter,cdo_warn_incompatible_univ);
  43. tcompare_defs_options = set of tcompare_defs_option;
  44. tconverttype = (tc_none,
  45. tc_equal,
  46. tc_not_possible,
  47. tc_string_2_string,
  48. tc_char_2_string,
  49. tc_char_2_chararray,
  50. tc_pchar_2_string,
  51. tc_cchar_2_pchar,
  52. tc_cstring_2_pchar,
  53. tc_cstring_2_int,
  54. tc_ansistring_2_pchar,
  55. tc_string_2_chararray,
  56. tc_chararray_2_string,
  57. tc_array_2_pointer,
  58. tc_pointer_2_array,
  59. tc_int_2_int,
  60. tc_int_2_bool,
  61. tc_bool_2_bool,
  62. tc_bool_2_int,
  63. tc_real_2_real,
  64. tc_int_2_real,
  65. tc_real_2_currency,
  66. tc_proc_2_procvar,
  67. tc_nil_2_methodprocvar,
  68. tc_arrayconstructor_2_set,
  69. tc_set_to_set,
  70. tc_cord_2_pointer,
  71. tc_intf_2_string,
  72. tc_intf_2_guid,
  73. tc_class_2_intf,
  74. tc_char_2_char,
  75. tc_dynarray_2_openarray,
  76. tc_pwchar_2_string,
  77. tc_variant_2_dynarray,
  78. tc_dynarray_2_variant,
  79. tc_variant_2_enum,
  80. tc_enum_2_variant,
  81. tc_interface_2_variant,
  82. tc_variant_2_interface,
  83. tc_array_2_dynarray
  84. );
  85. function compare_defs_ext(def_from,def_to : tdef;
  86. fromtreetype : tnodetype;
  87. var doconv : tconverttype;
  88. var operatorpd : tprocdef;
  89. cdoptions:tcompare_defs_options):tequaltype;
  90. { Returns if the type def_from can be converted to def_to or if both types are equal }
  91. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  92. { Returns true, if def1 and def2 are semantically the same }
  93. function equal_defs(def_from,def_to:tdef):boolean;
  94. { Checks for type compatibility (subgroups of type)
  95. used for case statements... probably missing stuff
  96. to use on other types }
  97. function is_subequal(def1, def2: tdef): boolean;
  98. {# true, if two parameter lists are equal
  99. if acp is cp_all, all have to match exactly
  100. if acp is cp_value_equal_const call by value
  101. and call by const parameter are assumed as
  102. equal
  103. if acp is cp_procvar then the varspez have to match,
  104. and all parameter types must be at least te_equal
  105. if acp is cp_none, then we don't check the varspez at all
  106. allowdefaults indicates if default value parameters
  107. are allowed (in this case, the search order will first
  108. search for a routine with default parameters, before
  109. searching for the same definition with no parameters)
  110. }
  111. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  112. { True if a function can be assigned to a procvar }
  113. { changed first argument type to pabstractprocdef so that it can also be }
  114. { used to test compatibility between two pprocvardefs (JM) }
  115. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef;checkincompatibleuniv: boolean):tequaltype;
  116. { Parentdef is the definition of a method defined in a parent class or interface }
  117. { Childdef is the definition of a method defined in a child class, interface or }
  118. { a class implementing an interface with parentdef. }
  119. { Returns true if the resultdef of childdef can be used to implement/override }
  120. { parentdef's resultdef }
  121. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  122. implementation
  123. uses
  124. verbose,systems,constexp,
  125. symtable,symsym,
  126. defutil,symutil;
  127. function compare_defs_ext(def_from,def_to : tdef;
  128. fromtreetype : tnodetype;
  129. var doconv : tconverttype;
  130. var operatorpd : tprocdef;
  131. cdoptions:tcompare_defs_options):tequaltype;
  132. { tordtype:
  133. uvoid,
  134. u8bit,u16bit,u32bit,u64bit,
  135. s8bit,s16bit,s32bit,s64bit,
  136. pasbool, bool8bit,bool16bit,bool32bit,bool64bit,
  137. uchar,uwidechar,scurrency }
  138. type
  139. tbasedef=(bvoid,bchar,bint,bbool);
  140. const
  141. basedeftbl:array[tordtype] of tbasedef =
  142. (bvoid,
  143. bint,bint,bint,bint,
  144. bint,bint,bint,bint,
  145. bbool,bbool,bbool,bbool,
  146. bbool,bbool,bbool,bbool,
  147. bchar,bchar,bint);
  148. basedefconvertsimplicit : array[tbasedef,tbasedef] of tconverttype =
  149. { void, char, int, bool }
  150. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  151. (tc_not_possible,tc_char_2_char,tc_not_possible,tc_not_possible),
  152. (tc_not_possible,tc_not_possible,tc_int_2_int,tc_not_possible),
  153. (tc_not_possible,tc_not_possible,tc_not_possible,tc_bool_2_bool));
  154. basedefconvertsexplicit : array[tbasedef,tbasedef] of tconverttype =
  155. { void, char, int, bool }
  156. ((tc_not_possible,tc_not_possible,tc_not_possible,tc_not_possible),
  157. (tc_not_possible,tc_char_2_char,tc_int_2_int,tc_int_2_bool),
  158. (tc_not_possible,tc_int_2_int,tc_int_2_int,tc_int_2_bool),
  159. (tc_not_possible,tc_bool_2_int,tc_bool_2_int,tc_bool_2_bool));
  160. var
  161. subeq,eq : tequaltype;
  162. hd1,hd2 : tdef;
  163. hct : tconverttype;
  164. hobjdef : tobjectdef;
  165. hpd : tprocdef;
  166. begin
  167. eq:=te_incompatible;
  168. doconv:=tc_not_possible;
  169. { safety check }
  170. if not(assigned(def_from) and assigned(def_to)) then
  171. begin
  172. compare_defs_ext:=te_incompatible;
  173. exit;
  174. end;
  175. { same def? then we've an exact match }
  176. if def_from=def_to then
  177. begin
  178. doconv:=tc_equal;
  179. compare_defs_ext:=te_exact;
  180. exit;
  181. end;
  182. { undefined def? then mark it as equal }
  183. if (def_from.typ=undefineddef) or
  184. (def_to.typ=undefineddef) then
  185. begin
  186. doconv:=tc_equal;
  187. compare_defs_ext:=te_exact;
  188. exit;
  189. end;
  190. { we walk the wanted (def_to) types and check then the def_from
  191. types if there is a conversion possible }
  192. case def_to.typ of
  193. orddef :
  194. begin
  195. case def_from.typ of
  196. orddef :
  197. begin
  198. if (torddef(def_from).ordtype=torddef(def_to).ordtype) then
  199. begin
  200. case torddef(def_from).ordtype of
  201. uchar,uwidechar,
  202. u8bit,u16bit,u32bit,u64bit,
  203. s8bit,s16bit,s32bit,s64bit:
  204. begin
  205. if (torddef(def_from).low>=torddef(def_to).low) and
  206. (torddef(def_from).high<=torddef(def_to).high) then
  207. eq:=te_equal
  208. else
  209. begin
  210. doconv:=tc_int_2_int;
  211. eq:=te_convert_l1;
  212. end;
  213. end;
  214. uvoid,
  215. pasbool8,pasbool16,pasbool32,pasbool64,
  216. bool8bit,bool16bit,bool32bit,bool64bit:
  217. eq:=te_equal;
  218. else
  219. internalerror(200210061);
  220. end;
  221. end
  222. else
  223. begin
  224. if cdo_explicit in cdoptions then
  225. doconv:=basedefconvertsexplicit[basedeftbl[torddef(def_from).ordtype],basedeftbl[torddef(def_to).ordtype]]
  226. else
  227. doconv:=basedefconvertsimplicit[basedeftbl[torddef(def_from).ordtype],basedeftbl[torddef(def_to).ordtype]];
  228. if (doconv=tc_not_possible) then
  229. eq:=te_incompatible
  230. else if (not is_in_limit(def_from,def_to)) then
  231. { "punish" bad type conversions :) (JM) }
  232. eq:=te_convert_l3
  233. else
  234. eq:=te_convert_l1;
  235. end;
  236. end;
  237. enumdef :
  238. begin
  239. { needed for char(enum) }
  240. if cdo_explicit in cdoptions then
  241. begin
  242. doconv:=tc_int_2_int;
  243. eq:=te_convert_l1;
  244. end;
  245. end;
  246. floatdef :
  247. begin
  248. if is_currency(def_to) then
  249. begin
  250. doconv:=tc_real_2_currency;
  251. eq:=te_convert_l2;
  252. end;
  253. end;
  254. objectdef:
  255. begin
  256. if (m_delphi in current_settings.modeswitches) and
  257. is_implicit_pointer_object_type(def_from) and
  258. (cdo_explicit in cdoptions) then
  259. begin
  260. eq:=te_convert_l1;
  261. if (fromtreetype=niln) then
  262. begin
  263. { will be handled by the constant folding }
  264. doconv:=tc_equal;
  265. end
  266. else
  267. doconv:=tc_int_2_int;
  268. end;
  269. end;
  270. classrefdef,
  271. procvardef,
  272. pointerdef :
  273. begin
  274. if cdo_explicit in cdoptions then
  275. begin
  276. eq:=te_convert_l1;
  277. if (fromtreetype=niln) then
  278. begin
  279. { will be handled by the constant folding }
  280. doconv:=tc_equal;
  281. end
  282. else
  283. doconv:=tc_int_2_int;
  284. end;
  285. end;
  286. arraydef :
  287. begin
  288. if (m_mac in current_settings.modeswitches) and
  289. (fromtreetype=stringconstn) then
  290. begin
  291. eq:=te_convert_l3;
  292. doconv:=tc_cstring_2_int;
  293. end;
  294. end;
  295. end;
  296. end;
  297. stringdef :
  298. begin
  299. case def_from.typ of
  300. stringdef :
  301. begin
  302. { Constant string }
  303. if (fromtreetype=stringconstn) then
  304. begin
  305. if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) and
  306. ((tstringdef(def_from).stringtype<>st_ansistring) or
  307. (tstringdef(def_from).encoding=tstringdef(def_to).encoding)
  308. ) then
  309. eq:=te_equal
  310. else
  311. begin
  312. doconv:=tc_string_2_string;
  313. if (tstringdef(def_from).stringtype = st_ansistring) and
  314. (tstringdef(def_to).stringtype = st_ansistring) then
  315. if (tstringdef(def_to).encoding=globals.CP_UTF8) then
  316. eq:=te_convert_l1
  317. else
  318. eq:=te_convert_l2
  319. else
  320. begin
  321. { Don't prefer conversions from widestring to a
  322. normal string as we can lose information }
  323. if (tstringdef(def_from).stringtype in [st_widestring,st_unicodestring]) and
  324. not (tstringdef(def_to).stringtype in [st_widestring,st_unicodestring]) then
  325. eq:=te_convert_l3
  326. else if tstringdef(def_to).stringtype in [st_widestring,st_unicodestring] then
  327. eq:=te_convert_l2
  328. else
  329. eq:=te_convert_l1;
  330. end;
  331. end;
  332. end
  333. else if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) and
  334. (tstringdef(def_from).stringtype=st_ansistring) then
  335. begin
  336. { don't convert ansistrings if any conditions is true:
  337. 1) same encoding
  338. 2) from explicit codepage ansistring to ansistring and vice versa
  339. 3) from any ansistring to rawbytestring }
  340. if (tstringdef(def_from).encoding=tstringdef(def_to).encoding) or
  341. ((tstringdef(def_to).encoding=0) and (tstringdef(def_from).encoding=getansistringcodepage)) or
  342. ((tstringdef(def_to).encoding=getansistringcodepage) and (tstringdef(def_from).encoding=0)) or
  343. (tstringdef(def_to).encoding=globals.CP_NONE) then
  344. begin
  345. eq:=te_equal;
  346. end
  347. else
  348. begin
  349. doconv := tc_string_2_string;
  350. if (tstringdef(def_to).encoding=globals.CP_UTF8) then
  351. eq:=te_convert_l1
  352. else
  353. eq:=te_convert_l2;
  354. end
  355. end
  356. else
  357. { same string type ? }
  358. if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) and
  359. { for shortstrings also the length must match }
  360. ((tstringdef(def_from).stringtype<>st_shortstring) or
  361. (tstringdef(def_from).len=tstringdef(def_to).len)) and
  362. { for ansi- and unicodestrings also the encoding must match }
  363. (not(tstringdef(def_from).stringtype in [st_ansistring,st_unicodestring]) or
  364. (tstringdef(def_from).encoding=tstringdef(def_to).encoding)) then
  365. eq:=te_equal
  366. else
  367. begin
  368. doconv:=tc_string_2_string;
  369. case tstringdef(def_from).stringtype of
  370. st_widestring :
  371. begin
  372. { Prefer conversions to unicodestring }
  373. if tstringdef(def_to).stringtype=st_unicodestring then
  374. eq:=te_convert_l1
  375. { else prefer conversions to ansistring }
  376. else if tstringdef(def_to).stringtype=st_ansistring then
  377. eq:=te_convert_l2
  378. else
  379. eq:=te_convert_l3;
  380. end;
  381. st_unicodestring :
  382. begin
  383. { Prefer conversions to widestring }
  384. if tstringdef(def_to).stringtype=st_widestring then
  385. eq:=te_convert_l1
  386. { else prefer conversions to ansistring }
  387. else if tstringdef(def_to).stringtype=st_ansistring then
  388. eq:=te_convert_l2
  389. else
  390. eq:=te_convert_l3;
  391. end;
  392. st_shortstring :
  393. begin
  394. { Prefer shortstrings of different length or conversions
  395. from shortstring to ansistring }
  396. if (tstringdef(def_to).stringtype=st_shortstring) then
  397. eq:=te_convert_l1
  398. else if tstringdef(def_to).stringtype=st_ansistring then
  399. eq:=te_convert_l2
  400. else
  401. eq:=te_convert_l3;
  402. end;
  403. st_ansistring :
  404. begin
  405. { Prefer conversion to widestrings }
  406. if (tstringdef(def_to).stringtype in [st_widestring,st_unicodestring]) then
  407. eq:=te_convert_l2
  408. else
  409. eq:=te_convert_l3;
  410. end;
  411. end;
  412. end;
  413. end;
  414. orddef :
  415. begin
  416. { char to string}
  417. if is_char(def_from) or
  418. is_widechar(def_from) then
  419. begin
  420. doconv:=tc_char_2_string;
  421. eq:=te_convert_l1;
  422. end;
  423. end;
  424. arraydef :
  425. begin
  426. { array of char to string, the length check is done by the firstpass of this node }
  427. if is_chararray(def_from) or is_open_chararray(def_from) then
  428. begin
  429. { "Untyped" stringconstn is an array of char }
  430. if fromtreetype=stringconstn then
  431. begin
  432. doconv:=tc_string_2_string;
  433. { prefered string type depends on the $H switch }
  434. if not(cs_ansistrings in current_settings.localswitches) and
  435. (tstringdef(def_to).stringtype=st_shortstring) then
  436. eq:=te_equal
  437. else if (cs_ansistrings in current_settings.localswitches) and
  438. (tstringdef(def_to).stringtype=st_ansistring) then
  439. eq:=te_equal
  440. else if tstringdef(def_to).stringtype in [st_widestring,st_unicodestring] then
  441. eq:=te_convert_l3
  442. else
  443. eq:=te_convert_l1;
  444. end
  445. else
  446. begin
  447. doconv:=tc_chararray_2_string;
  448. if is_open_array(def_from) then
  449. begin
  450. if is_ansistring(def_to) then
  451. eq:=te_convert_l1
  452. else if is_widestring(def_to) or is_unicodestring(def_to) then
  453. eq:=te_convert_l3
  454. else
  455. eq:=te_convert_l2;
  456. end
  457. else
  458. begin
  459. if is_shortstring(def_to) then
  460. begin
  461. { Only compatible with arrays that fit
  462. smaller than 255 chars }
  463. if (def_from.size <= 255) then
  464. eq:=te_convert_l1;
  465. end
  466. else if is_ansistring(def_to) then
  467. begin
  468. if (def_from.size > 255) then
  469. eq:=te_convert_l1
  470. else
  471. eq:=te_convert_l2;
  472. end
  473. else if is_widestring(def_to) or is_unicodestring(def_to) then
  474. eq:=te_convert_l3
  475. else
  476. eq:=te_convert_l2;
  477. end;
  478. end;
  479. end
  480. else
  481. { array of widechar to string, the length check is done by the firstpass of this node }
  482. if is_widechararray(def_from) or is_open_widechararray(def_from) then
  483. begin
  484. doconv:=tc_chararray_2_string;
  485. if is_widestring(def_to) or is_unicodestring(def_to) then
  486. eq:=te_convert_l1
  487. else
  488. { size of widechar array is double due the sizeof a widechar }
  489. if not(is_shortstring(def_to) and (is_open_widechararray(def_from) or (def_from.size>255*sizeof(widechar)))) then
  490. eq:=te_convert_l3
  491. else
  492. eq:=te_convert_l2;
  493. end;
  494. end;
  495. pointerdef :
  496. begin
  497. { pchar can be assigned to short/ansistrings,
  498. but not in tp7 compatible mode }
  499. if not(m_tp7 in current_settings.modeswitches) then
  500. begin
  501. if is_pchar(def_from) then
  502. begin
  503. doconv:=tc_pchar_2_string;
  504. { prefer ansistrings because pchars can overflow shortstrings, }
  505. { but only if ansistrings are the default (JM) }
  506. if (is_shortstring(def_to) and
  507. not(cs_ansistrings in current_settings.localswitches)) or
  508. (is_ansistring(def_to) and
  509. (cs_ansistrings in current_settings.localswitches)) then
  510. eq:=te_convert_l1
  511. else
  512. eq:=te_convert_l2;
  513. end
  514. else if is_pwidechar(def_from) then
  515. begin
  516. doconv:=tc_pwchar_2_string;
  517. if is_widestring(def_to) or is_unicodestring(def_to) then
  518. eq:=te_convert_l1
  519. else
  520. eq:=te_convert_l3;
  521. end;
  522. end;
  523. end;
  524. objectdef :
  525. begin
  526. { corba interface -> id string }
  527. if is_interfacecorba(def_from) then
  528. begin
  529. doconv:=tc_intf_2_string;
  530. eq:=te_convert_l1;
  531. end;
  532. end;
  533. end;
  534. end;
  535. floatdef :
  536. begin
  537. case def_from.typ of
  538. orddef :
  539. begin { ordinal to real }
  540. { only for implicit and internal typecasts in tp/delphi }
  541. if (([cdo_explicit,cdo_internal] * cdoptions <> [cdo_explicit]) or
  542. ([m_tp7,m_delphi] * current_settings.modeswitches = [])) and
  543. (is_integer(def_from) or
  544. (is_currency(def_from) and
  545. (s64currencytype.typ = floatdef))) then
  546. begin
  547. doconv:=tc_int_2_real;
  548. { prefer single over others }
  549. if is_single(def_to) then
  550. eq:=te_convert_l3
  551. else
  552. eq:=te_convert_l4;
  553. end
  554. else if is_currency(def_from)
  555. { and (s64currencytype.typ = orddef)) } then
  556. begin
  557. { prefer conversion to orddef in this case, unless }
  558. { the orddef < currency (then it will get convert l3, }
  559. { and conversion to float is favoured) }
  560. doconv:=tc_int_2_real;
  561. eq:=te_convert_l2;
  562. end;
  563. end;
  564. floatdef :
  565. begin
  566. if tfloatdef(def_from).floattype=tfloatdef(def_to).floattype then
  567. eq:=te_equal
  568. else
  569. begin
  570. { Delphi does not allow explicit type conversions for float types like:
  571. single_var:=single(double_var);
  572. But if such conversion is inserted by compiler (internal) for some purpose,
  573. it should be allowed even in Delphi mode. }
  574. if (fromtreetype=realconstn) or
  575. not((cdoptions*[cdo_explicit,cdo_internal]=[cdo_explicit]) and
  576. (m_delphi in current_settings.modeswitches)) then
  577. begin
  578. doconv:=tc_real_2_real;
  579. { do we lose precision? }
  580. if (def_to.size<def_from.size) or
  581. (is_currency(def_from) and (tfloatdef(def_to).floattype in [s32real,s64real])) then
  582. eq:=te_convert_l2
  583. else
  584. eq:=te_convert_l1;
  585. end;
  586. end;
  587. end;
  588. end;
  589. end;
  590. enumdef :
  591. begin
  592. case def_from.typ of
  593. enumdef :
  594. begin
  595. if cdo_explicit in cdoptions then
  596. begin
  597. eq:=te_convert_l1;
  598. doconv:=tc_int_2_int;
  599. end
  600. else
  601. begin
  602. hd1:=def_from;
  603. while assigned(tenumdef(hd1).basedef) do
  604. hd1:=tenumdef(hd1).basedef;
  605. hd2:=def_to;
  606. while assigned(tenumdef(hd2).basedef) do
  607. hd2:=tenumdef(hd2).basedef;
  608. if (hd1=hd2) then
  609. begin
  610. eq:=te_convert_l1;
  611. { because of packenum they can have different sizes! (JM) }
  612. doconv:=tc_int_2_int;
  613. end
  614. else
  615. begin
  616. { assignment of an enum symbol to an unique type? }
  617. if (fromtreetype=ordconstn) and
  618. (tenumsym(tenumdef(hd1).getfirstsym)=tenumsym(tenumdef(hd2).getfirstsym)) then
  619. begin
  620. { because of packenum they can have different sizes! (JM) }
  621. eq:=te_convert_l1;
  622. doconv:=tc_int_2_int;
  623. end;
  624. end;
  625. end;
  626. end;
  627. orddef :
  628. begin
  629. if cdo_explicit in cdoptions then
  630. begin
  631. eq:=te_convert_l1;
  632. doconv:=tc_int_2_int;
  633. end;
  634. end;
  635. variantdef :
  636. begin
  637. eq:=te_convert_l1;
  638. doconv:=tc_variant_2_enum;
  639. end;
  640. pointerdef :
  641. begin
  642. { ugly, but delphi allows it }
  643. if (cdo_explicit in cdoptions) and
  644. (m_delphi in current_settings.modeswitches) then
  645. begin
  646. doconv:=tc_int_2_int;
  647. eq:=te_convert_l1;
  648. end;
  649. end;
  650. objectdef:
  651. begin
  652. { ugly, but delphi allows it }
  653. if (m_delphi in current_settings.modeswitches) and
  654. is_class_or_interface_or_dispinterface(def_from) and
  655. (cdo_explicit in cdoptions) then
  656. begin
  657. doconv:=tc_int_2_int;
  658. eq:=te_convert_l1;
  659. end;
  660. end;
  661. end;
  662. end;
  663. arraydef :
  664. begin
  665. { open array is also compatible with a single element of its base type.
  666. the extra check for deftyp is needed because equal defs can also return
  667. true if the def types are not the same, for example with dynarray to pointer. }
  668. if is_open_array(def_to) and
  669. (def_from.typ=tarraydef(def_to).elementdef.typ) and
  670. equal_defs(def_from,tarraydef(def_to).elementdef) then
  671. begin
  672. doconv:=tc_equal;
  673. { also update in htypechk.pas/var_para_allowed if changed
  674. here }
  675. eq:=te_convert_l3;
  676. end
  677. else
  678. begin
  679. case def_from.typ of
  680. arraydef :
  681. begin
  682. { from/to packed array -- packed chararrays are }
  683. { strings in ISO Pascal (at least if the lower bound }
  684. { is 1, but GPC makes all equal-length chararrays }
  685. { compatible), so treat those the same as regular }
  686. { char arrays }
  687. if (is_packed_array(def_from) and
  688. not is_chararray(def_from) and
  689. not is_widechararray(def_from)) xor
  690. (is_packed_array(def_to) and
  691. not is_chararray(def_to) and
  692. not is_widechararray(def_to)) then
  693. { both must be packed }
  694. begin
  695. compare_defs_ext:=te_incompatible;
  696. exit;
  697. end
  698. { to dynamic array }
  699. else if is_dynamic_array(def_to) then
  700. begin
  701. if equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  702. begin
  703. { dynamic array -> dynamic array }
  704. if is_dynamic_array(def_from) then
  705. eq:=te_equal
  706. { fpc modes only: array -> dyn. array }
  707. else if (current_settings.modeswitches*[m_objfpc,m_fpc]<>[]) and
  708. not(is_special_array(def_from)) and
  709. is_zero_based_array(def_from) then
  710. begin
  711. eq:=te_convert_l2;
  712. doconv:=tc_array_2_dynarray;
  713. end;
  714. end
  715. end
  716. else
  717. { to open array }
  718. if is_open_array(def_to) then
  719. begin
  720. { array constructor -> open array }
  721. if is_array_constructor(def_from) then
  722. begin
  723. if is_void(tarraydef(def_from).elementdef) then
  724. begin
  725. doconv:=tc_equal;
  726. eq:=te_convert_l1;
  727. end
  728. else
  729. begin
  730. subeq:=compare_defs_ext(tarraydef(def_from).elementdef,
  731. tarraydef(def_to).elementdef,
  732. { reason for cdo_allow_variant: see webtbs/tw7070a and webtbs/tw7070b }
  733. arrayconstructorn,hct,hpd,[cdo_check_operator,cdo_allow_variant]);
  734. if (subeq>=te_equal) then
  735. begin
  736. doconv:=tc_equal;
  737. eq:=te_convert_l1;
  738. end
  739. else
  740. if (subeq>te_incompatible) then
  741. begin
  742. doconv:=hct;
  743. eq:=te_convert_l2;
  744. end;
  745. end;
  746. end
  747. else
  748. { dynamic array -> open array }
  749. if is_dynamic_array(def_from) and
  750. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  751. begin
  752. doconv:=tc_dynarray_2_openarray;
  753. eq:=te_convert_l2;
  754. end
  755. else
  756. { open array -> open array }
  757. if is_open_array(def_from) and
  758. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  759. if tarraydef(def_from).elementdef=tarraydef(def_to).elementdef then
  760. eq:=te_exact
  761. else
  762. eq:=te_equal
  763. else
  764. { array -> open array }
  765. if not(cdo_parameter in cdoptions) and
  766. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  767. begin
  768. if fromtreetype=stringconstn then
  769. eq:=te_convert_l1
  770. else
  771. eq:=te_equal;
  772. end;
  773. end
  774. else
  775. { to array of const }
  776. if is_array_of_const(def_to) then
  777. begin
  778. if is_array_of_const(def_from) or
  779. is_array_constructor(def_from) then
  780. begin
  781. eq:=te_equal;
  782. end
  783. else
  784. { array of tvarrec -> array of const }
  785. if equal_defs(tarraydef(def_to).elementdef,tarraydef(def_from).elementdef) then
  786. begin
  787. doconv:=tc_equal;
  788. eq:=te_convert_l1;
  789. end;
  790. end
  791. else
  792. { to array of char, from "Untyped" stringconstn (array of char) }
  793. if (fromtreetype=stringconstn) and
  794. (is_chararray(def_to) or
  795. is_widechararray(def_to)) then
  796. begin
  797. eq:=te_convert_l1;
  798. doconv:=tc_string_2_chararray;
  799. end
  800. else
  801. { other arrays }
  802. begin
  803. { open array -> array }
  804. if not(cdo_parameter in cdoptions) and
  805. is_open_array(def_from) and
  806. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  807. begin
  808. eq:=te_equal
  809. end
  810. else
  811. { array -> array }
  812. if not(m_tp7 in current_settings.modeswitches) and
  813. not(m_delphi in current_settings.modeswitches) and
  814. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  815. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  816. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) and
  817. equal_defs(tarraydef(def_from).rangedef,tarraydef(def_to).rangedef) then
  818. begin
  819. eq:=te_equal
  820. end;
  821. end;
  822. end;
  823. pointerdef :
  824. begin
  825. { nil and voidpointers are compatible with dyn. arrays }
  826. if is_dynamic_array(def_to) and
  827. ((fromtreetype=niln) or
  828. is_voidpointer(def_from)) then
  829. begin
  830. doconv:=tc_equal;
  831. eq:=te_convert_l1;
  832. end
  833. else
  834. if is_zero_based_array(def_to) and
  835. equal_defs(tpointerdef(def_from).pointeddef,tarraydef(def_to).elementdef) then
  836. begin
  837. doconv:=tc_pointer_2_array;
  838. eq:=te_convert_l1;
  839. end;
  840. end;
  841. stringdef :
  842. begin
  843. { string to char array }
  844. if (not is_special_array(def_to)) and
  845. (is_char(tarraydef(def_to).elementdef)or
  846. is_widechar(tarraydef(def_to).elementdef)) then
  847. begin
  848. doconv:=tc_string_2_chararray;
  849. eq:=te_convert_l1;
  850. end;
  851. end;
  852. orddef:
  853. begin
  854. if is_chararray(def_to) and
  855. is_char(def_from) then
  856. begin
  857. doconv:=tc_char_2_chararray;
  858. eq:=te_convert_l2;
  859. end;
  860. end;
  861. recorddef :
  862. begin
  863. { tvarrec -> array of const }
  864. if is_array_of_const(def_to) and
  865. equal_defs(def_from,tarraydef(def_to).elementdef) then
  866. begin
  867. doconv:=tc_equal;
  868. eq:=te_convert_l1;
  869. end;
  870. end;
  871. variantdef :
  872. begin
  873. if is_dynamic_array(def_to) then
  874. begin
  875. doconv:=tc_variant_2_dynarray;
  876. eq:=te_convert_l1;
  877. end;
  878. end;
  879. end;
  880. end;
  881. end;
  882. variantdef :
  883. begin
  884. if (cdo_allow_variant in cdoptions) then
  885. begin
  886. case def_from.typ of
  887. enumdef :
  888. begin
  889. doconv:=tc_enum_2_variant;
  890. eq:=te_convert_l1;
  891. end;
  892. arraydef :
  893. begin
  894. if is_dynamic_array(def_from) then
  895. begin
  896. doconv:=tc_dynarray_2_variant;
  897. eq:=te_convert_l1;
  898. end;
  899. end;
  900. objectdef :
  901. begin
  902. { corbainterfaces not accepted, until we have
  903. runtime support for them in Variants (sergei) }
  904. if is_interfacecom_or_dispinterface(def_from) then
  905. begin
  906. doconv:=tc_interface_2_variant;
  907. eq:=te_convert_l1;
  908. end;
  909. end;
  910. variantdef :
  911. begin
  912. { doing this in the compiler avoids a lot of unncessary
  913. copying }
  914. if (tvariantdef(def_from).varianttype=vt_olevariant) and
  915. (tvariantdef(def_to).varianttype=vt_normalvariant) then
  916. begin
  917. doconv:=tc_equal;
  918. eq:=te_convert_l1;
  919. end;
  920. end;
  921. end;
  922. end;
  923. end;
  924. pointerdef :
  925. begin
  926. case def_from.typ of
  927. stringdef :
  928. begin
  929. { string constant (which can be part of array constructor)
  930. to zero terminated string constant }
  931. if (fromtreetype = stringconstn) and
  932. (is_pchar(def_to) or is_pwidechar(def_to)) then
  933. begin
  934. doconv:=tc_cstring_2_pchar;
  935. eq:=te_convert_l2;
  936. end
  937. else
  938. if (cdo_explicit in cdoptions) or (fromtreetype = arrayconstructorn) then
  939. begin
  940. { pchar(ansistring) }
  941. if is_pchar(def_to) and
  942. is_ansistring(def_from) then
  943. begin
  944. doconv:=tc_ansistring_2_pchar;
  945. eq:=te_convert_l1;
  946. end
  947. else
  948. { pwidechar(widestring) }
  949. if is_pwidechar(def_to) and
  950. is_wide_or_unicode_string(def_from) then
  951. begin
  952. doconv:=tc_ansistring_2_pchar;
  953. eq:=te_convert_l1;
  954. end;
  955. end;
  956. end;
  957. orddef :
  958. begin
  959. { char constant to zero terminated string constant }
  960. if (fromtreetype in [ordconstn,arrayconstructorn]) then
  961. begin
  962. if (is_char(def_from) or is_widechar(def_from)) and
  963. (is_pchar(def_to) or is_pwidechar(def_to)) then
  964. begin
  965. doconv:=tc_cchar_2_pchar;
  966. eq:=te_convert_l1;
  967. end
  968. else
  969. if (m_delphi in current_settings.modeswitches) and is_integer(def_from) then
  970. begin
  971. doconv:=tc_cord_2_pointer;
  972. eq:=te_convert_l5;
  973. end;
  974. end;
  975. { allow explicit typecasts from ordinals to pointer.
  976. Support for delphi compatibility
  977. Support constructs like pointer(cardinal-cardinal) or pointer(longint+cardinal) where
  978. the result of the ordinal operation is int64 also on 32 bit platforms.
  979. It is also used by the compiler internally for inc(pointer,ordinal) }
  980. if (eq=te_incompatible) and
  981. not is_void(def_from) and
  982. (
  983. (
  984. (cdo_explicit in cdoptions) and
  985. (
  986. (m_delphi in current_settings.modeswitches) or
  987. { Don't allow pchar(char) in fpc modes }
  988. is_integer(def_from)
  989. )
  990. ) or
  991. (cdo_internal in cdoptions)
  992. ) then
  993. begin
  994. doconv:=tc_int_2_int;
  995. eq:=te_convert_l1;
  996. end;
  997. end;
  998. enumdef :
  999. begin
  1000. { allow explicit typecasts from enums to pointer.
  1001. Support for delphi compatibility
  1002. }
  1003. if (((cdo_explicit in cdoptions) and
  1004. (m_delphi in current_settings.modeswitches)
  1005. ) or
  1006. (cdo_internal in cdoptions)
  1007. ) then
  1008. begin
  1009. doconv:=tc_int_2_int;
  1010. eq:=te_convert_l1;
  1011. end;
  1012. end;
  1013. arraydef :
  1014. begin
  1015. { string constant (which can be part of array constructor)
  1016. to zero terminated string constant }
  1017. if (((fromtreetype = arrayconstructorn) and
  1018. { can't use is_chararray, because returns false for }
  1019. { array constructors }
  1020. is_char(tarraydef(def_from).elementdef)) or
  1021. (fromtreetype = stringconstn)) and
  1022. (is_pchar(def_to) or is_pwidechar(def_to)) then
  1023. begin
  1024. doconv:=tc_cstring_2_pchar;
  1025. eq:=te_convert_l2;
  1026. end
  1027. else
  1028. { chararray to pointer }
  1029. if (is_zero_based_array(def_from) or
  1030. is_open_array(def_from)) and
  1031. equal_defs(tarraydef(def_from).elementdef,tpointerdef(def_to).pointeddef) then
  1032. begin
  1033. doconv:=tc_array_2_pointer;
  1034. { don't prefer the pchar overload when a constant
  1035. string was passed }
  1036. if fromtreetype=stringconstn then
  1037. eq:=te_convert_l2
  1038. else
  1039. eq:=te_convert_l1;
  1040. end
  1041. else
  1042. { dynamic array to pointer, delphi only }
  1043. if (m_delphi in current_settings.modeswitches) and
  1044. is_dynamic_array(def_from) and
  1045. is_voidpointer(def_to) then
  1046. begin
  1047. eq:=te_equal;
  1048. end;
  1049. end;
  1050. pointerdef :
  1051. begin
  1052. { check for far pointers }
  1053. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  1054. begin
  1055. eq:=te_incompatible;
  1056. end
  1057. else
  1058. { the types can be forward type, handle before normal type check !! }
  1059. if assigned(def_to.typesym) and
  1060. (tpointerdef(def_to).pointeddef.typ=forwarddef) then
  1061. begin
  1062. if (def_from.typesym=def_to.typesym) then
  1063. eq:=te_equal
  1064. end
  1065. else
  1066. { same types }
  1067. if equal_defs(tpointerdef(def_from).pointeddef,tpointerdef(def_to).pointeddef) then
  1068. begin
  1069. eq:=te_equal
  1070. end
  1071. else
  1072. { child class pointer can be assigned to anchestor pointers }
  1073. if (
  1074. (tpointerdef(def_from).pointeddef.typ=objectdef) and
  1075. (tpointerdef(def_to).pointeddef.typ=objectdef) and
  1076. tobjectdef(tpointerdef(def_from).pointeddef).is_related(
  1077. tobjectdef(tpointerdef(def_to).pointeddef))
  1078. ) then
  1079. begin
  1080. doconv:=tc_equal;
  1081. eq:=te_convert_l1;
  1082. end
  1083. else
  1084. { all pointers can be assigned to void-pointer }
  1085. if is_void(tpointerdef(def_to).pointeddef) then
  1086. begin
  1087. doconv:=tc_equal;
  1088. { give pwidechar,pchar a penalty so it prefers
  1089. conversion to ansistring }
  1090. if is_pchar(def_from) or
  1091. is_pwidechar(def_from) then
  1092. eq:=te_convert_l2
  1093. else
  1094. eq:=te_convert_l1;
  1095. end
  1096. else
  1097. { all pointers can be assigned from void-pointer }
  1098. if is_void(tpointerdef(def_from).pointeddef) or
  1099. { all pointers can be assigned from void-pointer or formaldef pointer, check
  1100. tw3777.pp if you change this }
  1101. (tpointerdef(def_from).pointeddef.typ=formaldef) then
  1102. begin
  1103. doconv:=tc_equal;
  1104. { give pwidechar a penalty so it prefers
  1105. conversion to pchar }
  1106. if is_pwidechar(def_to) then
  1107. eq:=te_convert_l2
  1108. else
  1109. eq:=te_convert_l1;
  1110. end
  1111. { id = generic class instance. metaclasses are also
  1112. class instances themselves. }
  1113. else if ((def_from=objc_idtype) and
  1114. (def_to=objc_metaclasstype)) or
  1115. ((def_to=objc_idtype) and
  1116. (def_from=objc_metaclasstype)) then
  1117. begin
  1118. doconv:=tc_equal;
  1119. eq:=te_convert_l2;
  1120. end;
  1121. end;
  1122. procvardef :
  1123. begin
  1124. { procedure variable can be assigned to an void pointer,
  1125. this is not allowed for complex procvars }
  1126. if (is_void(tpointerdef(def_to).pointeddef) or
  1127. (m_mac_procvar in current_settings.modeswitches)) and
  1128. tprocvardef(def_from).is_addressonly then
  1129. begin
  1130. doconv:=tc_equal;
  1131. eq:=te_convert_l1;
  1132. end;
  1133. end;
  1134. procdef :
  1135. begin
  1136. { procedure variable can be assigned to an void pointer,
  1137. this not allowed for methodpointers }
  1138. if (m_mac_procvar in current_settings.modeswitches) and
  1139. tprocdef(def_from).is_addressonly then
  1140. begin
  1141. doconv:=tc_proc_2_procvar;
  1142. eq:=te_convert_l2;
  1143. end;
  1144. end;
  1145. classrefdef,
  1146. objectdef :
  1147. begin
  1148. { implicit pointer object and class reference types
  1149. can be assigned to void pointers, but it is less
  1150. preferred than assigning to a related objectdef }
  1151. if (
  1152. is_implicit_pointer_object_type(def_from) or
  1153. (def_from.typ=classrefdef)
  1154. ) and
  1155. (tpointerdef(def_to).pointeddef.typ=orddef) and
  1156. (torddef(tpointerdef(def_to).pointeddef).ordtype=uvoid) then
  1157. begin
  1158. doconv:=tc_equal;
  1159. eq:=te_convert_l2;
  1160. end
  1161. else if (is_objc_class_or_protocol(def_from) and
  1162. (def_to=objc_idtype)) or
  1163. { classrefs are also instances in Objective-C,
  1164. hence they're also assignment-cpmpatible with
  1165. id }
  1166. (is_objcclassref(def_from) and
  1167. ((def_to=objc_metaclasstype) or
  1168. (def_to=objc_idtype))) then
  1169. begin
  1170. doconv:=tc_equal;
  1171. eq:=te_convert_l2;
  1172. end;
  1173. end;
  1174. end;
  1175. end;
  1176. setdef :
  1177. begin
  1178. case def_from.typ of
  1179. setdef :
  1180. begin
  1181. if assigned(tsetdef(def_from).elementdef) and
  1182. assigned(tsetdef(def_to).elementdef) then
  1183. begin
  1184. { sets with the same element base type and the same range are equal }
  1185. if equal_defs(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) and
  1186. (tsetdef(def_from).setbase=tsetdef(def_to).setbase) and
  1187. (tsetdef(def_from).setmax=tsetdef(def_to).setmax) then
  1188. eq:=te_equal
  1189. else if is_subequal(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) then
  1190. begin
  1191. eq:=te_convert_l1;
  1192. doconv:=tc_set_to_set;
  1193. end;
  1194. end
  1195. else
  1196. begin
  1197. { empty set is compatible with everything }
  1198. eq:=te_convert_l1;
  1199. doconv:=tc_set_to_set;
  1200. end;
  1201. end;
  1202. arraydef :
  1203. begin
  1204. { automatic arrayconstructor -> set conversion }
  1205. if is_array_constructor(def_from) then
  1206. begin
  1207. doconv:=tc_arrayconstructor_2_set;
  1208. eq:=te_convert_l1;
  1209. end;
  1210. end;
  1211. end;
  1212. end;
  1213. procvardef :
  1214. begin
  1215. case def_from.typ of
  1216. procdef :
  1217. begin
  1218. { proc -> procvar }
  1219. if (m_tp_procvar in current_settings.modeswitches) or
  1220. (m_mac_procvar in current_settings.modeswitches) then
  1221. begin
  1222. subeq:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to),cdo_warn_incompatible_univ in cdoptions);
  1223. if subeq>te_incompatible then
  1224. begin
  1225. doconv:=tc_proc_2_procvar;
  1226. if subeq>te_convert_l5 then
  1227. eq:=pred(subeq)
  1228. else
  1229. eq:=subeq;
  1230. end;
  1231. end;
  1232. end;
  1233. procvardef :
  1234. begin
  1235. { procvar -> procvar }
  1236. eq:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to),cdo_warn_incompatible_univ in cdoptions);
  1237. end;
  1238. pointerdef :
  1239. begin
  1240. { nil is compatible with procvars }
  1241. if (fromtreetype=niln) then
  1242. begin
  1243. if not Tprocvardef(def_to).is_addressonly then
  1244. {Nil to method pointers requires to convert a single
  1245. pointer nil value to a two pointer procvardef.}
  1246. doconv:=tc_nil_2_methodprocvar
  1247. else
  1248. doconv:=tc_equal;
  1249. eq:=te_convert_l1;
  1250. end
  1251. else
  1252. { for example delphi allows the assignement from pointers }
  1253. { to procedure variables }
  1254. if (m_pointer_2_procedure in current_settings.modeswitches) and
  1255. is_void(tpointerdef(def_from).pointeddef) and
  1256. tprocvardef(def_to).is_addressonly then
  1257. begin
  1258. doconv:=tc_equal;
  1259. eq:=te_convert_l1;
  1260. end;
  1261. end;
  1262. end;
  1263. end;
  1264. objectdef :
  1265. begin
  1266. { Objective-C classes (handle anonymous externals) }
  1267. if (def_from.typ=objectdef) and
  1268. (find_real_objcclass_definition(tobjectdef(def_from),false) =
  1269. find_real_objcclass_definition(tobjectdef(def_to),false)) then
  1270. begin
  1271. doconv:=tc_equal;
  1272. { exact, not equal, because can change between interface
  1273. and implementation }
  1274. eq:=te_exact;
  1275. end
  1276. { object pascal objects }
  1277. else if (def_from.typ=objectdef) and
  1278. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  1279. begin
  1280. doconv:=tc_equal;
  1281. eq:=te_convert_l1;
  1282. end
  1283. else
  1284. { specific to implicit pointer object types }
  1285. if is_implicit_pointer_object_type(def_to) then
  1286. begin
  1287. { void pointer also for delphi mode }
  1288. if (m_delphi in current_settings.modeswitches) and
  1289. is_voidpointer(def_from) then
  1290. begin
  1291. doconv:=tc_equal;
  1292. { prefer pointer-pointer assignments }
  1293. eq:=te_convert_l2;
  1294. end
  1295. else
  1296. { nil is compatible with class instances and interfaces }
  1297. if (fromtreetype=niln) then
  1298. begin
  1299. doconv:=tc_equal;
  1300. eq:=te_convert_l1;
  1301. end
  1302. { All Objective-C classes are compatible with ID }
  1303. else if is_objc_class_or_protocol(def_to) and
  1304. (def_from=objc_idtype) then
  1305. begin
  1306. doconv:=tc_equal;
  1307. eq:=te_convert_l2;
  1308. end
  1309. { classes can be assigned to interfaces
  1310. (same with objcclass and objcprotocol) }
  1311. else if ((is_interface(def_to) and
  1312. is_class(def_from)) or
  1313. (is_objcprotocol(def_to) and
  1314. is_objcclass(def_from))) and
  1315. assigned(tobjectdef(def_from).ImplementedInterfaces) then
  1316. begin
  1317. { we've to search in parent classes as well }
  1318. hobjdef:=tobjectdef(def_from);
  1319. while assigned(hobjdef) do
  1320. begin
  1321. if hobjdef.find_implemented_interface(tobjectdef(def_to))<>nil then
  1322. begin
  1323. if is_interface(def_to) then
  1324. doconv:=tc_class_2_intf
  1325. else
  1326. { for Objective-C, we don't have to do anything special }
  1327. doconv:=tc_equal;
  1328. { don't prefer this over objectdef->objectdef }
  1329. eq:=te_convert_l2;
  1330. break;
  1331. end;
  1332. hobjdef:=hobjdef.childof;
  1333. end;
  1334. end
  1335. { Interface 2 GUID handling }
  1336. else if (def_to=tdef(rec_tguid)) and
  1337. (fromtreetype=typen) and
  1338. is_interface(def_from) and
  1339. assigned(tobjectdef(def_from).iidguid) then
  1340. begin
  1341. eq:=te_convert_l1;
  1342. doconv:=tc_equal;
  1343. end
  1344. else if (def_from.typ=variantdef) and is_interfacecom_or_dispinterface(def_to) then
  1345. begin
  1346. { corbainterfaces not accepted, until we have
  1347. runtime support for them in Variants (sergei) }
  1348. doconv:=tc_variant_2_interface;
  1349. eq:=te_convert_l2;
  1350. end
  1351. { ugly, but delphi allows it }
  1352. else if (def_from.typ in [orddef,enumdef]) and
  1353. (m_delphi in current_settings.modeswitches) and
  1354. (cdo_explicit in cdoptions) then
  1355. begin
  1356. doconv:=tc_int_2_int;
  1357. eq:=te_convert_l1;
  1358. end;
  1359. end;
  1360. end;
  1361. classrefdef :
  1362. begin
  1363. { similar to pointerdef wrt forwards }
  1364. if assigned(def_to.typesym) and
  1365. (tclassrefdef(def_to).pointeddef.typ=forwarddef) then
  1366. begin
  1367. if (def_from.typesym=def_to.typesym) then
  1368. eq:=te_equal;
  1369. end
  1370. else
  1371. { class reference types }
  1372. if (def_from.typ=classrefdef) then
  1373. begin
  1374. if equal_defs(tclassrefdef(def_from).pointeddef,tclassrefdef(def_to).pointeddef) then
  1375. begin
  1376. eq:=te_equal;
  1377. end
  1378. else
  1379. begin
  1380. doconv:=tc_equal;
  1381. if (cdo_explicit in cdoptions) or
  1382. tobjectdef(tclassrefdef(def_from).pointeddef).is_related(
  1383. tobjectdef(tclassrefdef(def_to).pointeddef)) then
  1384. eq:=te_convert_l1;
  1385. end;
  1386. end
  1387. else
  1388. if (m_delphi in current_settings.modeswitches) and
  1389. is_voidpointer(def_from) then
  1390. begin
  1391. doconv:=tc_equal;
  1392. { prefer pointer-pointer assignments }
  1393. eq:=te_convert_l2;
  1394. end
  1395. else
  1396. { nil is compatible with class references }
  1397. if (fromtreetype=niln) then
  1398. begin
  1399. doconv:=tc_equal;
  1400. eq:=te_convert_l1;
  1401. end
  1402. else
  1403. { id is compatible with all classref types }
  1404. if (def_from=objc_idtype) then
  1405. begin
  1406. doconv:=tc_equal;
  1407. eq:=te_convert_l1;
  1408. end;
  1409. end;
  1410. filedef :
  1411. begin
  1412. { typed files are all equal to the abstract file type
  1413. name TYPEDFILE in system.pp in is_equal in types.pas
  1414. the problem is that it sholud be also compatible to FILE
  1415. but this would leed to a problem for ASSIGN RESET and REWRITE
  1416. when trying to find the good overloaded function !!
  1417. so all file function are doubled in system.pp
  1418. this is not very beautiful !!}
  1419. if (def_from.typ=filedef) then
  1420. begin
  1421. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  1422. begin
  1423. if
  1424. (
  1425. (tfiledef(def_from).typedfiledef=nil) and
  1426. (tfiledef(def_to).typedfiledef=nil)
  1427. ) or
  1428. (
  1429. (tfiledef(def_from).typedfiledef<>nil) and
  1430. (tfiledef(def_to).typedfiledef<>nil) and
  1431. equal_defs(tfiledef(def_from).typedfiledef,tfiledef(def_to).typedfiledef)
  1432. ) or
  1433. (
  1434. (tfiledef(def_from).filetyp = ft_typed) and
  1435. (tfiledef(def_to).filetyp = ft_typed) and
  1436. (
  1437. (tfiledef(def_from).typedfiledef = tdef(voidtype)) or
  1438. (tfiledef(def_to).typedfiledef = tdef(voidtype))
  1439. )
  1440. ) then
  1441. begin
  1442. eq:=te_equal;
  1443. end;
  1444. end
  1445. else
  1446. if ((tfiledef(def_from).filetyp = ft_untyped) and
  1447. (tfiledef(def_to).filetyp = ft_typed)) or
  1448. ((tfiledef(def_from).filetyp = ft_typed) and
  1449. (tfiledef(def_to).filetyp = ft_untyped)) then
  1450. begin
  1451. doconv:=tc_equal;
  1452. eq:=te_convert_l1;
  1453. end;
  1454. end;
  1455. end;
  1456. recorddef :
  1457. begin
  1458. { interface -> guid }
  1459. if (def_to=rec_tguid) and
  1460. (is_interfacecom_or_dispinterface(def_from)) then
  1461. begin
  1462. doconv:=tc_intf_2_guid;
  1463. eq:=te_convert_l1;
  1464. end;
  1465. end;
  1466. formaldef :
  1467. begin
  1468. doconv:=tc_equal;
  1469. if (def_from.typ=formaldef) then
  1470. eq:=te_equal
  1471. else
  1472. { Just about everything can be converted to a formaldef...}
  1473. if not (def_from.typ in [abstractdef,errordef]) then
  1474. eq:=te_convert_l2;
  1475. end;
  1476. end;
  1477. { if we didn't find an appropriate type conversion yet
  1478. then we search also the := operator }
  1479. if (eq=te_incompatible) and
  1480. { make sure there is not a single variant if variants }
  1481. { are not allowed (otherwise if only cdo_check_operator }
  1482. { and e.g. fromdef=stringdef and todef=variantdef, then }
  1483. { the test will still succeed }
  1484. ((cdo_allow_variant in cdoptions) or
  1485. ((def_from.typ<>variantdef) and (def_to.typ<>variantdef))
  1486. ) and
  1487. (
  1488. { Check for variants? }
  1489. (
  1490. (cdo_allow_variant in cdoptions) and
  1491. ((def_from.typ=variantdef) or (def_to.typ=variantdef))
  1492. ) or
  1493. { Check for operators? }
  1494. (
  1495. (cdo_check_operator in cdoptions) and
  1496. ((def_from.typ<>variantdef) or (def_to.typ<>variantdef))
  1497. )
  1498. ) then
  1499. begin
  1500. operatorpd:=search_assignment_operator(def_from,def_to,cdo_explicit in cdoptions);
  1501. if assigned(operatorpd) then
  1502. eq:=te_convert_operator;
  1503. end;
  1504. { update convtype for te_equal when it is not yet set }
  1505. if (eq=te_equal) and
  1506. (doconv=tc_not_possible) then
  1507. doconv:=tc_equal;
  1508. compare_defs_ext:=eq;
  1509. end;
  1510. function equal_defs(def_from,def_to:tdef):boolean;
  1511. var
  1512. convtyp : tconverttype;
  1513. pd : tprocdef;
  1514. begin
  1515. { Compare defs with nothingn and no explicit typecasts and
  1516. searching for overloaded operators is not needed }
  1517. equal_defs:=(compare_defs_ext(def_from,def_to,nothingn,convtyp,pd,[])>=te_equal);
  1518. end;
  1519. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  1520. var
  1521. doconv : tconverttype;
  1522. pd : tprocdef;
  1523. begin
  1524. compare_defs:=compare_defs_ext(def_from,def_to,fromtreetype,doconv,pd,[cdo_check_operator,cdo_allow_variant]);
  1525. end;
  1526. function is_subequal(def1, def2: tdef): boolean;
  1527. var
  1528. basedef1,basedef2 : tenumdef;
  1529. Begin
  1530. is_subequal := false;
  1531. if assigned(def1) and assigned(def2) then
  1532. Begin
  1533. if (def1.typ = orddef) and (def2.typ = orddef) then
  1534. Begin
  1535. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  1536. { range checking for case statements is done with testrange }
  1537. case torddef(def1).ordtype of
  1538. u8bit,u16bit,u32bit,u64bit,
  1539. s8bit,s16bit,s32bit,s64bit :
  1540. is_subequal:=(torddef(def2).ordtype in [s64bit,u64bit,s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  1541. pasbool8,pasbool16,pasbool32,pasbool64,
  1542. bool8bit,bool16bit,bool32bit,bool64bit :
  1543. is_subequal:=(torddef(def2).ordtype in [pasbool8,pasbool16,pasbool32,pasbool64,bool8bit,bool16bit,bool32bit,bool64bit]);
  1544. uchar :
  1545. is_subequal:=(torddef(def2).ordtype=uchar);
  1546. uwidechar :
  1547. is_subequal:=(torddef(def2).ordtype=uwidechar);
  1548. end;
  1549. end
  1550. else
  1551. Begin
  1552. { Check if both basedefs are equal }
  1553. if (def1.typ=enumdef) and (def2.typ=enumdef) then
  1554. Begin
  1555. { get both basedefs }
  1556. basedef1:=tenumdef(def1);
  1557. while assigned(basedef1.basedef) do
  1558. basedef1:=basedef1.basedef;
  1559. basedef2:=tenumdef(def2);
  1560. while assigned(basedef2.basedef) do
  1561. basedef2:=basedef2.basedef;
  1562. is_subequal:=(basedef1=basedef2);
  1563. end;
  1564. end;
  1565. end;
  1566. end;
  1567. function potentially_incompatible_univ_paras(def1, def2: tdef): boolean;
  1568. begin
  1569. result :=
  1570. { not entirely safe: different records can be passed differently
  1571. depending on the types of their fields, but they're hard to compare
  1572. (variant records, bitpacked vs non-bitpacked) }
  1573. ((def1.typ in [floatdef,recorddef,arraydef,filedef,variantdef]) and
  1574. (def1.typ<>def2.typ)) or
  1575. { pointers, ordinals and small sets are all passed the same}
  1576. (((def1.typ in [orddef,enumdef,pointerdef,procvardef,classrefdef]) or
  1577. (is_class_or_interface_or_objc(def1)) or
  1578. is_dynamic_array(def1) or
  1579. is_smallset(def1) or
  1580. is_ansistring(def1) or
  1581. is_unicodestring(def1)) <>
  1582. (def2.typ in [orddef,enumdef,pointerdef,procvardef,classrefdef]) or
  1583. (is_class_or_interface_or_objc(def2)) or
  1584. is_dynamic_array(def2) or
  1585. is_smallset(def2) or
  1586. is_ansistring(def2) or
  1587. is_unicodestring(def2)) or
  1588. { shortstrings }
  1589. (is_shortstring(def1)<>
  1590. is_shortstring(def2)) or
  1591. { winlike widestrings }
  1592. (is_widestring(def1)<>
  1593. is_widestring(def2)) or
  1594. { TP-style objects }
  1595. (is_object(def1) <>
  1596. is_object(def2));
  1597. end;
  1598. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  1599. var
  1600. currpara1,
  1601. currpara2 : tparavarsym;
  1602. eq,lowesteq : tequaltype;
  1603. hpd : tprocdef;
  1604. convtype : tconverttype;
  1605. cdoptions : tcompare_defs_options;
  1606. i1,i2 : byte;
  1607. begin
  1608. compare_paras:=te_incompatible;
  1609. cdoptions:=[cdo_parameter,cdo_check_operator,cdo_allow_variant];
  1610. { we need to parse the list from left-right so the
  1611. not-default parameters are checked first }
  1612. lowesteq:=high(tequaltype);
  1613. i1:=0;
  1614. i2:=0;
  1615. if cpo_ignorehidden in cpoptions then
  1616. begin
  1617. while (i1<para1.count) and
  1618. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1619. inc(i1);
  1620. while (i2<para2.count) and
  1621. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1622. inc(i2);
  1623. end;
  1624. if cpo_ignoreframepointer in cpoptions then
  1625. begin
  1626. if (i1<para1.count) and
  1627. (vo_is_parentfp in tparavarsym(para1[i1]).varoptions) then
  1628. inc(i1);
  1629. if (i2<para2.count) and
  1630. (vo_is_parentfp in tparavarsym(para2[i2]).varoptions) then
  1631. inc(i2);
  1632. end;
  1633. while (i1<para1.count) and (i2<para2.count) do
  1634. begin
  1635. eq:=te_incompatible;
  1636. currpara1:=tparavarsym(para1[i1]);
  1637. currpara2:=tparavarsym(para2[i2]);
  1638. { Unique types must match exact }
  1639. if ((df_unique in currpara1.vardef.defoptions) or (df_unique in currpara2.vardef.defoptions)) and
  1640. (currpara1.vardef<>currpara2.vardef) then
  1641. exit;
  1642. { Handle hidden parameters separately, because self is
  1643. defined as voidpointer for methodpointers }
  1644. if (vo_is_hidden_para in currpara1.varoptions) or
  1645. (vo_is_hidden_para in currpara2.varoptions) then
  1646. begin
  1647. { both must be hidden }
  1648. if (vo_is_hidden_para in currpara1.varoptions)<>(vo_is_hidden_para in currpara2.varoptions) then
  1649. exit;
  1650. eq:=te_exact;
  1651. if not(vo_is_self in currpara1.varoptions) and
  1652. not(vo_is_self in currpara2.varoptions) then
  1653. begin
  1654. if not(cpo_ignorevarspez in cpoptions) and
  1655. (currpara1.varspez<>currpara2.varspez) then
  1656. exit;
  1657. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1658. convtype,hpd,cdoptions);
  1659. end;
  1660. end
  1661. else
  1662. begin
  1663. case acp of
  1664. cp_value_equal_const :
  1665. begin
  1666. { this one is used for matching parameters from a call
  1667. statement to a procdef -> univ state can't be equal
  1668. in any case since the call statement does not contain
  1669. any information about that }
  1670. if (
  1671. not(cpo_ignorevarspez in cpoptions) and
  1672. (currpara1.varspez<>currpara2.varspez) and
  1673. ((currpara1.varspez in [vs_var,vs_out,vs_constref]) or
  1674. (currpara2.varspez in [vs_var,vs_out,vs_constref]))
  1675. ) then
  1676. exit;
  1677. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1678. convtype,hpd,cdoptions);
  1679. end;
  1680. cp_all :
  1681. begin
  1682. { used to resolve forward definitions -> headers must
  1683. match exactly, including the "univ" specifier }
  1684. if (not(cpo_ignorevarspez in cpoptions) and
  1685. (currpara1.varspez<>currpara2.varspez)) or
  1686. (currpara1.univpara<>currpara2.univpara) then
  1687. exit;
  1688. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1689. convtype,hpd,cdoptions);
  1690. end;
  1691. cp_procvar :
  1692. begin
  1693. if not(cpo_ignorevarspez in cpoptions) and
  1694. (currpara1.varspez<>currpara2.varspez) then
  1695. exit;
  1696. { "univ" state doesn't matter here: from univ to non-univ
  1697. matches if the types are compatible (i.e., as usual),
  1698. from from non-univ to univ also matches if the types
  1699. have the same size (checked below) }
  1700. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1701. convtype,hpd,cdoptions);
  1702. { Parameters must be at least equal otherwise the are incompatible }
  1703. if (eq<te_equal) then
  1704. eq:=te_incompatible;
  1705. end;
  1706. else
  1707. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1708. convtype,hpd,cdoptions);
  1709. end;
  1710. end;
  1711. { check type }
  1712. if eq=te_incompatible then
  1713. begin
  1714. { special case: "univ" parameters match if their size is equal }
  1715. if not(cpo_ignoreuniv in cpoptions) and
  1716. currpara2.univpara and
  1717. is_valid_univ_para_type(currpara1.vardef) and
  1718. (currpara1.vardef.size=currpara2.vardef.size) then
  1719. begin
  1720. { only pick as last choice }
  1721. eq:=te_convert_l5;
  1722. if (acp=cp_procvar) and
  1723. (cpo_warn_incompatible_univ in cpoptions) then
  1724. begin
  1725. { if the types may be passed in different ways by the
  1726. calling convention then this can lead to crashes
  1727. (note: not an exhaustive check, and failing this
  1728. this check does not mean things will crash on all
  1729. platforms) }
  1730. if potentially_incompatible_univ_paras(currpara1.vardef,currpara2.vardef) then
  1731. Message2(type_w_procvar_univ_conflicting_para,currpara1.vardef.typename,currpara2.vardef.typename)
  1732. end;
  1733. end
  1734. else
  1735. exit;
  1736. end;
  1737. { open strings can never match exactly, since you cannot define }
  1738. { a separate "open string" type -> we have to be able to }
  1739. { consider those as exact when resolving forward definitions. }
  1740. { The same goes for array of const. Open arrays are handled }
  1741. { already (if their element types match exactly, they are }
  1742. { considered to be an exact match) }
  1743. { And also for "inline defined" function parameter definitions }
  1744. { (i.e., function types directly declared in a parameter list) }
  1745. if (is_array_of_const(currpara1.vardef) or
  1746. is_open_string(currpara1.vardef) or
  1747. ((currpara1.vardef.typ = procvardef) and
  1748. not(assigned(currpara1.vardef.typesym)))) and
  1749. (eq=te_equal) and
  1750. (cpo_openequalisexact in cpoptions) then
  1751. eq:=te_exact;
  1752. if eq<lowesteq then
  1753. lowesteq:=eq;
  1754. { also check default value if both have it declared }
  1755. if (cpo_comparedefaultvalue in cpoptions) and
  1756. assigned(currpara1.defaultconstsym) and
  1757. assigned(currpara2.defaultconstsym) then
  1758. begin
  1759. if not equal_constsym(tconstsym(currpara1.defaultconstsym),tconstsym(currpara2.defaultconstsym)) then
  1760. exit;
  1761. end;
  1762. if not(cpo_compilerproc in cpoptions) and
  1763. not(cpo_rtlproc in cpoptions) and
  1764. is_ansistring(currpara1.vardef) and
  1765. is_ansistring(currpara2.vardef) and
  1766. (tstringdef(currpara1.vardef).encoding<>tstringdef(currpara2.vardef).encoding) and
  1767. ((tstringdef(currpara1.vardef).encoding=globals.CP_NONE) or
  1768. (tstringdef(currpara2.vardef).encoding=globals.CP_NONE)
  1769. ) then
  1770. eq:=te_convert_l1;
  1771. if eq<lowesteq then
  1772. lowesteq:=eq;
  1773. inc(i1);
  1774. inc(i2);
  1775. if cpo_ignorehidden in cpoptions then
  1776. begin
  1777. while (i1<para1.count) and
  1778. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1779. inc(i1);
  1780. while (i2<para2.count) and
  1781. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1782. inc(i2);
  1783. end;
  1784. if cpo_ignoreframepointer in cpoptions then
  1785. begin
  1786. if (i1<para1.count) and
  1787. (vo_is_parentfp in tparavarsym(para1[i1]).varoptions) then
  1788. inc(i1);
  1789. if (i2<para2.count) and
  1790. (vo_is_parentfp in tparavarsym(para2[i2]).varoptions) then
  1791. inc(i2);
  1792. end;
  1793. end;
  1794. { when both lists are empty then the parameters are equal. Also
  1795. when one list is empty and the other has a parameter with default
  1796. value assigned then the parameters are also equal }
  1797. if ((i1>=para1.count) and (i2>=para2.count)) or
  1798. ((cpo_allowdefaults in cpoptions) and
  1799. (((i1<para1.count) and assigned(tparavarsym(para1[i1]).defaultconstsym)) or
  1800. ((i2<para2.count) and assigned(tparavarsym(para2[i2]).defaultconstsym)))) then
  1801. compare_paras:=lowesteq;
  1802. end;
  1803. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef;checkincompatibleuniv: boolean):tequaltype;
  1804. var
  1805. eq : tequaltype;
  1806. po_comp : tprocoptions;
  1807. pa_comp: tcompare_paras_options;
  1808. begin
  1809. proc_to_procvar_equal:=te_incompatible;
  1810. if not(assigned(def1)) or not(assigned(def2)) then
  1811. exit;
  1812. { check for method pointer and local procedure pointer:
  1813. a) if one is a procedure of object, the other also has to be one
  1814. b) if one is a pure address, the other also has to be one
  1815. except if def1 is a global proc and def2 is a nested procdef
  1816. (global procedures can be converted into nested procvars)
  1817. c) if def1 is a nested procedure, then def2 has to be a nested
  1818. procvar and def1 has to have the po_delphi_nested_cc option
  1819. d) if def1 is a procvar, def1 and def2 both have to be nested or
  1820. non-nested (we don't allow assignments from non-nested to
  1821. nested procvars to make sure that we can still implement
  1822. nested procvars using trampolines -- e.g., this would be
  1823. necessary for LLVM or CIL as long as they do not have support
  1824. for Delphi-style frame pointer parameter passing) }
  1825. if (def1.is_methodpointer<>def2.is_methodpointer) or { a) }
  1826. ((def1.is_addressonly<>def2.is_addressonly) and { b) }
  1827. (is_nested_pd(def1) or
  1828. not is_nested_pd(def2))) or
  1829. ((def1.typ=procdef) and { c) }
  1830. is_nested_pd(def1) and
  1831. (not(po_delphi_nested_cc in def1.procoptions) or
  1832. not is_nested_pd(def2))) or
  1833. ((def1.typ=procvardef) and { d) }
  1834. (is_nested_pd(def1)<>is_nested_pd(def2))) then
  1835. exit;
  1836. pa_comp:=[cpo_ignoreframepointer];
  1837. if checkincompatibleuniv then
  1838. include(pa_comp,cpo_warn_incompatible_univ);
  1839. { check return value and options, methodpointer is already checked }
  1840. po_comp:=[po_staticmethod,po_interrupt,
  1841. po_iocheck,po_varargs];
  1842. if (m_delphi in current_settings.modeswitches) then
  1843. exclude(po_comp,po_varargs);
  1844. if (def1.proccalloption=def2.proccalloption) and
  1845. ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1846. equal_defs(def1.returndef,def2.returndef) then
  1847. begin
  1848. { return equal type based on the parameters, but a proc->procvar
  1849. is never exact, so map an exact match of the parameters to
  1850. te_equal }
  1851. eq:=compare_paras(def1.paras,def2.paras,cp_procvar,pa_comp);
  1852. if eq=te_exact then
  1853. eq:=te_equal;
  1854. if (eq=te_equal) then
  1855. begin
  1856. { prefer non-nested to non-nested over non-nested to nested }
  1857. if (is_nested_pd(def1)<>is_nested_pd(def2)) then
  1858. eq:=te_convert_l1;
  1859. end;
  1860. proc_to_procvar_equal:=eq;
  1861. end;
  1862. end;
  1863. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  1864. begin
  1865. compatible_childmethod_resultdef :=
  1866. (equal_defs(parentretdef,childretdef)) or
  1867. ((parentretdef.typ=objectdef) and
  1868. (childretdef.typ=objectdef) and
  1869. is_class_or_interface_or_objc(parentretdef) and
  1870. is_class_or_interface_or_objc(childretdef) and
  1871. (tobjectdef(childretdef).is_related(tobjectdef(parentretdef))))
  1872. end;
  1873. end.