types.pas 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. {
  2. $Id$
  3. Copyright (C) 1993-98 by Florian Klaempfl
  4. This unit provides some help routines for type handling
  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 types;
  19. interface
  20. uses
  21. cobjects,globals,symtable;
  22. type
  23. tmmxtype = (mmxno,mmxu8bit,mmxs8bit,mmxu16bit,mmxs16bit,
  24. mmxu32bit,mmxs32bit,mmxfixed16,mmxsingle);
  25. { returns true, if def defines an ordinal type }
  26. function is_ordinal(def : pdef) : boolean;
  27. { returns the min. value of the type }
  28. function get_min_value(def : pdef) : longint;
  29. { returns true, if def defines an ordinal type }
  30. function is_integer(def : pdef) : boolean;
  31. { true if p is a boolean }
  32. function is_boolean(def : pdef) : boolean;
  33. { true if p points to an open array def }
  34. function is_open_array(p : pdef) : boolean;
  35. { true if o is an ansi string def }
  36. function is_ansistring(p : pdef) : boolean;
  37. { true if o is a long string def }
  38. function is_longstring(p : pdef) : boolean;
  39. { true if o is a wide string def }
  40. function is_widestring(p : pdef) : boolean;
  41. { true if o is a short string def }
  42. function is_shortstring(p : pdef) : boolean;
  43. { true if p is a char array def }
  44. function is_chararray(p : pdef) : boolean;
  45. { true if o is a pchar def }
  46. function is_pchar(p : pdef) : boolean;
  47. { returns true, if def defines a signed data type (only for ordinal types) }
  48. function is_signed(def : pdef) : boolean;
  49. { returns true, if def uses FPU }
  50. function is_fpu(def : pdef) : boolean;
  51. { true if the return value is in EAX }
  52. function ret_in_acc(def : pdef) : boolean;
  53. { true if uses a parameter as return value }
  54. function ret_in_param(def : pdef) : boolean;
  55. { true if a const parameter is too large to copy }
  56. function dont_copy_const_param(def : pdef) : boolean;
  57. { true if we must never copy this parameter }
  58. const
  59. never_copy_const_param : boolean = false;
  60. { true, if def1 and def2 are semantical the same }
  61. function is_equal(def1,def2 : pdef) : boolean;
  62. { checks for type compatibility (subgroups of type) }
  63. { used for case statements... probably missing stuff }
  64. { to use on other types }
  65. function is_subequal(def1, def2: pdef): boolean;
  66. { true, if two parameter lists are equal }
  67. { if value_equal_const is true, call by value }
  68. { and call by const parameter are assumed as }
  69. { equal }
  70. function equal_paras(def1,def2 : pdefcoll;value_equal_const : boolean) : boolean;
  71. { true if a function can be assigned to a procvar }
  72. function proc_to_procvar_equal(def1,def2 : pabstractprocdef) : boolean;
  73. { if l isn't in the range of def a range check error is generated }
  74. procedure testrange(def : pdef;l : longint);
  75. { returns the range of def }
  76. procedure getrange(def : pdef;var l : longint;var h : longint);
  77. { generates a VMT for _class }
  78. procedure genvmt(_class : pobjectdef);
  79. { some type helper routines for MMX support }
  80. function is_mmx_able_array(p : pdef) : boolean;
  81. { returns the mmx type }
  82. function mmx_type(p : pdef) : tmmxtype;
  83. implementation
  84. uses verbose,aasm;
  85. function equal_paras(def1,def2 : pdefcoll;value_equal_const : boolean) : boolean;
  86. begin
  87. while (assigned(def1)) and (assigned(def2)) do
  88. begin
  89. if value_equal_const then
  90. begin
  91. if not(is_equal(def1^.data,def2^.data)) or
  92. ((def1^.paratyp<>def2^.paratyp) and
  93. ((def1^.paratyp=vs_var) or
  94. (def1^.paratyp=vs_var)
  95. )
  96. ) then
  97. begin
  98. equal_paras:=false;
  99. exit;
  100. end;
  101. end
  102. else
  103. begin
  104. if not(is_equal(def1^.data,def2^.data)) or
  105. (def1^.paratyp<>def2^.paratyp) then
  106. begin
  107. equal_paras:=false;
  108. exit;
  109. end;
  110. end;
  111. def1:=def1^.next;
  112. def2:=def2^.next;
  113. end;
  114. if (def1=nil) and (def2=nil) then
  115. equal_paras:=true
  116. else
  117. equal_paras:=false;
  118. end;
  119. { true if a function can be assigned to a procvar }
  120. function proc_to_procvar_equal(def1,def2 : pabstractprocdef) : boolean;
  121. begin
  122. if is_equal(def1^.retdef,def2^.retdef) and
  123. equal_paras(def1^.para1,def2^.para1,false) and
  124. ((def1^.options and po_compatibility_options)=
  125. (def2^.options and po_compatibility_options)) then
  126. proc_to_procvar_equal:=true
  127. else
  128. proc_to_procvar_equal:=false;
  129. end;
  130. { returns true, if def uses FPU }
  131. function is_fpu(def : pdef) : boolean;
  132. begin
  133. is_fpu:=(def^.deftype=floatdef) and (pfloatdef(def)^.typ<>f32bit);
  134. end;
  135. { true if p is an ordinal }
  136. function is_ordinal(def : pdef) : boolean;
  137. var
  138. dt : tbasetype;
  139. begin
  140. case def^.deftype of
  141. orddef : begin
  142. dt:=porddef(def)^.typ;
  143. is_ordinal:=dt in [uchar,u8bit,u16bit,u32bit,s8bit,s16bit,s32bit,bool8bit,bool16bit,bool32bit];
  144. end;
  145. enumdef : is_ordinal:=true;
  146. else
  147. is_ordinal:=false;
  148. end;
  149. end;
  150. { returns the min. value of the type }
  151. function get_min_value(def : pdef) : longint;
  152. begin
  153. case def^.deftype of
  154. orddef:
  155. get_min_value:=porddef(def)^.low;
  156. enumdef:
  157. get_min_value:=penumdef(def)^.min;
  158. else
  159. get_min_value:=0;
  160. end;
  161. end;
  162. { true if p is an integer }
  163. function is_integer(def : pdef) : boolean;
  164. begin
  165. is_integer:=(def^.deftype=orddef) and
  166. (porddef(def)^.typ in [uauto,u8bit,u16bit,u32bit,s8bit,s16bit,s32bit]);
  167. end;
  168. { true if p is a boolean }
  169. function is_boolean(def : pdef) : boolean;
  170. begin
  171. is_boolean:=(def^.deftype=orddef) and
  172. (porddef(def)^.typ in [bool8bit,bool16bit,bool32bit]);
  173. end;
  174. { true if p is signed (integer) }
  175. function is_signed(def : pdef) : boolean;
  176. var
  177. dt : tbasetype;
  178. begin
  179. case def^.deftype of
  180. orddef : begin
  181. dt:=porddef(def)^.typ;
  182. is_signed:=(dt in [s8bit,s16bit,s32bit]);
  183. end;
  184. enumdef : is_signed:=false;
  185. else
  186. is_signed:=false;
  187. end;
  188. end;
  189. { true, if p points to an open array def }
  190. function is_open_array(p : pdef) : boolean;
  191. begin
  192. is_open_array:=(p^.deftype=arraydef) and
  193. (parraydef(p)^.lowrange=0) and
  194. (parraydef(p)^.highrange=-1);
  195. end;
  196. { true if p is an ansi string def }
  197. function is_ansistring(p : pdef) : boolean;
  198. begin
  199. is_ansistring:=(p^.deftype=stringdef) and
  200. (pstringdef(p)^.string_typ=st_ansistring);
  201. end;
  202. { true if p is an long string def }
  203. function is_longstring(p : pdef) : boolean;
  204. begin
  205. is_longstring:=(p^.deftype=stringdef) and
  206. (pstringdef(p)^.string_typ=st_longstring);
  207. end;
  208. { true if p is an wide string def }
  209. function is_widestring(p : pdef) : boolean;
  210. begin
  211. is_widestring:=(p^.deftype=stringdef) and
  212. (pstringdef(p)^.string_typ=st_widestring);
  213. end;
  214. { true if p is an short string def }
  215. function is_shortstring(p : pdef) : boolean;
  216. begin
  217. is_shortstring:=(p^.deftype=stringdef) and
  218. (pstringdef(p)^.string_typ=st_shortstring);
  219. end;
  220. { true if p is a char array def }
  221. function is_chararray(p : pdef) : boolean;
  222. begin
  223. is_chararray:=(p^.deftype=arraydef) and
  224. (parraydef(p)^.lowrange=0) and
  225. is_equal(parraydef(p)^.definition,cchardef);
  226. end;
  227. { true if p is a pchar def }
  228. function is_pchar(p : pdef) : boolean;
  229. begin
  230. is_pchar:=(p^.deftype=pointerdef) and
  231. is_equal(Ppointerdef(p)^.definition,cchardef);
  232. end;
  233. { true if the return value is in accumulator (EAX for i386), D0 for 68k }
  234. function ret_in_acc(def : pdef) : boolean;
  235. begin
  236. ret_in_acc:=(def^.deftype in [orddef,pointerdef,enumdef,classrefdef]) or
  237. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_ansistring,st_widestring])) or
  238. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)=0)) or
  239. ((def^.deftype=objectdef) and pobjectdef(def)^.isclass) or
  240. ((def^.deftype=setdef) and (psetdef(def)^.settype=smallset)) or
  241. ((def^.deftype=floatdef) and (pfloatdef(def)^.typ=f32bit));
  242. end;
  243. { true if uses a parameter as return value }
  244. function ret_in_param(def : pdef) : boolean;
  245. begin
  246. ret_in_param:=(def^.deftype in [arraydef,recorddef]) or
  247. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
  248. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)<>0)) or
  249. ((def^.deftype=objectdef) and ((pobjectdef(def)^.options and oois_class)=0)) or
  250. ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
  251. end;
  252. { true if a const parameter is too large to copy }
  253. function dont_copy_const_param(def : pdef) : boolean;
  254. begin
  255. dont_copy_const_param:=(def^.deftype in [arraydef,objectdef,formaldef,recorddef]) or
  256. ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
  257. ((def^.deftype=procvardef) and ((pprocvardef(def)^.options and pomethodpointer)<>0)) or
  258. ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
  259. end;
  260. { test if l is in the range of def, outputs error if out of range }
  261. procedure testrange(def : pdef;l : longint);
  262. var
  263. lv,hv: longint;
  264. begin
  265. getrange(def,lv,hv);
  266. if (def^.deftype=orddef) and
  267. (porddef(def)^.typ=u32bit) then
  268. begin
  269. if lv<=hv then
  270. begin
  271. if (l<lv) or (l>hv) then
  272. Message(parser_e_range_check_error);
  273. end
  274. else
  275. { this happens with the wrap around problem }
  276. { if lv is positive and hv is over $7ffffff }
  277. { so it seems negative }
  278. begin
  279. if ((l>=0) and (l<lv)) or
  280. ((l<0) and (l>hv)) then
  281. Message(parser_e_range_check_error);
  282. end;
  283. end
  284. else if (l<lv) or (l>hv) then
  285. Message(parser_e_range_check_error);
  286. end;
  287. { return the range from def in l and h }
  288. procedure getrange(def : pdef;var l : longint;var h : longint);
  289. begin
  290. case def^.deftype of
  291. orddef : begin
  292. l:=porddef(def)^.low;
  293. h:=porddef(def)^.high;
  294. end;
  295. enumdef : begin
  296. l:=penumdef(def)^.min;
  297. h:=penumdef(def)^.max;
  298. end;
  299. end;
  300. end;
  301. function mmx_type(p : pdef) : tmmxtype;
  302. begin
  303. mmx_type:=mmxno;
  304. if is_mmx_able_array(p) then
  305. begin
  306. if parraydef(p)^.definition^.deftype=floatdef then
  307. case pfloatdef(parraydef(p)^.definition)^.typ of
  308. s32real:
  309. mmx_type:=mmxsingle;
  310. f16bit:
  311. mmx_type:=mmxfixed16
  312. end
  313. else
  314. case porddef(parraydef(p)^.definition)^.typ of
  315. u8bit:
  316. mmx_type:=mmxu8bit;
  317. s8bit:
  318. mmx_type:=mmxs8bit;
  319. u16bit:
  320. mmx_type:=mmxu16bit;
  321. s16bit:
  322. mmx_type:=mmxs16bit;
  323. u32bit:
  324. mmx_type:=mmxu32bit;
  325. s32bit:
  326. mmx_type:=mmxs32bit;
  327. end;
  328. end;
  329. end;
  330. function is_mmx_able_array(p : pdef) : boolean;
  331. begin
  332. {$ifdef SUPPORT_MMX}
  333. if (cs_mmx_saturation in aktlocalswitches) then
  334. begin
  335. is_mmx_able_array:=(p^.deftype=arraydef) and
  336. (
  337. ((parraydef(p)^.definition^.deftype=orddef) and
  338. (
  339. (parraydef(p)^.lowrange=0) and
  340. (parraydef(p)^.highrange=1) and
  341. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  342. ) or
  343. (
  344. (parraydef(p)^.lowrange=0) and
  345. (parraydef(p)^.highrange=3) and
  346. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  347. )
  348. )
  349. ) or
  350. (
  351. ((parraydef(p)^.definition^.deftype=floatdef) and
  352. (
  353. (parraydef(p)^.lowrange=0) and
  354. (parraydef(p)^.highrange=3) and
  355. (pfloatdef(parraydef(p)^.definition)^.typ=f16bit)
  356. ) or
  357. (
  358. (parraydef(p)^.lowrange=0) and
  359. (parraydef(p)^.highrange=1) and
  360. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  361. )
  362. )
  363. );
  364. end
  365. else
  366. begin
  367. is_mmx_able_array:=(p^.deftype=arraydef) and
  368. (
  369. ((parraydef(p)^.definition^.deftype=orddef) and
  370. (
  371. (parraydef(p)^.lowrange=0) and
  372. (parraydef(p)^.highrange=1) and
  373. (porddef(parraydef(p)^.definition)^.typ in [u32bit,s32bit])
  374. ) or
  375. (
  376. (parraydef(p)^.lowrange=0) and
  377. (parraydef(p)^.highrange=3) and
  378. (porddef(parraydef(p)^.definition)^.typ in [u16bit,s16bit])
  379. ) or
  380. (
  381. (parraydef(p)^.lowrange=0) and
  382. (parraydef(p)^.highrange=7) and
  383. (porddef(parraydef(p)^.definition)^.typ in [u8bit,s8bit])
  384. )
  385. )
  386. ) or
  387. (
  388. ((parraydef(p)^.definition^.deftype=floatdef) and
  389. (
  390. (parraydef(p)^.lowrange=0) and
  391. (parraydef(p)^.highrange=3) and
  392. (pfloatdef(parraydef(p)^.definition)^.typ=f32bit)
  393. )
  394. or
  395. (
  396. (parraydef(p)^.lowrange=0) and
  397. (parraydef(p)^.highrange=1) and
  398. (pfloatdef(parraydef(p)^.definition)^.typ=s32real)
  399. )
  400. )
  401. );
  402. end;
  403. {$else SUPPORT_MMX}
  404. is_mmx_able_array:=false;
  405. {$endif SUPPORT_MMX}
  406. end;
  407. function is_equal(def1,def2 : pdef) : boolean;
  408. var
  409. b : boolean;
  410. hd : pdef;
  411. hp1,hp2 : pdefcoll;
  412. begin
  413. { both types must exists }
  414. if not (assigned(def1) and assigned(def2)) then
  415. begin
  416. is_equal:=false;
  417. exit;
  418. end;
  419. { be sure, that if there is a stringdef, that this is def1 }
  420. if def2^.deftype=stringdef then
  421. begin
  422. hd:=def1;
  423. def1:=def2;
  424. def2:=hd;
  425. end;
  426. b:=false;
  427. { both point to the same definition ? }
  428. if def1=def2 then
  429. b:=true
  430. else
  431. { pointer with an equal definition are equal }
  432. if (def1^.deftype=pointerdef) and (def2^.deftype=pointerdef) then
  433. { here a problem detected in tabsolutesym }
  434. { the types can be forward type !! }
  435. begin
  436. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  437. b:=(def1^.sym=def2^.sym)
  438. else
  439. b:=ppointerdef(def1)^.definition=ppointerdef(def2)^.definition;
  440. end
  441. else
  442. { ordinals are equal only when the ordinal type is equal }
  443. if (def1^.deftype=orddef) and (def2^.deftype=orddef) then
  444. begin
  445. case porddef(def1)^.typ of
  446. u8bit,u16bit,u32bit,
  447. s8bit,s16bit,s32bit:
  448. b:=((porddef(def1)^.typ=porddef(def2)^.typ) and
  449. (porddef(def1)^.low=porddef(def2)^.low) and
  450. (porddef(def1)^.high=porddef(def2)^.high));
  451. uvoid,uchar,
  452. bool8bit,bool16bit,bool32bit:
  453. b:=(porddef(def1)^.typ=porddef(def2)^.typ);
  454. end;
  455. end
  456. else
  457. if (def1^.deftype=floatdef) and (def2^.deftype=floatdef) then
  458. b:=pfloatdef(def1)^.typ=pfloatdef(def2)^.typ
  459. else
  460. { strings with the same length are equal }
  461. if (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  462. (pstringdef(def1)^.string_typ=pstringdef(def2)^.string_typ) then
  463. begin
  464. b:=not(is_shortstring(def1)) or
  465. (pstringdef(def1)^.len=pstringdef(def2)^.len);
  466. end
  467. { STRING[N] ist equivalent zu ARRAY[0..N] OF CHAR (N<256) }
  468. {
  469. else if ((def1^.deftype=stringdef) and (def2^.deftype=arraydef)) and
  470. (parraydef(def2)^.definition^.deftype=orddef) and
  471. (porddef(parraydef(def1)^.definition)^.typ=uchar) and
  472. (parraydef(def2)^.lowrange=0) and
  473. (parraydef(def2)^.highrange=pstringdef(def1)^.len) then
  474. b:=true }
  475. else
  476. if (def1^.deftype=formaldef) and (def2^.deftype=formaldef) then
  477. b:=true
  478. { file types with the same file element type are equal }
  479. { this is a problem for assign !! }
  480. { changed to allow if one is untyped }
  481. { all typed files are equal to the special }
  482. { typed file that has voiddef as elemnt type }
  483. { but must NOT match for text file !!! }
  484. else
  485. if (def1^.deftype=filedef) and (def2^.deftype=filedef) then
  486. b:=(pfiledef(def1)^.filetype=pfiledef(def2)^.filetype) and
  487. ((
  488. ((pfiledef(def1)^.typed_as=nil) and
  489. (pfiledef(def2)^.typed_as=nil)) or
  490. (
  491. (pfiledef(def1)^.typed_as<>nil) and
  492. (pfiledef(def2)^.typed_as<>nil) and
  493. is_equal(pfiledef(def1)^.typed_as,pfiledef(def2)^.typed_as)
  494. ) or
  495. ( (pfiledef(def1)^.typed_as=pdef(voiddef)) or
  496. (pfiledef(def2)^.typed_as=pdef(voiddef))
  497. )))
  498. { sets with the same element type are equal }
  499. else
  500. if (def1^.deftype=setdef) and (def2^.deftype=setdef) then
  501. begin
  502. if assigned(psetdef(def1)^.setof) and
  503. assigned(psetdef(def2)^.setof) then
  504. b:=(psetdef(def1)^.setof^.deftype=psetdef(def2)^.setof^.deftype)
  505. else
  506. b:=true;
  507. end
  508. else
  509. if (def1^.deftype=procvardef) and (def2^.deftype=procvardef) then
  510. begin
  511. { poassembler isn't important for compatibility }
  512. b:=((pprocvardef(def1)^.options and not(poassembler))=
  513. (pprocvardef(def2)^.options and not(poassembler))
  514. ) and
  515. is_equal(pprocvardef(def1)^.retdef,pprocvardef(def2)^.retdef);
  516. { now evalute the parameters }
  517. if b then
  518. begin
  519. hp1:=pprocvardef(def1)^.para1;
  520. hp2:=pprocvardef(def1)^.para1;
  521. while assigned(hp1) and assigned(hp2) do
  522. begin
  523. if not(is_equal(hp1^.data,hp2^.data)) or
  524. not(hp1^.paratyp=hp2^.paratyp) then
  525. begin
  526. b:=false;
  527. break;
  528. end;
  529. hp1:=hp1^.next;
  530. hp2:=hp2^.next;
  531. end;
  532. b:=(hp1=nil) and (hp2=nil);
  533. end;
  534. end
  535. else
  536. if (def1^.deftype=arraydef) and (def2^.deftype=arraydef) and
  537. (is_open_array(def1) or is_open_array(def2)) then
  538. begin
  539. if parraydef(def1)^.IsArrayOfConst or parraydef(def2)^.IsArrayOfConst then
  540. b:=true
  541. else
  542. b:=is_equal(parraydef(def1)^.definition,parraydef(def2)^.definition);
  543. end
  544. else
  545. if (def1^.deftype=classrefdef) and (def2^.deftype=classrefdef) then
  546. begin
  547. { similar to pointerdef: }
  548. if assigned(def1^.sym) and ((def1^.sym^.properties and sp_forwarddef)<>0) then
  549. b:=(def1^.sym=def2^.sym)
  550. else
  551. b:=is_equal(pclassrefdef(def1)^.definition,pclassrefdef(def2)^.definition);
  552. end;
  553. is_equal:=b;
  554. end;
  555. function is_subequal(def1, def2: pdef): boolean;
  556. Begin
  557. if assigned(def1) and assigned(def2) then
  558. Begin
  559. is_subequal := FALSE;
  560. if (def1^.deftype = orddef) and (def2^.deftype = orddef) then
  561. Begin
  562. { see p.47 of Turbo Pascal 7.01 manual for the separation of types }
  563. { range checking for case statements is done with testrange }
  564. case porddef(def1)^.typ of
  565. u8bit,u16bit,u32bit,
  566. s8bit,s16bit,s32bit : is_subequal:=(porddef(def2)^.typ in [s32bit,u32bit,u8bit,s8bit,s16bit,u16bit]);
  567. bool8bit,bool16bit,bool32bit : is_subequal:=(porddef(def2)^.typ in [bool8bit,bool16bit,bool32bit]);
  568. uchar : is_subequal:=(porddef(def2)^.typ=uchar);
  569. end;
  570. end
  571. else
  572. Begin
  573. { I assume that both enumerations are equal when the first }
  574. { pointers are equal. }
  575. if (def1^.deftype = enumdef) and (def2^.deftype =enumdef) then
  576. Begin
  577. if penumdef(def1)^.first = penumdef(def2)^.first then
  578. is_subequal := TRUE;
  579. end;
  580. end;
  581. end; { endif assigned ... }
  582. end;
  583. type
  584. pprocdefcoll = ^tprocdefcoll;
  585. tprocdefcoll = record
  586. next : pprocdefcoll;
  587. data : pprocdef;
  588. end;
  589. psymcoll = ^tsymcoll;
  590. tsymcoll = record
  591. next : psymcoll;
  592. name : pstring;
  593. data : pprocdefcoll;
  594. end;
  595. var
  596. wurzel : psymcoll;
  597. nextvirtnumber : longint;
  598. _c : pobjectdef;
  599. has_constructor,has_virtual_method : boolean;
  600. procedure eachsym(sym : psym);{$ifndef FPC}far;{$endif}
  601. var
  602. procdefcoll : pprocdefcoll;
  603. hp : pprocdef;
  604. symcoll : psymcoll;
  605. _name : string;
  606. stored : boolean;
  607. { creates a new entry in the procsym list }
  608. procedure newentry;
  609. begin
  610. { if not, generate a new symbol item }
  611. new(symcoll);
  612. symcoll^.name:=stringdup(sym^.name);
  613. symcoll^.next:=wurzel;
  614. symcoll^.data:=nil;
  615. wurzel:=symcoll;
  616. hp:=pprocsym(sym)^.definition;
  617. { inserts all definitions }
  618. while assigned(hp) do
  619. begin
  620. new(procdefcoll);
  621. procdefcoll^.data:=hp;
  622. procdefcoll^.next:=symcoll^.data;
  623. symcoll^.data:=procdefcoll;
  624. { if it's a virtual method }
  625. if (hp^.options and povirtualmethod)<>0 then
  626. begin
  627. { then it gets a number ... }
  628. hp^.extnumber:=nextvirtnumber;
  629. { and we inc the number }
  630. inc(nextvirtnumber);
  631. has_virtual_method:=true;
  632. end;
  633. if (hp^.options and poconstructor)<>0 then
  634. has_constructor:=true;
  635. { check, if a method should be overridden }
  636. if (hp^.options and pooverridingmethod)<>0 then
  637. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  638. { next overloaded method }
  639. hp:=hp^.nextoverloaded;
  640. end;
  641. end;
  642. begin
  643. { put only sub routines into the VMT }
  644. if sym^.typ=procsym then
  645. begin
  646. _name:=sym^.name;
  647. symcoll:=wurzel;
  648. while assigned(symcoll) do
  649. begin
  650. { does the symbol already exist in the list ? }
  651. if _name=symcoll^.name^ then
  652. begin
  653. { walk through all defs of the symbol }
  654. hp:=pprocsym(sym)^.definition;
  655. while assigned(hp) do
  656. begin
  657. { compare with all stored definitions }
  658. procdefcoll:=symcoll^.data;
  659. stored:=false;
  660. while assigned(procdefcoll) do
  661. begin
  662. { compare parameters }
  663. if equal_paras(procdefcoll^.data^.para1,hp^.para1,false) and
  664. (
  665. ((procdefcoll^.data^.options and povirtualmethod)<>0) or
  666. ((hp^.options and povirtualmethod)<>0)
  667. ) then
  668. begin
  669. { wenn sie gleich sind }
  670. { und eine davon virtual deklariert ist }
  671. { Fehler falls nur eine VIRTUAL }
  672. if (procdefcoll^.data^.options and povirtualmethod)<>
  673. (hp^.options and povirtualmethod) then
  674. begin
  675. { in classes, we hide the old method }
  676. if _c^.isclass then
  677. begin
  678. { warn only if it is the first time,
  679. we hide the method }
  680. if _c=hp^._class then
  681. Message1(parser_w_should_use_override,_c^.name^+'.'+_name);
  682. newentry;
  683. exit;
  684. end
  685. else
  686. if _c=hp^._class then
  687. begin
  688. Message1(parser_w_overloaded_are_not_both_virtual,_c^.name^+'.'+_name);
  689. newentry;
  690. exit;
  691. end;
  692. end;
  693. { check, if the overridden directive is set }
  694. { (povirtualmethod is set! }
  695. { class ? }
  696. if _c^.isclass and
  697. ((hp^.options and pooverridingmethod)=0) then
  698. begin
  699. { warn only if it is the first time,
  700. we hide the method }
  701. if _c=hp^._class then
  702. Message1(parser_w_should_use_override,_c^.name^+'.'+_name);
  703. newentry;
  704. exit;
  705. end;
  706. { error, if the return types aren't equal }
  707. if not(is_equal(procdefcoll^.data^.retdef,hp^.retdef)) then
  708. Message1(parser_e_overloaded_methodes_not_same_ret,_c^.name^+'.'+_name);
  709. { the flags have to match }
  710. { except abstract and override }
  711. if (procdefcoll^.data^.options and not(poabstractmethod or pooverridingmethod))<>
  712. (hp^.options and not(poabstractmethod or pooverridingmethod)) then
  713. Message1(parser_e_header_dont_match_forward,_c^.name^+'.'+_name);
  714. { now set the number }
  715. hp^.extnumber:=procdefcoll^.data^.extnumber;
  716. { and exchange }
  717. procdefcoll^.data:=hp;
  718. stored:=true;
  719. end;
  720. procdefcoll:=procdefcoll^.next;
  721. end;
  722. { if it isn't saved in the list }
  723. { we create a new entry }
  724. if not(stored) then
  725. begin
  726. new(procdefcoll);
  727. procdefcoll^.data:=hp;
  728. procdefcoll^.next:=symcoll^.data;
  729. symcoll^.data:=procdefcoll;
  730. { if the method is virtual ... }
  731. if (hp^.options and povirtualmethod)<>0 then
  732. begin
  733. { ... it will get a number }
  734. hp^.extnumber:=nextvirtnumber;
  735. inc(nextvirtnumber);
  736. end;
  737. { check, if a method should be overridden }
  738. if (hp^.options and pooverridingmethod)<>0 then
  739. Message1(parser_e_nothing_to_be_overridden,_c^.name^+'.'+_name);
  740. end;
  741. hp:=hp^.nextoverloaded;
  742. end;
  743. exit;
  744. end;
  745. symcoll:=symcoll^.next;
  746. end;
  747. newentry;
  748. end;
  749. end;
  750. procedure genvmt(_class : pobjectdef);
  751. procedure do_genvmt(p : pobjectdef);
  752. begin
  753. { start with the base class }
  754. if assigned(p^.childof) then
  755. do_genvmt(p^.childof);
  756. { walk through all public syms }
  757. _c:=_class;
  758. {$ifdef tp}
  759. p^.publicsyms^.foreach(eachsym);
  760. {$else}
  761. p^.publicsyms^.foreach(@eachsym);
  762. {$endif}
  763. end;
  764. var
  765. symcoll : psymcoll;
  766. procdefcoll : pprocdefcoll;
  767. i : longint;
  768. begin
  769. wurzel:=nil;
  770. nextvirtnumber:=0;
  771. has_constructor:=false;
  772. has_virtual_method:=false;
  773. { generates a tree of all used methods }
  774. do_genvmt(_class);
  775. if has_virtual_method and not(has_constructor) then
  776. Message1(parser_w_virtual_without_constructor,_class^.name^);
  777. { generates the VMT }
  778. { walk trough all numbers for virtual methods and search }
  779. { the method }
  780. for i:=0 to nextvirtnumber-1 do
  781. begin
  782. symcoll:=wurzel;
  783. { walk trough all symbols }
  784. while assigned(symcoll) do
  785. begin
  786. { walk trough all methods }
  787. procdefcoll:=symcoll^.data;
  788. while assigned(procdefcoll) do
  789. begin
  790. { writes the addresses to the VMT }
  791. { but only this which are declared as virtual }
  792. if procdefcoll^.data^.extnumber=i then
  793. begin
  794. if (procdefcoll^.data^.options and povirtualmethod)<>0 then
  795. begin
  796. { if a method is abstract, then is also the }
  797. { class abstract and it's not allow to }
  798. { generates an instance }
  799. if (procdefcoll^.data^.options and poabstractmethod)<>0 then
  800. begin
  801. _class^.options:=_class^.options or oois_abstract;
  802. datasegment^.concat(new(pai_const,init_symbol('FPC_ABSTRACTERROR')));
  803. end
  804. else
  805. begin
  806. datasegment^.concat(new(pai_const,init_symbol(
  807. strpnew(procdefcoll^.data^.mangledname))));
  808. maybe_concat_external(procdefcoll^.data^.owner,
  809. procdefcoll^.data^.mangledname);
  810. end;
  811. end;
  812. end;
  813. procdefcoll:=procdefcoll^.next;
  814. end;
  815. symcoll:=symcoll^.next;
  816. end;
  817. end;
  818. { disposes the above generated tree }
  819. symcoll:=wurzel;
  820. while assigned(symcoll) do
  821. begin
  822. wurzel:=symcoll^.next;
  823. stringdispose(symcoll^.name);
  824. procdefcoll:=symcoll^.data;
  825. while assigned(procdefcoll) do
  826. begin
  827. symcoll^.data:=procdefcoll^.next;
  828. dispose(procdefcoll);
  829. procdefcoll:=symcoll^.data;
  830. end;
  831. dispose(symcoll);
  832. symcoll:=wurzel;
  833. end;
  834. end;
  835. end.
  836. {
  837. $Log$
  838. Revision 1.32 1998-10-05 21:33:35 peter
  839. * fixed 161,165,166,167,168
  840. Revision 1.31 1998/09/23 09:58:56 peter
  841. * first working array of const things
  842. Revision 1.30 1998/09/22 15:40:58 peter
  843. * some extra ifdef GDB
  844. Revision 1.29 1998/09/16 12:37:31 michael
  845. Added FPC_ prefix to abstracterror
  846. Revision 1.28 1998/09/09 16:44:23 florian
  847. * I hope, the case bug is fixed now
  848. Revision 1.27 1998/09/07 17:37:07 florian
  849. * first fixes for published properties
  850. Revision 1.26 1998/09/04 12:24:31 florian
  851. * bug0159 fixed
  852. Revision 1.25 1998/09/04 09:06:36 florian
  853. * bug0132 fixed
  854. Revision 1.24 1998/09/04 08:36:49 peter
  855. * fixed boolean:=integer which is not explicit
  856. Revision 1.23 1998/09/01 17:39:55 peter
  857. + internal constant functions
  858. Revision 1.22 1998/09/01 12:53:28 peter
  859. + aktpackenum
  860. Revision 1.21 1998/08/19 00:42:45 peter
  861. + subrange types for enums
  862. + checking for bounds type with ranges
  863. Revision 1.20 1998/08/18 14:17:14 pierre
  864. * bug about assigning the return value of a function to
  865. a procvar fixed : warning
  866. assigning a proc to a procvar need @ in FPC mode !!
  867. * missing file/line info restored
  868. Revision 1.19 1998/08/18 09:24:48 pierre
  869. * small warning position bug fixed
  870. * support_mmx switches splitting was missing
  871. * rhide error and warning output corrected
  872. Revision 1.18 1998/08/14 18:18:49 peter
  873. + dynamic set contruction
  874. * smallsets are now working (always longint size)
  875. Revision 1.17 1998/08/05 16:00:17 florian
  876. * some fixes for ansi strings
  877. Revision 1.16 1998/07/20 23:35:50 michael
  878. Const ansistrings are not copied.
  879. Revision 1.15 1998/07/18 22:54:32 florian
  880. * some ansi/wide/longstring support fixed:
  881. o parameter passing
  882. o returning as result from functions
  883. Revision 1.14 1998/06/12 14:50:50 peter
  884. * removed the tree dependency to types.pas
  885. * long_fil.pas support (not fully tested yet)
  886. Revision 1.13 1998/06/03 22:49:07 peter
  887. + wordbool,longbool
  888. * rename bis,von -> high,low
  889. * moved some systemunit loading/creating to psystem.pas
  890. Revision 1.12 1998/05/12 10:47:00 peter
  891. * moved printstatus to verb_def
  892. + V_Normal which is between V_Error and V_Warning and doesn't have a
  893. prefix like error: warning: and is included in V_Default
  894. * fixed some messages
  895. * first time parameter scan is only for -v and -T
  896. - removed old style messages
  897. Revision 1.11 1998/05/01 16:38:46 florian
  898. * handling of private and protected fixed
  899. + change_keywords_to_tp implemented to remove
  900. keywords which aren't supported by tp
  901. * break and continue are now symbols of the system unit
  902. + widestring, longstring and ansistring type released
  903. Revision 1.10 1998/04/29 10:34:08 pierre
  904. + added some code for ansistring (not complete nor working yet)
  905. * corrected operator overloading
  906. * corrected nasm output
  907. + started inline procedures
  908. + added starstarn : use ** for exponentiation (^ gave problems)
  909. + started UseTokenInfo cond to get accurate positions
  910. Revision 1.9 1998/04/21 10:16:49 peter
  911. * patches from strasbourg
  912. * objects is not used anymore in the fpc compiled version
  913. Revision 1.8 1998/04/12 22:39:44 florian
  914. * problem with read access to properties solved
  915. * correct handling of hidding methods via virtual (COM)
  916. * correct result type of constructor calls (COM), the resulttype
  917. depends now on the type of the class reference
  918. Revision 1.7 1998/04/10 21:36:56 florian
  919. + some stuff to support method pointers (procedure of object) added
  920. (declaration, parameter handling)
  921. Revision 1.6 1998/04/10 15:39:49 florian
  922. * more fixes to get classes.pas compiled
  923. Revision 1.5 1998/04/09 23:02:16 florian
  924. * small problems solved to get remake3 work
  925. Revision 1.4 1998/04/08 16:58:09 pierre
  926. * several bugfixes
  927. ADD ADC and AND are also sign extended
  928. nasm output OK (program still crashes at end
  929. and creates wrong assembler files !!)
  930. procsym types sym in tdef removed !!
  931. Revision 1.3 1998/04/08 11:34:22 peter
  932. * nasm works (linux only tested)
  933. }