types.pas 38 KB

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