types.pas 39 KB

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