types.pas 41 KB

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