defcmp.pas 53 KB

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