tcmem.pas 26 KB

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