tcmem.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Type checking and register allocation for memory related nodes
  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 tcmem;
  19. interface
  20. uses
  21. tree;
  22. procedure firstloadvmt(var p : ptree);
  23. procedure firsthnew(var p : ptree);
  24. procedure firstnew(var p : ptree);
  25. procedure firsthdispose(var p : ptree);
  26. procedure firstsimplenewdispose(var p : ptree);
  27. procedure firstaddr(var p : ptree);
  28. procedure firstdoubleaddr(var p : ptree);
  29. procedure firstderef(var p : ptree);
  30. procedure firstsubscript(var p : ptree);
  31. procedure firstvec(var p : ptree);
  32. procedure firstself(var p : ptree);
  33. procedure firstwith(var p : ptree);
  34. implementation
  35. uses
  36. globtype,systems,
  37. cobjects,verbose,globals,
  38. symconst,symtable,aasm,types,
  39. hcodegen,htypechk,pass_1,cpubase;
  40. {*****************************************************************************
  41. FirstLoadVMT
  42. *****************************************************************************}
  43. procedure firstloadvmt(var p : ptree);
  44. begin
  45. p^.registers32:=1;
  46. p^.location.loc:=LOC_REGISTER;
  47. end;
  48. {*****************************************************************************
  49. FirstHNew
  50. *****************************************************************************}
  51. procedure firsthnew(var p : ptree);
  52. begin
  53. end;
  54. {*****************************************************************************
  55. FirstNewN
  56. *****************************************************************************}
  57. procedure firstnew(var p : ptree);
  58. begin
  59. { Standardeinleitung }
  60. if assigned(p^.left) then
  61. firstpass(p^.left);
  62. if codegenerror then
  63. exit;
  64. if assigned(p^.left) then
  65. begin
  66. p^.registers32:=p^.left^.registers32;
  67. p^.registersfpu:=p^.left^.registersfpu;
  68. {$ifdef SUPPORT_MMX}
  69. p^.registersmmx:=p^.left^.registersmmx;
  70. {$endif SUPPORT_MMX}
  71. end;
  72. { result type is already set }
  73. procinfo.flags:=procinfo.flags or pi_do_call;
  74. if assigned(p^.left) then
  75. p^.location.loc:=LOC_REGISTER
  76. else
  77. p^.location.loc:=LOC_REFERENCE;
  78. end;
  79. {*****************************************************************************
  80. FirstDispose
  81. *****************************************************************************}
  82. procedure firsthdispose(var p : ptree);
  83. begin
  84. firstpass(p^.left);
  85. if codegenerror then
  86. exit;
  87. p^.registers32:=p^.left^.registers32;
  88. p^.registersfpu:=p^.left^.registersfpu;
  89. {$ifdef SUPPORT_MMX}
  90. p^.registersmmx:=p^.left^.registersmmx;
  91. {$endif SUPPORT_MMX}
  92. if p^.registers32<1 then
  93. p^.registers32:=1;
  94. {
  95. if p^.left^.location.loc<>LOC_REFERENCE then
  96. CGMessage(cg_e_illegal_expression);
  97. }
  98. p^.location.loc:=LOC_REFERENCE;
  99. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  100. end;
  101. {*****************************************************************************
  102. FirstSimpleNewDispose
  103. *****************************************************************************}
  104. procedure firstsimplenewdispose(var p : ptree);
  105. begin
  106. { this cannot be in a register !! }
  107. make_not_regable(p^.left);
  108. firstpass(p^.left);
  109. if codegenerror then
  110. exit;
  111. { check the type }
  112. if (p^.left^.resulttype=nil) or (p^.left^.resulttype^.deftype<>pointerdef) then
  113. CGMessage(type_e_pointer_type_expected);
  114. if (p^.left^.location.loc<>LOC_REFERENCE) {and
  115. (p^.left^.location.loc<>LOC_CREGISTER)} then
  116. CGMessage(cg_e_illegal_expression);
  117. p^.registers32:=p^.left^.registers32;
  118. p^.registersfpu:=p^.left^.registersfpu;
  119. {$ifdef SUPPORT_MMX}
  120. p^.registersmmx:=p^.left^.registersmmx;
  121. {$endif SUPPORT_MMX}
  122. p^.resulttype:=voiddef;
  123. procinfo.flags:=procinfo.flags or pi_do_call;
  124. end;
  125. {*****************************************************************************
  126. FirstAddr
  127. *****************************************************************************}
  128. procedure firstaddr(var p : ptree);
  129. var
  130. hp : ptree;
  131. hp2 : pdefcoll;
  132. store_valid : boolean;
  133. hp3 : pabstractprocdef;
  134. begin
  135. make_not_regable(p^.left);
  136. if not(assigned(p^.resulttype)) then
  137. begin
  138. { proc/procvar 2 procvar ? }
  139. if p^.left^.treetype=calln then
  140. begin
  141. { is it a procvar, this is needed for @procvar in tp mode ! }
  142. if assigned(p^.left^.right) then
  143. begin
  144. { just return the load of the procvar, remove the
  145. addrn and calln nodes }
  146. hp:=p^.left^.right;
  147. putnode(p^.left);
  148. putnode(p);
  149. firstpass(hp);
  150. p:=hp;
  151. exit;
  152. end
  153. else
  154. begin
  155. { generate a methodcallnode or proccallnode }
  156. if (p^.left^.symtableprocentry^.owner^.symtabletype=objectsymtable) and
  157. (pobjectdef(p^.left^.symtableprocentry^.owner^.defowner)^.is_class) then
  158. begin
  159. hp:=genloadmethodcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc,
  160. getcopy(p^.left^.methodpointer));
  161. disposetree(p);
  162. firstpass(hp);
  163. p:=hp;
  164. exit;
  165. end
  166. else
  167. hp:=genloadcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc);
  168. end;
  169. { result is a procedure variable }
  170. { No, to be TP compatible, you must return a pointer to
  171. the procedure that is stored in the procvar.}
  172. if not(m_tp_procvar in aktmodeswitches) then
  173. begin
  174. p^.resulttype:=new(pprocvardef,init);
  175. { it could also be a procvar, not only pprocsym ! }
  176. if p^.left^.symtableprocentry^.typ=varsym then
  177. hp3:=pabstractprocdef(pvarsym(p^.left^.symtableentry)^.definition)
  178. else
  179. hp3:=pabstractprocdef(pprocsym(p^.left^.symtableprocentry)^.definition);
  180. pprocvardef(p^.resulttype)^.proctypeoption:=hp3^.proctypeoption;
  181. pprocvardef(p^.resulttype)^.proccalloptions:=hp3^.proccalloptions;
  182. pprocvardef(p^.resulttype)^.procoptions:=hp3^.procoptions;
  183. pprocvardef(p^.resulttype)^.retdef:=hp3^.retdef;
  184. { method ? then set the methodpointer flag }
  185. if (hp3^.owner^.symtabletype=objectsymtable) and
  186. (pobjectdef(hp3^.owner^.defowner)^.is_class) then
  187. {$ifdef INCLUDEOK}
  188. include(pprocvardef(p^.resulttype)^.procoptions,po_methodpointer);
  189. {$else}
  190. pprocvardef(p^.resulttype)^.procoptions:=pprocvardef(p^.resulttype)^.procoptions+[po_methodpointer];
  191. {$endif}
  192. hp2:=hp3^.para1;
  193. while assigned(hp2) do
  194. begin
  195. pprocvardef(p^.resulttype)^.concatdef(hp2^.data,hp2^.paratyp);
  196. hp2:=hp2^.next;
  197. end;
  198. end
  199. else
  200. p^.resulttype:=voidpointerdef;
  201. disposetree(p^.left);
  202. p^.left:=hp;
  203. end
  204. else
  205. begin
  206. { what are we getting the address from an absolute sym? }
  207. hp:=p^.left;
  208. while assigned(hp) and (hp^.treetype in [vecn,subscriptn]) do
  209. hp:=hp^.left;
  210. if assigned(hp) and (hp^.treetype=loadn) and
  211. ((hp^.symtableentry^.typ=absolutesym) and
  212. pabsolutesym(hp^.symtableentry)^.absseg) then
  213. begin
  214. if not(cs_typed_addresses in aktlocalswitches) then
  215. p^.resulttype:=voidfarpointerdef
  216. else
  217. p^.resulttype:=new(ppointerdef,initfar(p^.left^.resulttype));
  218. end
  219. else
  220. begin
  221. if not(cs_typed_addresses in aktlocalswitches) then
  222. p^.resulttype:=voidpointerdef
  223. else
  224. p^.resulttype:=new(ppointerdef,init(p^.left^.resulttype));
  225. end;
  226. end;
  227. end;
  228. store_valid:=must_be_valid;
  229. must_be_valid:=false;
  230. firstpass(p^.left);
  231. must_be_valid:=store_valid;
  232. if codegenerror then
  233. exit;
  234. { don't allow constants }
  235. if is_constnode(p^.left) then
  236. begin
  237. aktfilepos:=p^.left^.fileinfo;
  238. CGMessage(type_e_no_addr_of_constant);
  239. end
  240. else
  241. begin
  242. { we should allow loc_mem for @string }
  243. if not(p^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) then
  244. begin
  245. aktfilepos:=p^.left^.fileinfo;
  246. CGMessage(cg_e_illegal_expression);
  247. end;
  248. end;
  249. p^.registers32:=p^.left^.registers32;
  250. p^.registersfpu:=p^.left^.registersfpu;
  251. {$ifdef SUPPORT_MMX}
  252. p^.registersmmx:=p^.left^.registersmmx;
  253. {$endif SUPPORT_MMX}
  254. if p^.registers32<1 then
  255. p^.registers32:=1;
  256. p^.location.loc:=LOC_REGISTER;
  257. end;
  258. {*****************************************************************************
  259. FirstDoubleAddr
  260. *****************************************************************************}
  261. procedure firstdoubleaddr(var p : ptree);
  262. begin
  263. make_not_regable(p^.left);
  264. firstpass(p^.left);
  265. if p^.resulttype=nil then
  266. p^.resulttype:=voidpointerdef;
  267. if codegenerror then
  268. exit;
  269. if (p^.left^.resulttype^.deftype)<>procvardef then
  270. CGMessage(cg_e_illegal_expression);
  271. if (p^.left^.location.loc<>LOC_REFERENCE) then
  272. CGMessage(cg_e_illegal_expression);
  273. p^.registers32:=p^.left^.registers32;
  274. p^.registersfpu:=p^.left^.registersfpu;
  275. {$ifdef SUPPORT_MMX}
  276. p^.registersmmx:=p^.left^.registersmmx;
  277. {$endif SUPPORT_MMX}
  278. if p^.registers32<1 then
  279. p^.registers32:=1;
  280. p^.location.loc:=LOC_REGISTER;
  281. end;
  282. {*****************************************************************************
  283. FirstDeRef
  284. *****************************************************************************}
  285. procedure firstderef(var p : ptree);
  286. begin
  287. firstpass(p^.left);
  288. if codegenerror then
  289. begin
  290. p^.resulttype:=generrordef;
  291. exit;
  292. end;
  293. p^.registers32:=max(p^.left^.registers32,1);
  294. p^.registersfpu:=p^.left^.registersfpu;
  295. {$ifdef SUPPORT_MMX}
  296. p^.registersmmx:=p^.left^.registersmmx;
  297. {$endif SUPPORT_MMX}
  298. if p^.left^.resulttype^.deftype<>pointerdef then
  299. CGMessage(cg_e_invalid_qualifier);
  300. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  301. p^.location.loc:=LOC_REFERENCE;
  302. end;
  303. {*****************************************************************************
  304. FirstSubScript
  305. *****************************************************************************}
  306. procedure firstsubscript(var p : ptree);
  307. begin
  308. firstpass(p^.left);
  309. if codegenerror then
  310. begin
  311. p^.resulttype:=generrordef;
  312. exit;
  313. end;
  314. p^.resulttype:=p^.vs^.definition;
  315. { this must be done in the parser
  316. if count_ref and not must_be_valid then
  317. if (p^.vs^.properties and sp_protected)<>0 then
  318. CGMessage(parser_e_cant_write_protected_member);
  319. }
  320. p^.registers32:=p^.left^.registers32;
  321. p^.registersfpu:=p^.left^.registersfpu;
  322. {$ifdef SUPPORT_MMX}
  323. p^.registersmmx:=p^.left^.registersmmx;
  324. {$endif SUPPORT_MMX}
  325. { classes must be dereferenced implicit }
  326. if (p^.left^.resulttype^.deftype=objectdef) and
  327. pobjectdef(p^.left^.resulttype)^.is_class then
  328. begin
  329. if p^.registers32=0 then
  330. p^.registers32:=1;
  331. p^.location.loc:=LOC_REFERENCE;
  332. end
  333. else
  334. begin
  335. if (p^.left^.location.loc<>LOC_MEM) and
  336. (p^.left^.location.loc<>LOC_REFERENCE) then
  337. CGMessage(cg_e_illegal_expression);
  338. set_location(p^.location,p^.left^.location);
  339. end;
  340. end;
  341. {*****************************************************************************
  342. FirstVec
  343. *****************************************************************************}
  344. procedure firstvec(var p : ptree);
  345. var
  346. harr : pdef;
  347. ct : tconverttype;
  348. {$ifdef consteval}
  349. tcsym : ptypedconstsym;
  350. {$endif}
  351. begin
  352. firstpass(p^.left);
  353. firstpass(p^.right);
  354. if codegenerror then
  355. exit;
  356. { range check only for arrays }
  357. if (p^.left^.resulttype^.deftype=arraydef) then
  358. begin
  359. if (isconvertable(p^.right^.resulttype,parraydef(p^.left^.resulttype)^.rangedef,
  360. ct,ordconstn,false)=0) and
  361. not(is_equal(p^.right^.resulttype,parraydef(p^.left^.resulttype)^.rangedef)) then
  362. CGMessage(type_e_mismatch);
  363. end;
  364. { Never convert a boolean or a char !}
  365. { maybe type conversion }
  366. if (p^.right^.resulttype^.deftype<>enumdef) and
  367. not(is_char(p^.right^.resulttype)) and
  368. not(is_boolean(p^.right^.resulttype)) then
  369. begin
  370. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  371. firstpass(p^.right);
  372. if codegenerror then
  373. exit;
  374. end;
  375. { determine return type }
  376. if not assigned(p^.resulttype) then
  377. if p^.left^.resulttype^.deftype=arraydef then
  378. p^.resulttype:=parraydef(p^.left^.resulttype)^.definition
  379. else if (p^.left^.resulttype^.deftype=pointerdef) then
  380. begin
  381. { convert pointer to array }
  382. harr:=new(parraydef,init(0,$7fffffff,s32bitdef));
  383. parraydef(harr)^.definition:=ppointerdef(p^.left^.resulttype)^.definition;
  384. p^.left:=gentypeconvnode(p^.left,harr);
  385. firstpass(p^.left);
  386. if codegenerror then
  387. exit;
  388. p^.resulttype:=parraydef(harr)^.definition
  389. end
  390. else if p^.left^.resulttype^.deftype=stringdef then
  391. begin
  392. { indexed access to strings }
  393. case pstringdef(p^.left^.resulttype)^.string_typ of
  394. {
  395. st_widestring : p^.resulttype:=cwchardef;
  396. }
  397. st_ansistring : p^.resulttype:=cchardef;
  398. st_longstring : p^.resulttype:=cchardef;
  399. st_shortstring : p^.resulttype:=cchardef;
  400. end;
  401. end
  402. else
  403. CGMessage(type_e_mismatch);
  404. { the register calculation is easy if a const index is used }
  405. if p^.right^.treetype=ordconstn then
  406. begin
  407. {$ifdef consteval}
  408. { constant evaluation }
  409. if (p^.left^.treetype=loadn) and
  410. (p^.left^.symtableentry^.typ=typedconstsym) then
  411. begin
  412. tcsym:=ptypedconstsym(p^.left^.symtableentry);
  413. if tcsym^.defintion^.typ=stringdef then
  414. begin
  415. end;
  416. end;
  417. {$endif}
  418. p^.registers32:=p^.left^.registers32;
  419. { for ansi/wide strings, we need at least one register }
  420. if is_ansistring(p^.left^.resulttype) or
  421. is_widestring(p^.left^.resulttype) then
  422. p^.registers32:=max(p^.registers32,1);
  423. end
  424. else
  425. begin
  426. { this rules are suboptimal, but they should give }
  427. { good results }
  428. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  429. { for ansi/wide strings, we need at least one register }
  430. if is_ansistring(p^.left^.resulttype) or
  431. is_widestring(p^.left^.resulttype) then
  432. p^.registers32:=max(p^.registers32,1);
  433. { need we an extra register when doing the restore ? }
  434. if (p^.left^.registers32<=p^.right^.registers32) and
  435. { only if the node needs less than 3 registers }
  436. { two for the right node and one for the }
  437. { left address }
  438. (p^.registers32<3) then
  439. inc(p^.registers32);
  440. { need we an extra register for the index ? }
  441. if (p^.right^.location.loc<>LOC_REGISTER)
  442. { only if the right node doesn't need a register }
  443. and (p^.right^.registers32<1) then
  444. inc(p^.registers32);
  445. { not correct, but what works better ?
  446. if p^.left^.registers32>0 then
  447. p^.registers32:=max(p^.registers32,2)
  448. else
  449. min. one register
  450. p^.registers32:=max(p^.registers32,1);
  451. }
  452. end;
  453. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  454. {$ifdef SUPPORT_MMX}
  455. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  456. {$endif SUPPORT_MMX}
  457. if p^.left^.location.loc in [LOC_CREGISTER,LOC_REFERENCE] then
  458. p^.location.loc:=LOC_REFERENCE
  459. else
  460. p^.location.loc:=LOC_MEM;
  461. end;
  462. {*****************************************************************************
  463. FirstSelf
  464. *****************************************************************************}
  465. procedure firstself(var p : ptree);
  466. begin
  467. if (p^.resulttype^.deftype=classrefdef) or
  468. ((p^.resulttype^.deftype=objectdef)
  469. and pobjectdef(p^.resulttype)^.is_class
  470. ) then
  471. p^.location.loc:=LOC_CREGISTER
  472. else
  473. p^.location.loc:=LOC_REFERENCE;
  474. end;
  475. {*****************************************************************************
  476. FirstWithN
  477. *****************************************************************************}
  478. procedure firstwith(var p : ptree);
  479. var
  480. symtable : pwithsymtable;
  481. i : longint;
  482. begin
  483. if assigned(p^.left) and assigned(p^.right) then
  484. begin
  485. firstpass(p^.left);
  486. if codegenerror then
  487. exit;
  488. symtable:=p^.withsymtable;
  489. for i:=1 to p^.tablecount do
  490. begin
  491. if (p^.left^.treetype=loadn) and
  492. (p^.left^.symtable=aktprocsym^.definition^.localst) then
  493. symtable^.direct_with:=true;
  494. symtable^.withnode:=p;
  495. symtable:=pwithsymtable(symtable^.next);
  496. end;
  497. firstpass(p^.right);
  498. if codegenerror then
  499. exit;
  500. left_right_max(p);
  501. p^.resulttype:=voiddef;
  502. end
  503. else
  504. begin
  505. { optimization }
  506. disposetree(p);
  507. p:=nil;
  508. end;
  509. end;
  510. end.
  511. {
  512. $Log$
  513. Revision 1.23 1999-08-04 00:23:44 florian
  514. * renamed i386asm and i386base to cpuasm and cpubase
  515. Revision 1.22 1999/08/03 22:03:35 peter
  516. * moved bitmask constants to sets
  517. * some other type/const renamings
  518. Revision 1.21 1999/07/16 10:04:39 peter
  519. * merged
  520. Revision 1.20 1999/07/05 20:25:41 peter
  521. * merged
  522. Revision 1.19 1999/07/05 16:24:17 peter
  523. * merged
  524. Revision 1.18.2.4 1999/07/16 09:54:59 peter
  525. * @procvar support in tp7 mode works again
  526. Revision 1.18.2.3 1999/07/05 20:06:47 peter
  527. * give error instead of warning for ln(0) and sqrt(0)
  528. Revision 1.18.2.2 1999/07/05 16:22:56 peter
  529. * error if @constant
  530. Revision 1.18.2.1 1999/06/28 00:33:53 pierre
  531. * better error position bug0269
  532. Revision 1.18 1999/06/03 09:34:12 peter
  533. * better methodpointer check for proc->procvar
  534. Revision 1.17 1999/05/27 19:45:24 peter
  535. * removed oldasm
  536. * plabel -> pasmlabel
  537. * -a switches to source writing automaticly
  538. * assembler readers OOPed
  539. * asmsymbol automaticly external
  540. * jumptables and other label fixes for asm readers
  541. Revision 1.16 1999/05/18 09:52:21 peter
  542. * procedure of object and addrn fixes
  543. Revision 1.15 1999/05/17 23:51:46 peter
  544. * with temp vars now use a reference with a persistant temp instead
  545. of setting datasize
  546. Revision 1.14 1999/05/01 13:24:57 peter
  547. * merged nasm compiler
  548. * old asm moved to oldasm/
  549. Revision 1.13 1999/04/26 18:30:05 peter
  550. * farpointerdef moved into pointerdef.is_far
  551. Revision 1.12 1999/03/02 18:24:24 peter
  552. * fixed overloading of array of char
  553. Revision 1.11 1999/02/22 02:15:54 peter
  554. * updates for ag386bin
  555. Revision 1.10 1999/02/04 11:44:47 florian
  556. * fixed indexed access of ansistrings to temp. ansistring, i.e.
  557. c:=(s1+s2)[i], the temp is now correctly remove and the generated
  558. code is also fixed
  559. Revision 1.9 1999/01/22 12:18:34 pierre
  560. * with bug introduced with DIRECTWITH removed
  561. Revision 1.8 1999/01/21 16:41:08 pierre
  562. * fix for constructor inside with statements
  563. Revision 1.7 1998/12/30 22:15:59 peter
  564. + farpointer type
  565. * absolutesym now also stores if its far
  566. Revision 1.6 1998/12/15 17:16:02 peter
  567. * fixed const s : ^string
  568. * first things for const pchar : @string[1]
  569. Revision 1.5 1998/12/11 00:03:57 peter
  570. + globtype,tokens,version unit splitted from globals
  571. Revision 1.4 1998/11/25 19:12:53 pierre
  572. * var:=new(pointer_type) support added
  573. Revision 1.3 1998/09/26 15:03:05 florian
  574. * small problems with DOM and excpetions fixed (code generation
  575. of raise was wrong and self was sometimes destroyed :()
  576. Revision 1.2 1998/09/24 23:49:24 peter
  577. + aktmodeswitches
  578. Revision 1.1 1998/09/23 20:42:24 peter
  579. * splitted pass_1
  580. }