types.pas 38 KB

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