2
0

defcmp.pas 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689
  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,cpo_openequalisexact);
  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,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. pasbool,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 if (not is_in_limit(def_from,def_to)) then
  222. { "punish" bad type conversions :) (JM) }
  223. eq:=te_convert_l3
  224. else
  225. eq:=te_convert_l1;
  226. end;
  227. end;
  228. enumdef :
  229. begin
  230. { needed for char(enum) }
  231. if cdo_explicit in cdoptions then
  232. begin
  233. doconv:=tc_int_2_int;
  234. eq:=te_convert_l1;
  235. end;
  236. end;
  237. floatdef :
  238. begin
  239. if is_currency(def_to) then
  240. begin
  241. doconv:=tc_real_2_currency;
  242. eq:=te_convert_l2;
  243. end;
  244. end;
  245. objectdef:
  246. begin
  247. if (m_delphi in current_settings.modeswitches) and
  248. is_class_or_interface_or_dispinterface(def_from) and
  249. (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 in [st_widestring,st_unicodestring] then
  304. eq:=te_convert_l3
  305. else if tstringdef(def_to).stringtype in [st_widestring,st_unicodestring] 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_unicodestring :
  330. begin
  331. { Prefer conversions to ansistring }
  332. if tstringdef(def_to).stringtype=st_ansistring then
  333. eq:=te_convert_l2
  334. else
  335. eq:=te_convert_l3;
  336. end;
  337. st_shortstring :
  338. begin
  339. { Prefer shortstrings of different length or conversions
  340. from shortstring to ansistring }
  341. if (tstringdef(def_to).stringtype=st_shortstring) then
  342. eq:=te_convert_l1
  343. else if tstringdef(def_to).stringtype=st_ansistring then
  344. eq:=te_convert_l2
  345. else
  346. eq:=te_convert_l3;
  347. end;
  348. st_ansistring :
  349. begin
  350. { Prefer conversion to widestrings }
  351. if (tstringdef(def_to).stringtype in [st_widestring,st_unicodestring]) then
  352. eq:=te_convert_l2
  353. else
  354. eq:=te_convert_l3;
  355. end;
  356. end;
  357. end;
  358. end;
  359. orddef :
  360. begin
  361. { char to string}
  362. if is_char(def_from) or
  363. is_widechar(def_from) then
  364. begin
  365. doconv:=tc_char_2_string;
  366. eq:=te_convert_l1;
  367. end;
  368. end;
  369. arraydef :
  370. begin
  371. { array of char to string, the length check is done by the firstpass of this node }
  372. if is_chararray(def_from) or is_open_chararray(def_from) then
  373. begin
  374. { "Untyped" stringconstn is an array of char }
  375. if fromtreetype=stringconstn then
  376. begin
  377. doconv:=tc_string_2_string;
  378. { prefered string type depends on the $H switch }
  379. if not(cs_ansistrings in current_settings.localswitches) and
  380. (tstringdef(def_to).stringtype=st_shortstring) then
  381. eq:=te_equal
  382. else if (cs_ansistrings in current_settings.localswitches) and
  383. (tstringdef(def_to).stringtype=st_ansistring) then
  384. eq:=te_equal
  385. else if tstringdef(def_to).stringtype in [st_widestring,st_unicodestring] then
  386. eq:=te_convert_l3
  387. else
  388. eq:=te_convert_l1;
  389. end
  390. else
  391. begin
  392. doconv:=tc_chararray_2_string;
  393. if is_open_array(def_from) then
  394. begin
  395. if is_ansistring(def_to) then
  396. eq:=te_convert_l1
  397. else if is_widestring(def_to) or is_unicodestring(def_to) then
  398. eq:=te_convert_l3
  399. else
  400. eq:=te_convert_l2;
  401. end
  402. else
  403. begin
  404. if is_shortstring(def_to) then
  405. begin
  406. { Only compatible with arrays that fit
  407. smaller than 255 chars }
  408. if (def_from.size <= 255) then
  409. eq:=te_convert_l1;
  410. end
  411. else if is_ansistring(def_to) then
  412. begin
  413. if (def_from.size > 255) then
  414. eq:=te_convert_l1
  415. else
  416. eq:=te_convert_l2;
  417. end
  418. else if is_widestring(def_to) or is_unicodestring(def_to) then
  419. eq:=te_convert_l3
  420. else
  421. eq:=te_convert_l2;
  422. end;
  423. end;
  424. end
  425. else
  426. { array of widechar to string, the length check is done by the firstpass of this node }
  427. if is_widechararray(def_from) or is_open_widechararray(def_from) then
  428. begin
  429. doconv:=tc_chararray_2_string;
  430. if is_widestring(def_to) or is_unicodestring(def_to) then
  431. eq:=te_convert_l1
  432. else
  433. { size of widechar array is double due the sizeof a widechar }
  434. if not(is_shortstring(def_to) and (is_open_widechararray(def_from) or (def_from.size>255*sizeof(widechar)))) then
  435. eq:=te_convert_l3
  436. else
  437. eq:=te_convert_l2;
  438. end;
  439. end;
  440. pointerdef :
  441. begin
  442. { pchar can be assigned to short/ansistrings,
  443. but not in tp7 compatible mode }
  444. if not(m_tp7 in current_settings.modeswitches) then
  445. begin
  446. if is_pchar(def_from) then
  447. begin
  448. doconv:=tc_pchar_2_string;
  449. { prefer ansistrings because pchars can overflow shortstrings, }
  450. { but only if ansistrings are the default (JM) }
  451. if (is_shortstring(def_to) and
  452. not(cs_ansistrings in current_settings.localswitches)) or
  453. (is_ansistring(def_to) and
  454. (cs_ansistrings in current_settings.localswitches)) then
  455. eq:=te_convert_l1
  456. else
  457. eq:=te_convert_l2;
  458. end
  459. else if is_pwidechar(def_from) then
  460. begin
  461. doconv:=tc_pwchar_2_string;
  462. if is_widestring(def_to) or is_unicodestring(def_to) then
  463. eq:=te_convert_l1
  464. else
  465. eq:=te_convert_l3;
  466. end;
  467. end;
  468. end;
  469. objectdef :
  470. begin
  471. { corba interface -> id string }
  472. if is_interfacecorba(def_from) then
  473. begin
  474. doconv:=tc_intf_2_string;
  475. eq:=te_convert_l1;
  476. end;
  477. end;
  478. end;
  479. end;
  480. floatdef :
  481. begin
  482. case def_from.typ of
  483. orddef :
  484. begin { ordinal to real }
  485. { only for implicit and internal typecasts in tp/delphi }
  486. if (([cdo_explicit,cdo_internal] * cdoptions <> [cdo_explicit]) or
  487. ([m_tp7,m_delphi] * current_settings.modeswitches = [])) and
  488. (is_integer(def_from) or
  489. (is_currency(def_from) and
  490. (s64currencytype.typ = floatdef))) then
  491. begin
  492. doconv:=tc_int_2_real;
  493. eq:=te_convert_l4;
  494. end
  495. else if is_currency(def_from)
  496. { and (s64currencytype.typ = orddef)) } then
  497. begin
  498. { prefer conversion to orddef in this case, unless }
  499. { the orddef < currency (then it will get convert l3, }
  500. { and conversion to float is favoured) }
  501. doconv:=tc_int_2_real;
  502. eq:=te_convert_l2;
  503. end;
  504. end;
  505. floatdef :
  506. begin
  507. if tfloatdef(def_from).floattype=tfloatdef(def_to).floattype then
  508. eq:=te_equal
  509. else
  510. begin
  511. { Delphi does not allow explicit type conversions for float types like:
  512. single_var:=single(double_var);
  513. But if such conversion is inserted by compiler (internal) for some purpose,
  514. it should be allowed even in Delphi mode. }
  515. if (fromtreetype=realconstn) or
  516. not((cdoptions*[cdo_explicit,cdo_internal]=[cdo_explicit]) and
  517. (m_delphi in current_settings.modeswitches)) then
  518. begin
  519. doconv:=tc_real_2_real;
  520. { do we lose precision? }
  521. if def_to.size<def_from.size then
  522. eq:=te_convert_l2
  523. else
  524. eq:=te_convert_l1;
  525. end;
  526. end;
  527. end;
  528. end;
  529. end;
  530. enumdef :
  531. begin
  532. case def_from.typ of
  533. enumdef :
  534. begin
  535. if cdo_explicit in cdoptions then
  536. begin
  537. eq:=te_convert_l1;
  538. doconv:=tc_int_2_int;
  539. end
  540. else
  541. begin
  542. hd1:=def_from;
  543. while assigned(tenumdef(hd1).basedef) do
  544. hd1:=tenumdef(hd1).basedef;
  545. hd2:=def_to;
  546. while assigned(tenumdef(hd2).basedef) do
  547. hd2:=tenumdef(hd2).basedef;
  548. if (hd1=hd2) then
  549. begin
  550. eq:=te_convert_l1;
  551. { because of packenum they can have different sizes! (JM) }
  552. doconv:=tc_int_2_int;
  553. end
  554. else
  555. begin
  556. { assignment of an enum symbol to an unique type? }
  557. if (fromtreetype=ordconstn) and
  558. (tenumsym(tenumdef(hd1).firstenum)=tenumsym(tenumdef(hd2).firstenum)) then
  559. begin
  560. { because of packenum they can have different sizes! (JM) }
  561. eq:=te_convert_l1;
  562. doconv:=tc_int_2_int;
  563. end;
  564. end;
  565. end;
  566. end;
  567. orddef :
  568. begin
  569. if cdo_explicit in cdoptions then
  570. begin
  571. eq:=te_convert_l1;
  572. doconv:=tc_int_2_int;
  573. end;
  574. end;
  575. variantdef :
  576. begin
  577. eq:=te_convert_l1;
  578. doconv:=tc_variant_2_enum;
  579. end;
  580. pointerdef :
  581. begin
  582. { ugly, but delphi allows it }
  583. if (cdo_explicit in cdoptions) and
  584. (m_delphi in current_settings.modeswitches) then
  585. begin
  586. doconv:=tc_int_2_int;
  587. eq:=te_convert_l1;
  588. end;
  589. end;
  590. objectdef:
  591. begin
  592. { ugly, but delphi allows it }
  593. if (m_delphi in current_settings.modeswitches) and
  594. is_class_or_interface_or_dispinterface(def_from) and
  595. (cdo_explicit in cdoptions) then
  596. begin
  597. doconv:=tc_int_2_int;
  598. eq:=te_convert_l1;
  599. end;
  600. end;
  601. end;
  602. end;
  603. arraydef :
  604. begin
  605. { open array is also compatible with a single element of its base type.
  606. the extra check for deftyp is needed because equal defs can also return
  607. true if the def types are not the same, for example with dynarray to pointer. }
  608. if is_open_array(def_to) and
  609. (def_from.typ=tarraydef(def_to).elementdef.typ) and
  610. equal_defs(def_from,tarraydef(def_to).elementdef) then
  611. begin
  612. doconv:=tc_equal;
  613. eq:=te_convert_l1;
  614. end
  615. else
  616. begin
  617. case def_from.typ of
  618. arraydef :
  619. begin
  620. { from/to packed array -- packed chararrays are }
  621. { strings in ISO Pascal (at least if the lower bound }
  622. { is 1, but GPC makes all equal-length chararrays }
  623. { compatible), so treat those the same as regular }
  624. { char arrays }
  625. if (is_packed_array(def_from) and
  626. not is_chararray(def_from) and
  627. not is_widechararray(def_from)) xor
  628. (is_packed_array(def_to) and
  629. not is_chararray(def_to) and
  630. not is_widechararray(def_to)) then
  631. { both must be packed }
  632. begin
  633. compare_defs_ext:=te_incompatible;
  634. exit;
  635. end
  636. { to dynamic array }
  637. else if is_dynamic_array(def_to) then
  638. begin
  639. if equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  640. begin
  641. { dynamic array -> dynamic array }
  642. if is_dynamic_array(def_from) then
  643. eq:=te_equal
  644. { fpc modes only: array -> dyn. array }
  645. else if (current_settings.modeswitches*[m_objfpc,m_fpc]<>[]) and
  646. not(is_special_array(def_from)) and
  647. is_zero_based_array(def_from) then
  648. begin
  649. eq:=te_convert_l2;
  650. doconv:=tc_array_2_dynarray;
  651. end;
  652. end
  653. end
  654. else
  655. { to open array }
  656. if is_open_array(def_to) then
  657. begin
  658. { array constructor -> open array }
  659. if is_array_constructor(def_from) then
  660. begin
  661. if is_void(tarraydef(def_from).elementdef) then
  662. begin
  663. doconv:=tc_equal;
  664. eq:=te_convert_l1;
  665. end
  666. else
  667. begin
  668. subeq:=compare_defs_ext(tarraydef(def_from).elementdef,
  669. tarraydef(def_to).elementdef,
  670. { reason for cdo_allow_variant: see webtbs/tw7070a and webtbs/tw7070b }
  671. arrayconstructorn,hct,hpd,[cdo_check_operator,cdo_allow_variant]);
  672. if (subeq>=te_equal) then
  673. begin
  674. doconv:=tc_equal;
  675. eq:=te_convert_l1;
  676. end
  677. else
  678. if (subeq>te_incompatible) then
  679. begin
  680. doconv:=hct;
  681. eq:=te_convert_l2;
  682. end;
  683. end;
  684. end
  685. else
  686. { dynamic array -> open array }
  687. if is_dynamic_array(def_from) and
  688. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  689. begin
  690. doconv:=tc_dynarray_2_openarray;
  691. eq:=te_convert_l2;
  692. end
  693. else
  694. { open array -> open array }
  695. if is_open_array(def_from) and
  696. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  697. if tarraydef(def_from).elementdef=tarraydef(def_to).elementdef then
  698. eq:=te_exact
  699. else
  700. eq:=te_equal
  701. else
  702. { array -> open array }
  703. if not(cdo_parameter in cdoptions) and
  704. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  705. begin
  706. if fromtreetype=stringconstn then
  707. eq:=te_convert_l1
  708. else
  709. eq:=te_equal;
  710. end;
  711. end
  712. else
  713. { to array of const }
  714. if is_array_of_const(def_to) then
  715. begin
  716. if is_array_of_const(def_from) or
  717. is_array_constructor(def_from) then
  718. begin
  719. eq:=te_equal;
  720. end
  721. else
  722. { array of tvarrec -> array of const }
  723. if equal_defs(tarraydef(def_to).elementdef,tarraydef(def_from).elementdef) then
  724. begin
  725. doconv:=tc_equal;
  726. eq:=te_convert_l1;
  727. end;
  728. end
  729. else
  730. { to array of char, from "Untyped" stringconstn (array of char) }
  731. if (fromtreetype=stringconstn) and
  732. (is_chararray(def_to) or
  733. is_widechararray(def_to)) then
  734. begin
  735. eq:=te_convert_l1;
  736. doconv:=tc_string_2_chararray;
  737. end
  738. else
  739. { other arrays }
  740. begin
  741. { open array -> array }
  742. if not(cdo_parameter in cdoptions) and
  743. is_open_array(def_from) and
  744. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) then
  745. begin
  746. eq:=te_equal
  747. end
  748. else
  749. { array -> array }
  750. if not(m_tp7 in current_settings.modeswitches) and
  751. not(m_delphi in current_settings.modeswitches) and
  752. (tarraydef(def_from).lowrange=tarraydef(def_to).lowrange) and
  753. (tarraydef(def_from).highrange=tarraydef(def_to).highrange) and
  754. equal_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef) and
  755. equal_defs(tarraydef(def_from).rangedef,tarraydef(def_to).rangedef) then
  756. begin
  757. eq:=te_equal
  758. end;
  759. end;
  760. end;
  761. pointerdef :
  762. begin
  763. { nil and voidpointers are compatible with dyn. arrays }
  764. if is_dynamic_array(def_to) and
  765. ((fromtreetype=niln) or
  766. is_voidpointer(def_from)) then
  767. begin
  768. doconv:=tc_equal;
  769. eq:=te_convert_l1;
  770. end
  771. else
  772. if is_zero_based_array(def_to) and
  773. equal_defs(tpointerdef(def_from).pointeddef,tarraydef(def_to).elementdef) then
  774. begin
  775. doconv:=tc_pointer_2_array;
  776. eq:=te_convert_l1;
  777. end;
  778. end;
  779. stringdef :
  780. begin
  781. { string to char array }
  782. if (not is_special_array(def_to)) and
  783. (is_char(tarraydef(def_to).elementdef)or
  784. is_widechar(tarraydef(def_to).elementdef)) then
  785. begin
  786. doconv:=tc_string_2_chararray;
  787. eq:=te_convert_l1;
  788. end;
  789. end;
  790. orddef:
  791. begin
  792. if is_chararray(def_to) and
  793. is_char(def_from) then
  794. begin
  795. doconv:=tc_char_2_chararray;
  796. eq:=te_convert_l2;
  797. end;
  798. end;
  799. recorddef :
  800. begin
  801. { tvarrec -> array of const }
  802. if is_array_of_const(def_to) and
  803. equal_defs(def_from,tarraydef(def_to).elementdef) then
  804. begin
  805. doconv:=tc_equal;
  806. eq:=te_convert_l1;
  807. end;
  808. end;
  809. variantdef :
  810. begin
  811. if is_dynamic_array(def_to) then
  812. begin
  813. doconv:=tc_variant_2_dynarray;
  814. eq:=te_convert_l1;
  815. end;
  816. end;
  817. end;
  818. end;
  819. end;
  820. variantdef :
  821. begin
  822. if (cdo_allow_variant in cdoptions) then
  823. begin
  824. case def_from.typ of
  825. enumdef :
  826. begin
  827. doconv:=tc_enum_2_variant;
  828. eq:=te_convert_l1;
  829. end;
  830. arraydef :
  831. begin
  832. if is_dynamic_array(def_from) then
  833. begin
  834. doconv:=tc_dynarray_2_variant;
  835. eq:=te_convert_l1;
  836. end;
  837. end;
  838. objectdef :
  839. begin
  840. if is_interface(def_from) then
  841. begin
  842. doconv:=tc_interface_2_variant;
  843. eq:=te_convert_l1;
  844. end;
  845. end;
  846. variantdef :
  847. begin
  848. { doing this in the compiler avoids a lot of unncessary
  849. copying }
  850. if (tvariantdef(def_from).varianttype=vt_olevariant) and
  851. (tvariantdef(def_to).varianttype=vt_normalvariant) then
  852. begin
  853. doconv:=tc_equal;
  854. eq:=te_convert_l1;
  855. end;
  856. end;
  857. end;
  858. end;
  859. end;
  860. pointerdef :
  861. begin
  862. case def_from.typ of
  863. stringdef :
  864. begin
  865. { string constant (which can be part of array constructor)
  866. to zero terminated string constant }
  867. if (fromtreetype = stringconstn) and
  868. (is_pchar(def_to) or is_pwidechar(def_to)) then
  869. begin
  870. doconv:=tc_cstring_2_pchar;
  871. eq:=te_convert_l2;
  872. end
  873. else
  874. if (cdo_explicit in cdoptions) or (fromtreetype = arrayconstructorn) then
  875. begin
  876. { pchar(ansistring) }
  877. if is_pchar(def_to) and
  878. is_ansistring(def_from) then
  879. begin
  880. doconv:=tc_ansistring_2_pchar;
  881. eq:=te_convert_l1;
  882. end
  883. else
  884. { pwidechar(widestring) }
  885. if is_pwidechar(def_to) and
  886. is_wide_or_unicode_string(def_from) then
  887. begin
  888. doconv:=tc_ansistring_2_pchar;
  889. eq:=te_convert_l1;
  890. end;
  891. end;
  892. end;
  893. orddef :
  894. begin
  895. { char constant to zero terminated string constant }
  896. if (fromtreetype in [ordconstn,arrayconstructorn]) then
  897. begin
  898. if (is_char(def_from) or is_widechar(def_from)) and
  899. (is_pchar(def_to) or is_pwidechar(def_to)) then
  900. begin
  901. doconv:=tc_cchar_2_pchar;
  902. eq:=te_convert_l1;
  903. end
  904. else
  905. if (m_delphi in current_settings.modeswitches) and is_integer(def_from) then
  906. begin
  907. doconv:=tc_cord_2_pointer;
  908. eq:=te_convert_l5;
  909. end;
  910. end;
  911. { allow explicit typecasts from ordinals to pointer.
  912. Support for delphi compatibility
  913. Support constructs like pointer(cardinal-cardinal) or pointer(longint+cardinal) where
  914. the result of the ordinal operation is int64 also on 32 bit platforms.
  915. It is also used by the compiler internally for inc(pointer,ordinal) }
  916. if (eq=te_incompatible) and
  917. not is_void(def_from) and
  918. (
  919. (
  920. (cdo_explicit in cdoptions) and
  921. (
  922. (m_delphi in current_settings.modeswitches) or
  923. { Don't allow pchar(char) in fpc modes }
  924. is_integer(def_from)
  925. )
  926. ) or
  927. (cdo_internal in cdoptions)
  928. ) then
  929. begin
  930. doconv:=tc_int_2_int;
  931. eq:=te_convert_l1;
  932. end;
  933. end;
  934. enumdef :
  935. begin
  936. { allow explicit typecasts from enums to pointer.
  937. Support for delphi compatibility
  938. }
  939. if (((cdo_explicit in cdoptions) and
  940. (m_delphi in current_settings.modeswitches)
  941. ) or
  942. (cdo_internal in cdoptions)
  943. ) then
  944. begin
  945. doconv:=tc_int_2_int;
  946. eq:=te_convert_l1;
  947. end;
  948. end;
  949. arraydef :
  950. begin
  951. { string constant (which can be part of array constructor)
  952. to zero terminated string constant }
  953. if (((fromtreetype = arrayconstructorn) and
  954. { can't use is_chararray, because returns false for }
  955. { array constructors }
  956. is_char(tarraydef(def_from).elementdef)) or
  957. (fromtreetype = stringconstn)) and
  958. (is_pchar(def_to) or is_pwidechar(def_to)) then
  959. begin
  960. doconv:=tc_cstring_2_pchar;
  961. eq:=te_convert_l2;
  962. end
  963. else
  964. { chararray to pointer }
  965. if (is_zero_based_array(def_from) or
  966. is_open_array(def_from)) and
  967. equal_defs(tarraydef(def_from).elementdef,tpointerdef(def_to).pointeddef) then
  968. begin
  969. doconv:=tc_array_2_pointer;
  970. { don't prefer the pchar overload when a constant
  971. string was passed }
  972. if fromtreetype=stringconstn then
  973. eq:=te_convert_l2
  974. else
  975. eq:=te_convert_l1;
  976. end
  977. else
  978. { dynamic array to pointer, delphi only }
  979. if (m_delphi in current_settings.modeswitches) and
  980. is_dynamic_array(def_from) and
  981. is_voidpointer(def_to) then
  982. begin
  983. eq:=te_equal;
  984. end;
  985. end;
  986. pointerdef :
  987. begin
  988. { check for far pointers }
  989. if (tpointerdef(def_from).is_far<>tpointerdef(def_to).is_far) then
  990. begin
  991. eq:=te_incompatible;
  992. end
  993. else
  994. { the types can be forward type, handle before normal type check !! }
  995. if assigned(def_to.typesym) and
  996. (tpointerdef(def_to).pointeddef.typ=forwarddef) then
  997. begin
  998. if (def_from.typesym=def_to.typesym) then
  999. eq:=te_equal
  1000. end
  1001. else
  1002. { same types }
  1003. if equal_defs(tpointerdef(def_from).pointeddef,tpointerdef(def_to).pointeddef) then
  1004. begin
  1005. eq:=te_equal
  1006. end
  1007. else
  1008. { child class pointer can be assigned to anchestor pointers }
  1009. if (
  1010. (tpointerdef(def_from).pointeddef.typ=objectdef) and
  1011. (tpointerdef(def_to).pointeddef.typ=objectdef) and
  1012. tobjectdef(tpointerdef(def_from).pointeddef).is_related(
  1013. tobjectdef(tpointerdef(def_to).pointeddef))
  1014. ) then
  1015. begin
  1016. doconv:=tc_equal;
  1017. eq:=te_convert_l1;
  1018. end
  1019. else
  1020. { all pointers can be assigned to void-pointer }
  1021. if is_void(tpointerdef(def_to).pointeddef) then
  1022. begin
  1023. doconv:=tc_equal;
  1024. { give pwidechar,pchar a penalty so it prefers
  1025. conversion to ansistring }
  1026. if is_pchar(def_from) or
  1027. is_pwidechar(def_from) then
  1028. eq:=te_convert_l2
  1029. else
  1030. eq:=te_convert_l1;
  1031. end
  1032. else
  1033. { all pointers can be assigned from void-pointer }
  1034. if is_void(tpointerdef(def_from).pointeddef) or
  1035. { all pointers can be assigned from void-pointer or formaldef pointer, check
  1036. tw3777.pp if you change this }
  1037. (tpointerdef(def_from).pointeddef.typ=formaldef) then
  1038. begin
  1039. doconv:=tc_equal;
  1040. { give pwidechar a penalty so it prefers
  1041. conversion to pchar }
  1042. if is_pwidechar(def_to) then
  1043. eq:=te_convert_l2
  1044. else
  1045. eq:=te_convert_l1;
  1046. end;
  1047. end;
  1048. procvardef :
  1049. begin
  1050. { procedure variable can be assigned to an void pointer,
  1051. this not allowed for methodpointers }
  1052. if (is_void(tpointerdef(def_to).pointeddef) or
  1053. (m_mac_procvar in current_settings.modeswitches)) and
  1054. tprocvardef(def_from).is_addressonly then
  1055. begin
  1056. doconv:=tc_equal;
  1057. eq:=te_convert_l1;
  1058. end;
  1059. end;
  1060. procdef :
  1061. begin
  1062. { procedure variable can be assigned to an void pointer,
  1063. this not allowed for methodpointers }
  1064. if (m_mac_procvar in current_settings.modeswitches) and
  1065. tprocdef(def_from).is_addressonly then
  1066. begin
  1067. doconv:=tc_proc_2_procvar;
  1068. eq:=te_convert_l2;
  1069. end;
  1070. end;
  1071. classrefdef,
  1072. objectdef :
  1073. begin
  1074. { class types and class reference type
  1075. can be assigned to void pointers, but it is less
  1076. preferred than assigning to a related objectdef }
  1077. if (
  1078. is_class_or_interface_or_dispinterface(def_from) or
  1079. (def_from.typ=classrefdef)
  1080. ) and
  1081. (tpointerdef(def_to).pointeddef.typ=orddef) and
  1082. (torddef(tpointerdef(def_to).pointeddef).ordtype=uvoid) then
  1083. begin
  1084. doconv:=tc_equal;
  1085. eq:=te_convert_l2;
  1086. end;
  1087. end;
  1088. end;
  1089. end;
  1090. setdef :
  1091. begin
  1092. case def_from.typ of
  1093. setdef :
  1094. begin
  1095. if assigned(tsetdef(def_from).elementdef) and
  1096. assigned(tsetdef(def_to).elementdef) then
  1097. begin
  1098. { sets with the same element base type and the same range are equal }
  1099. if equal_defs(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) and
  1100. (tsetdef(def_from).setbase=tsetdef(def_to).setbase) and
  1101. (tsetdef(def_from).setmax=tsetdef(def_to).setmax) then
  1102. eq:=te_equal
  1103. else if is_subequal(tsetdef(def_from).elementdef,tsetdef(def_to).elementdef) then
  1104. begin
  1105. eq:=te_convert_l1;
  1106. doconv:=tc_set_to_set;
  1107. end;
  1108. end
  1109. else
  1110. begin
  1111. { empty set is compatible with everything }
  1112. eq:=te_convert_l1;
  1113. doconv:=tc_set_to_set;
  1114. end;
  1115. end;
  1116. arraydef :
  1117. begin
  1118. { automatic arrayconstructor -> set conversion }
  1119. if is_array_constructor(def_from) then
  1120. begin
  1121. doconv:=tc_arrayconstructor_2_set;
  1122. eq:=te_convert_l1;
  1123. end;
  1124. end;
  1125. end;
  1126. end;
  1127. procvardef :
  1128. begin
  1129. case def_from.typ of
  1130. procdef :
  1131. begin
  1132. { proc -> procvar }
  1133. if (m_tp_procvar in current_settings.modeswitches) or
  1134. (m_mac_procvar in current_settings.modeswitches) then
  1135. begin
  1136. subeq:=proc_to_procvar_equal(tprocdef(def_from),tprocvardef(def_to));
  1137. if subeq>te_incompatible then
  1138. begin
  1139. doconv:=tc_proc_2_procvar;
  1140. eq:=te_convert_l1;
  1141. end;
  1142. end;
  1143. end;
  1144. procvardef :
  1145. begin
  1146. { procvar -> procvar }
  1147. eq:=proc_to_procvar_equal(tprocvardef(def_from),tprocvardef(def_to));
  1148. end;
  1149. pointerdef :
  1150. begin
  1151. { nil is compatible with procvars }
  1152. if (fromtreetype=niln) then
  1153. begin
  1154. if not Tprocvardef(def_to).is_addressonly then
  1155. {Nil to method pointers requires to convert a single
  1156. pointer nil value to a two pointer procvardef.}
  1157. doconv:=tc_nil_2_methodprocvar
  1158. else
  1159. doconv:=tc_equal;
  1160. eq:=te_convert_l1;
  1161. end
  1162. else
  1163. { for example delphi allows the assignement from pointers }
  1164. { to procedure variables }
  1165. if (m_pointer_2_procedure in current_settings.modeswitches) and
  1166. is_void(tpointerdef(def_from).pointeddef) and
  1167. tprocvardef(def_to).is_addressonly then
  1168. begin
  1169. doconv:=tc_equal;
  1170. eq:=te_convert_l1;
  1171. end;
  1172. end;
  1173. end;
  1174. end;
  1175. objectdef :
  1176. begin
  1177. { object pascal objects }
  1178. if (def_from.typ=objectdef) and
  1179. (tobjectdef(def_from).is_related(tobjectdef(def_to))) then
  1180. begin
  1181. doconv:=tc_equal;
  1182. eq:=te_convert_l1;
  1183. end
  1184. else
  1185. { Class/interface specific }
  1186. if is_class_or_interface_or_dispinterface(def_to) then
  1187. begin
  1188. { void pointer also for delphi mode }
  1189. if (m_delphi in current_settings.modeswitches) and
  1190. is_voidpointer(def_from) then
  1191. begin
  1192. doconv:=tc_equal;
  1193. { prefer pointer-pointer assignments }
  1194. eq:=te_convert_l2;
  1195. end
  1196. else
  1197. { nil is compatible with class instances and interfaces }
  1198. if (fromtreetype=niln) then
  1199. begin
  1200. doconv:=tc_equal;
  1201. eq:=te_convert_l1;
  1202. end
  1203. { classes can be assigned to interfaces }
  1204. else if is_interface(def_to) and
  1205. is_class(def_from) and
  1206. assigned(tobjectdef(def_from).ImplementedInterfaces) then
  1207. begin
  1208. { we've to search in parent classes as well }
  1209. hobjdef:=tobjectdef(def_from);
  1210. while assigned(hobjdef) do
  1211. begin
  1212. if hobjdef.find_implemented_interface(tobjectdef(def_to))<>nil then
  1213. begin
  1214. doconv:=tc_class_2_intf;
  1215. { don't prefer this over objectdef->objectdef }
  1216. eq:=te_convert_l2;
  1217. break;
  1218. end;
  1219. hobjdef:=hobjdef.childof;
  1220. end;
  1221. end
  1222. { Interface 2 GUID handling }
  1223. else if (def_to=tdef(rec_tguid)) and
  1224. (fromtreetype=typen) and
  1225. is_interface(def_from) and
  1226. assigned(tobjectdef(def_from).iidguid) then
  1227. begin
  1228. eq:=te_convert_l1;
  1229. doconv:=tc_equal;
  1230. end
  1231. else if (def_from.typ=variantdef) and is_interface(def_to) then
  1232. begin
  1233. doconv:=tc_variant_2_interface;
  1234. eq:=te_convert_l2;
  1235. end
  1236. { ugly, but delphi allows it }
  1237. else if (def_from.typ in [orddef,enumdef]) and
  1238. (m_delphi in current_settings.modeswitches) and
  1239. (cdo_explicit in cdoptions) then
  1240. begin
  1241. doconv:=tc_int_2_int;
  1242. eq:=te_convert_l1;
  1243. end;
  1244. end;
  1245. end;
  1246. classrefdef :
  1247. begin
  1248. { similar to pointerdef wrt forwards }
  1249. if assigned(def_to.typesym) and
  1250. (tclassrefdef(def_to).pointeddef.typ=forwarddef) then
  1251. begin
  1252. if (def_from.typesym=def_to.typesym) then
  1253. eq:=te_equal;
  1254. end
  1255. else
  1256. { class reference types }
  1257. if (def_from.typ=classrefdef) then
  1258. begin
  1259. if equal_defs(tclassrefdef(def_from).pointeddef,tclassrefdef(def_to).pointeddef) then
  1260. begin
  1261. eq:=te_equal;
  1262. end
  1263. else
  1264. begin
  1265. doconv:=tc_equal;
  1266. if (cdo_explicit in cdoptions) or
  1267. tobjectdef(tclassrefdef(def_from).pointeddef).is_related(
  1268. tobjectdef(tclassrefdef(def_to).pointeddef)) then
  1269. eq:=te_convert_l1;
  1270. end;
  1271. end
  1272. else
  1273. if (m_delphi in current_settings.modeswitches) and
  1274. is_voidpointer(def_from) then
  1275. begin
  1276. doconv:=tc_equal;
  1277. { prefer pointer-pointer assignments }
  1278. eq:=te_convert_l2;
  1279. end
  1280. else
  1281. { nil is compatible with class references }
  1282. if (fromtreetype=niln) then
  1283. begin
  1284. doconv:=tc_equal;
  1285. eq:=te_convert_l1;
  1286. end;
  1287. end;
  1288. filedef :
  1289. begin
  1290. { typed files are all equal to the abstract file type
  1291. name TYPEDFILE in system.pp in is_equal in types.pas
  1292. the problem is that it sholud be also compatible to FILE
  1293. but this would leed to a problem for ASSIGN RESET and REWRITE
  1294. when trying to find the good overloaded function !!
  1295. so all file function are doubled in system.pp
  1296. this is not very beautiful !!}
  1297. if (def_from.typ=filedef) then
  1298. begin
  1299. if (tfiledef(def_from).filetyp=tfiledef(def_to).filetyp) then
  1300. begin
  1301. if
  1302. (
  1303. (tfiledef(def_from).typedfiledef=nil) and
  1304. (tfiledef(def_to).typedfiledef=nil)
  1305. ) or
  1306. (
  1307. (tfiledef(def_from).typedfiledef<>nil) and
  1308. (tfiledef(def_to).typedfiledef<>nil) and
  1309. equal_defs(tfiledef(def_from).typedfiledef,tfiledef(def_to).typedfiledef)
  1310. ) or
  1311. (
  1312. (tfiledef(def_from).filetyp = ft_typed) and
  1313. (tfiledef(def_to).filetyp = ft_typed) and
  1314. (
  1315. (tfiledef(def_from).typedfiledef = tdef(voidtype)) or
  1316. (tfiledef(def_to).typedfiledef = tdef(voidtype))
  1317. )
  1318. ) then
  1319. begin
  1320. eq:=te_equal;
  1321. end;
  1322. end
  1323. else
  1324. if ((tfiledef(def_from).filetyp = ft_untyped) and
  1325. (tfiledef(def_to).filetyp = ft_typed)) or
  1326. ((tfiledef(def_from).filetyp = ft_typed) and
  1327. (tfiledef(def_to).filetyp = ft_untyped)) then
  1328. begin
  1329. doconv:=tc_equal;
  1330. eq:=te_convert_l1;
  1331. end;
  1332. end;
  1333. end;
  1334. recorddef :
  1335. begin
  1336. { interface -> guid }
  1337. if (def_to=rec_tguid) and
  1338. (is_interfacecom(def_from) or is_dispinterface(def_from)) then
  1339. begin
  1340. doconv:=tc_intf_2_guid;
  1341. eq:=te_convert_l1;
  1342. end;
  1343. end;
  1344. formaldef :
  1345. begin
  1346. doconv:=tc_equal;
  1347. if (def_from.typ=formaldef) then
  1348. eq:=te_equal
  1349. else
  1350. { Just about everything can be converted to a formaldef...}
  1351. if not (def_from.typ in [abstractdef,errordef]) then
  1352. eq:=te_convert_l2;
  1353. end;
  1354. end;
  1355. { if we didn't find an appropriate type conversion yet
  1356. then we search also the := operator }
  1357. if (eq=te_incompatible) and
  1358. { make sure there is not a single variant if variants }
  1359. { are not allowed (otherwise if only cdo_check_operator }
  1360. { and e.g. fromdef=stringdef and todef=variantdef, then }
  1361. { the test will still succeed }
  1362. ((cdo_allow_variant in cdoptions) or
  1363. ((def_from.typ<>variantdef) and (def_to.typ<>variantdef))
  1364. ) and
  1365. (
  1366. { Check for variants? }
  1367. (
  1368. (cdo_allow_variant in cdoptions) and
  1369. ((def_from.typ=variantdef) or (def_to.typ=variantdef))
  1370. ) or
  1371. { Check for operators? }
  1372. (
  1373. (cdo_check_operator in cdoptions) and
  1374. ((def_from.typ in [objectdef,recorddef,arraydef,stringdef]) or
  1375. (def_to.typ in [objectdef,recorddef,arraydef,stringdef]))
  1376. )
  1377. ) then
  1378. begin
  1379. operatorpd:=search_assignment_operator(def_from,def_to);
  1380. if assigned(operatorpd) then
  1381. eq:=te_convert_operator;
  1382. end;
  1383. { update convtype for te_equal when it is not yet set }
  1384. if (eq=te_equal) and
  1385. (doconv=tc_not_possible) then
  1386. doconv:=tc_equal;
  1387. compare_defs_ext:=eq;
  1388. end;
  1389. function equal_defs(def_from,def_to:tdef):boolean;
  1390. var
  1391. convtyp : tconverttype;
  1392. pd : tprocdef;
  1393. begin
  1394. { Compare defs with nothingn and no explicit typecasts and
  1395. searching for overloaded operators is not needed }
  1396. equal_defs:=(compare_defs_ext(def_from,def_to,nothingn,convtyp,pd,[])>=te_equal);
  1397. end;
  1398. function compare_defs(def_from,def_to:tdef;fromtreetype:tnodetype):tequaltype;
  1399. var
  1400. doconv : tconverttype;
  1401. pd : tprocdef;
  1402. begin
  1403. compare_defs:=compare_defs_ext(def_from,def_to,fromtreetype,doconv,pd,[cdo_check_operator,cdo_allow_variant]);
  1404. end;
  1405. function is_subequal(def1, def2: tdef): boolean;
  1406. var
  1407. basedef1,basedef2 : tenumdef;
  1408. Begin
  1409. is_subequal := false;
  1410. if assigned(def1) and assigned(def2) then
  1411. Begin
  1412. if (def1.typ = orddef) and (def2.typ = orddef) then
  1413. Begin
  1414. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  1415. { range checking for case statements is done with testrange }
  1416. case torddef(def1).ordtype of
  1417. u8bit,u16bit,u32bit,u64bit,
  1418. s8bit,s16bit,s32bit,s64bit :
  1419. is_subequal:=(torddef(def2).ordtype in [s64bit,u64bit,s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  1420. pasbool,bool8bit,bool16bit,bool32bit,bool64bit :
  1421. is_subequal:=(torddef(def2).ordtype in [pasbool,bool8bit,bool16bit,bool32bit,bool64bit]);
  1422. uchar :
  1423. is_subequal:=(torddef(def2).ordtype=uchar);
  1424. uwidechar :
  1425. is_subequal:=(torddef(def2).ordtype=uwidechar);
  1426. end;
  1427. end
  1428. else
  1429. Begin
  1430. { Check if both basedefs are equal }
  1431. if (def1.typ=enumdef) and (def2.typ=enumdef) then
  1432. Begin
  1433. { get both basedefs }
  1434. basedef1:=tenumdef(def1);
  1435. while assigned(basedef1.basedef) do
  1436. basedef1:=basedef1.basedef;
  1437. basedef2:=tenumdef(def2);
  1438. while assigned(basedef2.basedef) do
  1439. basedef2:=basedef2.basedef;
  1440. is_subequal:=(basedef1=basedef2);
  1441. end;
  1442. end;
  1443. end;
  1444. end;
  1445. function compare_paras(para1,para2 : TFPObjectList; acp : tcompare_paras_type; cpoptions: tcompare_paras_options):tequaltype;
  1446. var
  1447. currpara1,
  1448. currpara2 : tparavarsym;
  1449. eq,lowesteq : tequaltype;
  1450. hpd : tprocdef;
  1451. convtype : tconverttype;
  1452. cdoptions : tcompare_defs_options;
  1453. i1,i2 : byte;
  1454. begin
  1455. compare_paras:=te_incompatible;
  1456. cdoptions:=[cdo_parameter,cdo_check_operator,cdo_allow_variant];
  1457. { we need to parse the list from left-right so the
  1458. not-default parameters are checked first }
  1459. lowesteq:=high(tequaltype);
  1460. i1:=0;
  1461. i2:=0;
  1462. if cpo_ignorehidden in cpoptions then
  1463. begin
  1464. while (i1<para1.count) and
  1465. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1466. inc(i1);
  1467. while (i2<para2.count) and
  1468. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1469. inc(i2);
  1470. end;
  1471. while (i1<para1.count) and (i2<para2.count) do
  1472. begin
  1473. eq:=te_incompatible;
  1474. currpara1:=tparavarsym(para1[i1]);
  1475. currpara2:=tparavarsym(para2[i2]);
  1476. { Unique types must match exact }
  1477. if ((df_unique in currpara1.vardef.defoptions) or (df_unique in currpara2.vardef.defoptions)) and
  1478. (currpara1.vardef<>currpara2.vardef) then
  1479. exit;
  1480. { Handle hidden parameters separately, because self is
  1481. defined as voidpointer for methodpointers }
  1482. if (vo_is_hidden_para in currpara1.varoptions) or
  1483. (vo_is_hidden_para in currpara2.varoptions) then
  1484. begin
  1485. { both must be hidden }
  1486. if (vo_is_hidden_para in currpara1.varoptions)<>(vo_is_hidden_para in currpara2.varoptions) then
  1487. exit;
  1488. eq:=te_exact;
  1489. if not(vo_is_self in currpara1.varoptions) and
  1490. not(vo_is_self in currpara2.varoptions) then
  1491. begin
  1492. if (currpara1.varspez<>currpara2.varspez) then
  1493. exit;
  1494. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1495. convtype,hpd,cdoptions);
  1496. end;
  1497. end
  1498. else
  1499. begin
  1500. case acp of
  1501. cp_value_equal_const :
  1502. begin
  1503. if (
  1504. (currpara1.varspez<>currpara2.varspez) and
  1505. ((currpara1.varspez in [vs_var,vs_out]) or
  1506. (currpara2.varspez in [vs_var,vs_out]))
  1507. ) then
  1508. exit;
  1509. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1510. convtype,hpd,cdoptions);
  1511. end;
  1512. cp_all :
  1513. begin
  1514. if (currpara1.varspez<>currpara2.varspez) then
  1515. exit;
  1516. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1517. convtype,hpd,cdoptions);
  1518. end;
  1519. cp_procvar :
  1520. begin
  1521. if (currpara1.varspez<>currpara2.varspez) then
  1522. exit;
  1523. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1524. convtype,hpd,cdoptions);
  1525. { Parameters must be at least equal otherwise the are incompatible }
  1526. if (eq<te_equal) then
  1527. eq:=te_incompatible;
  1528. end;
  1529. else
  1530. eq:=compare_defs_ext(currpara1.vardef,currpara2.vardef,nothingn,
  1531. convtype,hpd,cdoptions);
  1532. end;
  1533. end;
  1534. { check type }
  1535. if eq=te_incompatible then
  1536. exit;
  1537. { open strings can never match exactly, since you cannot define }
  1538. { a separate "open string" type -> we have to be able to }
  1539. { consider those as exact when resolving forward definitions. }
  1540. { The same goes for array of const. Open arrays are handled }
  1541. { already (if their element types match exactly, they are }
  1542. { considered to be an exact match) }
  1543. { And also for "inline defined" function parameter definitions }
  1544. { (i.e., function types directly declared in a parameter list) }
  1545. if (is_array_of_const(currpara1.vardef) or
  1546. is_open_string(currpara1.vardef) or
  1547. ((currpara1.vardef.typ = procvardef) and
  1548. not(assigned(currpara1.vardef.typesym)))) and
  1549. (eq=te_equal) and
  1550. (cpo_openequalisexact in cpoptions) then
  1551. eq:=te_exact;
  1552. if eq<lowesteq then
  1553. lowesteq:=eq;
  1554. { also check default value if both have it declared }
  1555. if (cpo_comparedefaultvalue in cpoptions) and
  1556. assigned(currpara1.defaultconstsym) and
  1557. assigned(currpara2.defaultconstsym) then
  1558. begin
  1559. if not equal_constsym(tconstsym(currpara1.defaultconstsym),tconstsym(currpara2.defaultconstsym)) then
  1560. exit;
  1561. end;
  1562. inc(i1);
  1563. inc(i2);
  1564. if cpo_ignorehidden in cpoptions then
  1565. begin
  1566. while (i1<para1.count) and
  1567. (vo_is_hidden_para in tparavarsym(para1[i1]).varoptions) do
  1568. inc(i1);
  1569. while (i2<para2.count) and
  1570. (vo_is_hidden_para in tparavarsym(para2[i2]).varoptions) do
  1571. inc(i2);
  1572. end;
  1573. end;
  1574. { when both lists are empty then the parameters are equal. Also
  1575. when one list is empty and the other has a parameter with default
  1576. value assigned then the parameters are also equal }
  1577. if ((i1>=para1.count) and (i2>=para2.count)) or
  1578. ((cpo_allowdefaults in cpoptions) and
  1579. (((i1<para1.count) and assigned(tparavarsym(para1[i1]).defaultconstsym)) or
  1580. ((i2<para2.count) and assigned(tparavarsym(para2[i2]).defaultconstsym)))) then
  1581. compare_paras:=lowesteq;
  1582. end;
  1583. function proc_to_procvar_equal(def1:tabstractprocdef;def2:tprocvardef):tequaltype;
  1584. var
  1585. eq : tequaltype;
  1586. po_comp : tprocoptions;
  1587. begin
  1588. proc_to_procvar_equal:=te_incompatible;
  1589. if not(assigned(def1)) or not(assigned(def2)) then
  1590. exit;
  1591. { check for method pointer }
  1592. if (def1.is_methodpointer xor def2.is_methodpointer) or
  1593. (def1.is_addressonly xor def2.is_addressonly) then
  1594. exit;
  1595. { check return value and options, methodpointer is already checked }
  1596. po_comp:=[po_staticmethod,po_interrupt,
  1597. po_iocheck,po_varargs];
  1598. if (m_delphi in current_settings.modeswitches) then
  1599. exclude(po_comp,po_varargs);
  1600. if (def1.proccalloption=def2.proccalloption) and
  1601. ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
  1602. equal_defs(def1.returndef,def2.returndef) then
  1603. begin
  1604. { return equal type based on the parameters, but a proc->procvar
  1605. is never exact, so map an exact match of the parameters to
  1606. te_equal }
  1607. eq:=compare_paras(def1.paras,def2.paras,cp_procvar,[]);
  1608. if eq=te_exact then
  1609. eq:=te_equal;
  1610. proc_to_procvar_equal:=eq;
  1611. end;
  1612. end;
  1613. function compatible_childmethod_resultdef(parentretdef, childretdef: tdef): boolean;
  1614. begin
  1615. compatible_childmethod_resultdef :=
  1616. (equal_defs(parentretdef,childretdef)) or
  1617. ((parentretdef.typ=objectdef) and
  1618. (childretdef.typ=objectdef) and
  1619. is_class_or_interface(parentretdef) and
  1620. is_class_or_interface(childretdef) and
  1621. (tobjectdef(childretdef).is_related(tobjectdef(parentretdef))))
  1622. end;
  1623. end.