types.pas 37 KB

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