types.pas 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  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. if (procdefcoll^.data^.options and povirtualmethod)<>0 then
  745. maybe_concat_external(procdefcoll^.data^.owner,
  746. procdefcoll^.data^.mangledname);
  747. end;
  748. end;
  749. end;
  750. procdefcoll:=procdefcoll^.next;
  751. end;
  752. symcoll:=symcoll^.next;
  753. end;
  754. end;
  755. { disposes the above generated tree }
  756. symcoll:=wurzel;
  757. while assigned(symcoll) do
  758. begin
  759. wurzel:=symcoll^.next;
  760. stringdispose(symcoll^.name);
  761. procdefcoll:=symcoll^.data;
  762. while assigned(procdefcoll) do
  763. begin
  764. symcoll^.data:=procdefcoll^.next;
  765. dispose(procdefcoll);
  766. procdefcoll:=symcoll^.data;
  767. end;
  768. dispose(symcoll);
  769. symcoll:=wurzel;
  770. end;
  771. end;
  772. end.
  773. {
  774. $Log$
  775. Revision 1.3 1998-04-08 11:34:22 peter
  776. * nasm works (linux only tested)
  777. Revision 1.2 1998/03/28 23:09:57 florian
  778. * secondin bugfix (m68k and i386)
  779. * overflow checking bugfix (m68k and i386) -- pretty useless in
  780. secondadd, since everything is done using 32-bit
  781. * loading pointer to routines hopefully fixed (m68k)
  782. * flags problem with calls to RTL internal routines fixed (still strcmp
  783. to fix) (m68k)
  784. * #ELSE was still incorrect (didn't take care of the previous level)
  785. * problem with filenames in the command line solved
  786. * problem with mangledname solved
  787. * linking name problem solved (was case insensitive)
  788. * double id problem and potential crash solved
  789. * stop after first error
  790. * and=>test problem removed
  791. * correct read for all float types
  792. * 2 sigsegv fixes and a cosmetic fix for Internal Error
  793. * push/pop is now correct optimized (=> mov (%esp),reg)
  794. Revision 1.1.1.1 1998/03/25 11:18:15 root
  795. * Restored version
  796. Revision 1.24 1998/03/21 23:59:40 florian
  797. * indexed properties fixed
  798. * ppu i/o of properties fixed
  799. * field can be also used for write access
  800. * overriding of properties
  801. Revision 1.23 1998/03/20 23:31:35 florian
  802. * bug0113 fixed
  803. * problem with interdepened units fixed ("options.pas problem")
  804. * two small extensions for future AMD 3D support
  805. Revision 1.22 1998/03/10 01:17:30 peter
  806. * all files have the same header
  807. * messages are fully implemented, EXTDEBUG uses Comment()
  808. + AG... files for the Assembler generation
  809. Revision 1.21 1998/03/06 01:09:01 peter
  810. * removed the conflicts that had occured
  811. Revision 1.20 1998/03/06 00:53:01 peter
  812. * replaced all old messages from errore.msg, only ExtDebug and some
  813. Comment() calls are left
  814. * fixed options.pas
  815. Revision 1.19 1998/03/05 22:40:56 florian
  816. + warning about missing constructor added
  817. Revision 1.18 1998/03/04 17:34:14 michael
  818. + Changed ifdef FPK to ifdef FPC
  819. Revision 1.17 1998/03/02 01:49:38 peter
  820. * renamed target_DOS to target_GO32V1
  821. + new verbose system, merged old errors and verbose units into one new
  822. verbose.pas, so errors.pas is obsolete
  823. Revision 1.16 1998/02/13 10:35:55 daniel
  824. * Made Motorola version compilable.
  825. * Fixed optimizer
  826. Revision 1.15 1998/02/12 17:19:33 florian
  827. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  828. also that aktswitches isn't a pointer)
  829. Revision 1.14 1998/02/12 11:50:52 daniel
  830. Yes! Finally! After three retries, my patch!
  831. Changes:
  832. Complete rewrite of psub.pas.
  833. Added support for DLL's.
  834. Compiler requires less memory.
  835. Platform units for each platform.
  836. Revision 1.13 1998/02/11 21:56:41 florian
  837. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  838. Revision 1.12 1998/02/07 23:05:08 florian
  839. * once more MMX
  840. Revision 1.11 1998/02/06 10:34:35 florian
  841. * bug0082 and bug0084 fixed
  842. Revision 1.10 1998/02/05 22:27:07 florian
  843. * small problems fixed: remake3 should now work
  844. Revision 1.9 1998/02/05 21:54:36 florian
  845. + more MMX
  846. Revision 1.8 1998/01/31 00:43:37 carl
  847. - removed in in is_subequal, because the code generator is buggy!
  848. (instead uses if...)
  849. Revision 1.7 1998/01/16 18:03:21 florian
  850. * small bug fixes, some stuff of delphi styled constructores added
  851. Revision 1.6 1998/01/11 19:24:35 carl
  852. + type checking routine (is_subequal) for case statements
  853. Revision 1.5 1998/01/09 23:08:38 florian
  854. + C++/Delphi styled //-comments
  855. * some bugs in Delphi object model fixed
  856. + override directive
  857. Revision 1.4 1998/01/09 16:08:24 florian
  858. * abstract methods call now abstracterrorproc if they are called
  859. a class with an abstract method can be create with a class reference else
  860. the compiler forbides this
  861. Revision 1.3 1998/01/07 00:17:12 michael
  862. Restored released version (plus fixes) as current
  863. Revision 1.2 1997/11/28 18:14:51 pierre
  864. working version with several bug fixes
  865. Revision 1.1.1.1 1997/11/27 08:33:03 michael
  866. FPC Compiler CVS start
  867. Pre-CVS log:
  868. CEC Carl-Eric Codere
  869. FK Florian Klaempfl
  870. PM Pierre Muller
  871. + feature added
  872. - removed
  873. * bug fixed or changed
  874. History:
  875. 22th september 1997
  876. + function dont_copy_const_param added (FK)
  877. 25th september 1997
  878. + is_open_array added (FK)
  879. + is_equal handles now also open arrays (FK)
  880. 2nd october 1997
  881. + added then boolean never_copy_const_param for use in typed write
  882. where we must push the reference anyway (PM)
  883. 3rd october 1997:
  884. + renamed ret_in_eax to ret_in_acc (for accumulator for port.) (CEC)
  885. - removed reference to i386 unit (CEC)
  886. 25th october 1997:
  887. * poassembler isn't important for compatiblity of proc vars (FK)
  888. 3rd november 1997:
  889. + added formaldef type to types where we dont_copy_const_param (PM)
  890. 20rd november 1997:
  891. + added is_fpu function (PM)
  892. }