tcmem.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  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 : pparaitem;
  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. subscriptn,
  166. typeconvn,
  167. vecn,
  168. derefn :
  169. begin
  170. firstpass(hp);
  171. if codegenerror then
  172. exit;
  173. if hp^.resulttype^.deftype=procvardef then
  174. begin
  175. p^.procvarload:=true;
  176. end;
  177. end;
  178. end;
  179. end;
  180. if p^.procvarload then
  181. begin
  182. p^.registers32:=p^.left^.registers32;
  183. p^.registersfpu:=p^.left^.registersfpu;
  184. {$ifdef SUPPORT_MMX}
  185. p^.registersmmx:=p^.left^.registersmmx;
  186. {$endif SUPPORT_MMX}
  187. if p^.registers32<1 then
  188. p^.registers32:=1;
  189. p^.location.loc:=p^.left^.location.loc;
  190. p^.resulttype:=voidpointerdef;
  191. exit;
  192. end;
  193. { proc 2 procvar ? }
  194. if p^.left^.treetype=calln then
  195. begin
  196. { generate a methodcallnode or proccallnode }
  197. { we shouldn't convert things like @tcollection.load }
  198. if (p^.left^.symtableprocentry^.owner^.symtabletype=objectsymtable) and
  199. not(assigned(p^.left^.methodpointer) and (p^.left^.methodpointer^.treetype=typen)) then
  200. begin
  201. hp:=genloadmethodcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc,
  202. getcopy(p^.left^.methodpointer));
  203. disposetree(p);
  204. firstpass(hp);
  205. p:=hp;
  206. exit;
  207. end
  208. else
  209. hp:=genloadcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc);
  210. { result is a procedure variable }
  211. { No, to be TP compatible, you must return a pointer to
  212. the procedure that is stored in the procvar.}
  213. if not(m_tp_procvar in aktmodeswitches) then
  214. begin
  215. p^.resulttype:=new(pprocvardef,init);
  216. { it could also be a procvar, not only pprocsym ! }
  217. if p^.left^.symtableprocentry^.typ=varsym then
  218. hp3:=pabstractprocdef(pvarsym(p^.left^.symtableentry)^.definition)
  219. else
  220. hp3:=pabstractprocdef(pprocsym(p^.left^.symtableprocentry)^.definition);
  221. pprocvardef(p^.resulttype)^.proctypeoption:=hp3^.proctypeoption;
  222. pprocvardef(p^.resulttype)^.proccalloptions:=hp3^.proccalloptions;
  223. pprocvardef(p^.resulttype)^.procoptions:=hp3^.procoptions;
  224. pprocvardef(p^.resulttype)^.retdef:=hp3^.retdef;
  225. pprocvardef(p^.resulttype)^.symtablelevel:=hp3^.symtablelevel;
  226. { method ? then set the methodpointer flag }
  227. if (hp3^.owner^.symtabletype=objectsymtable) and
  228. (pobjectdef(hp3^.owner^.defowner)^.is_class) then
  229. {$ifdef INCLUDEOK}
  230. include(pprocvardef(p^.resulttype)^.procoptions,po_methodpointer);
  231. {$else}
  232. pprocvardef(p^.resulttype)^.procoptions:=pprocvardef(p^.resulttype)^.procoptions+[po_methodpointer];
  233. {$endif}
  234. { we need to process the parameters reverse so they are inserted
  235. in the correct right2left order (PFV) }
  236. hp2:=pparaitem(hp3^.para^.last);
  237. while assigned(hp2) do
  238. begin
  239. pprocvardef(p^.resulttype)^.concatdef(hp2^.data,hp2^.paratyp);
  240. hp2:=pparaitem(hp2^.previous);
  241. end;
  242. end
  243. else
  244. p^.resulttype:=voidpointerdef;
  245. disposetree(p^.left);
  246. p^.left:=hp;
  247. end
  248. else
  249. begin
  250. { what are we getting the address from an absolute sym? }
  251. hp:=p^.left;
  252. while assigned(hp) and (hp^.treetype in [vecn,derefn,subscriptn]) do
  253. hp:=hp^.left;
  254. if assigned(hp) and (hp^.treetype=loadn) and
  255. ((hp^.symtableentry^.typ=absolutesym) and
  256. pabsolutesym(hp^.symtableentry)^.absseg) then
  257. begin
  258. if not(cs_typed_addresses in aktlocalswitches) then
  259. p^.resulttype:=voidfarpointerdef
  260. else
  261. p^.resulttype:=new(ppointerdef,initfar(p^.left^.resulttype));
  262. end
  263. else
  264. begin
  265. if not(cs_typed_addresses in aktlocalswitches) then
  266. p^.resulttype:=voidpointerdef
  267. else
  268. p^.resulttype:=new(ppointerdef,init(p^.left^.resulttype));
  269. end;
  270. end;
  271. end;
  272. store_valid:=must_be_valid;
  273. must_be_valid:=false;
  274. firstpass(p^.left);
  275. must_be_valid:=store_valid;
  276. if codegenerror then
  277. exit;
  278. { don't allow constants }
  279. if is_constnode(p^.left) then
  280. begin
  281. aktfilepos:=p^.left^.fileinfo;
  282. CGMessage(type_e_no_addr_of_constant);
  283. end
  284. else
  285. begin
  286. { we should allow loc_mem for @string }
  287. if not(p^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) then
  288. begin
  289. aktfilepos:=p^.left^.fileinfo;
  290. CGMessage(cg_e_illegal_expression);
  291. end;
  292. end;
  293. p^.registers32:=p^.left^.registers32;
  294. p^.registersfpu:=p^.left^.registersfpu;
  295. {$ifdef SUPPORT_MMX}
  296. p^.registersmmx:=p^.left^.registersmmx;
  297. {$endif SUPPORT_MMX}
  298. if p^.registers32<1 then
  299. p^.registers32:=1;
  300. p^.location.loc:=LOC_REGISTER;
  301. end;
  302. {*****************************************************************************
  303. FirstDoubleAddr
  304. *****************************************************************************}
  305. procedure firstdoubleaddr(var p : ptree);
  306. begin
  307. make_not_regable(p^.left);
  308. firstpass(p^.left);
  309. if p^.resulttype=nil then
  310. p^.resulttype:=voidpointerdef;
  311. if codegenerror then
  312. exit;
  313. if (p^.left^.resulttype^.deftype)<>procvardef then
  314. CGMessage(cg_e_illegal_expression);
  315. if (p^.left^.location.loc<>LOC_REFERENCE) then
  316. CGMessage(cg_e_illegal_expression);
  317. p^.registers32:=p^.left^.registers32;
  318. p^.registersfpu:=p^.left^.registersfpu;
  319. {$ifdef SUPPORT_MMX}
  320. p^.registersmmx:=p^.left^.registersmmx;
  321. {$endif SUPPORT_MMX}
  322. if p^.registers32<1 then
  323. p^.registers32:=1;
  324. p^.location.loc:=LOC_REGISTER;
  325. end;
  326. {*****************************************************************************
  327. FirstDeRef
  328. *****************************************************************************}
  329. procedure firstderef(var p : ptree);
  330. begin
  331. firstpass(p^.left);
  332. if codegenerror then
  333. begin
  334. p^.resulttype:=generrordef;
  335. exit;
  336. end;
  337. p^.registers32:=max(p^.left^.registers32,1);
  338. p^.registersfpu:=p^.left^.registersfpu;
  339. {$ifdef SUPPORT_MMX}
  340. p^.registersmmx:=p^.left^.registersmmx;
  341. {$endif SUPPORT_MMX}
  342. if p^.left^.resulttype^.deftype<>pointerdef then
  343. CGMessage(cg_e_invalid_qualifier);
  344. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  345. p^.location.loc:=LOC_REFERENCE;
  346. end;
  347. {*****************************************************************************
  348. FirstSubScript
  349. *****************************************************************************}
  350. procedure firstsubscript(var p : ptree);
  351. begin
  352. firstpass(p^.left);
  353. if codegenerror then
  354. begin
  355. p^.resulttype:=generrordef;
  356. exit;
  357. end;
  358. p^.resulttype:=p^.vs^.definition;
  359. p^.registers32:=p^.left^.registers32;
  360. p^.registersfpu:=p^.left^.registersfpu;
  361. {$ifdef SUPPORT_MMX}
  362. p^.registersmmx:=p^.left^.registersmmx;
  363. {$endif SUPPORT_MMX}
  364. { classes must be dereferenced implicit }
  365. if (p^.left^.resulttype^.deftype=objectdef) and
  366. pobjectdef(p^.left^.resulttype)^.is_class then
  367. begin
  368. if p^.registers32=0 then
  369. p^.registers32:=1;
  370. p^.location.loc:=LOC_REFERENCE;
  371. end
  372. else
  373. begin
  374. if (p^.left^.location.loc<>LOC_MEM) and
  375. (p^.left^.location.loc<>LOC_REFERENCE) then
  376. CGMessage(cg_e_illegal_expression);
  377. set_location(p^.location,p^.left^.location);
  378. end;
  379. end;
  380. {*****************************************************************************
  381. FirstVec
  382. *****************************************************************************}
  383. procedure firstvec(var p : ptree);
  384. var
  385. harr : pdef;
  386. ct : tconverttype;
  387. {$ifdef consteval}
  388. tcsym : ptypedconstsym;
  389. {$endif}
  390. begin
  391. firstpass(p^.left);
  392. firstpass(p^.right);
  393. if codegenerror then
  394. exit;
  395. { range check only for arrays }
  396. if (p^.left^.resulttype^.deftype=arraydef) then
  397. begin
  398. if (isconvertable(p^.right^.resulttype,parraydef(p^.left^.resulttype)^.rangedef,
  399. ct,ordconstn,false)=0) and
  400. not(is_equal(p^.right^.resulttype,parraydef(p^.left^.resulttype)^.rangedef)) then
  401. CGMessage(type_e_mismatch);
  402. end;
  403. { Never convert a boolean or a char !}
  404. { maybe type conversion }
  405. if (p^.right^.resulttype^.deftype<>enumdef) and
  406. not(is_char(p^.right^.resulttype)) and
  407. not(is_boolean(p^.right^.resulttype)) then
  408. begin
  409. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  410. firstpass(p^.right);
  411. if codegenerror then
  412. exit;
  413. end;
  414. { determine return type }
  415. if not assigned(p^.resulttype) then
  416. if p^.left^.resulttype^.deftype=arraydef then
  417. p^.resulttype:=parraydef(p^.left^.resulttype)^.definition
  418. else if (p^.left^.resulttype^.deftype=pointerdef) then
  419. begin
  420. { convert pointer to array }
  421. harr:=new(parraydef,init(0,$7fffffff,s32bitdef));
  422. parraydef(harr)^.definition:=ppointerdef(p^.left^.resulttype)^.definition;
  423. p^.left:=gentypeconvnode(p^.left,harr);
  424. firstpass(p^.left);
  425. if codegenerror then
  426. exit;
  427. p^.resulttype:=parraydef(harr)^.definition
  428. end
  429. else if p^.left^.resulttype^.deftype=stringdef then
  430. begin
  431. { indexed access to strings }
  432. case pstringdef(p^.left^.resulttype)^.string_typ of
  433. {
  434. st_widestring : p^.resulttype:=cwchardef;
  435. }
  436. st_ansistring : p^.resulttype:=cchardef;
  437. st_longstring : p^.resulttype:=cchardef;
  438. st_shortstring : p^.resulttype:=cchardef;
  439. end;
  440. end
  441. else
  442. CGMessage(type_e_mismatch);
  443. { the register calculation is easy if a const index is used }
  444. if p^.right^.treetype=ordconstn then
  445. begin
  446. {$ifdef consteval}
  447. { constant evaluation }
  448. if (p^.left^.treetype=loadn) and
  449. (p^.left^.symtableentry^.typ=typedconstsym) then
  450. begin
  451. tcsym:=ptypedconstsym(p^.left^.symtableentry);
  452. if tcsym^.defintion^.typ=stringdef then
  453. begin
  454. end;
  455. end;
  456. {$endif}
  457. p^.registers32:=p^.left^.registers32;
  458. { for ansi/wide strings, we need at least one register }
  459. if is_ansistring(p^.left^.resulttype) or
  460. is_widestring(p^.left^.resulttype) then
  461. p^.registers32:=max(p^.registers32,1);
  462. end
  463. else
  464. begin
  465. { this rules are suboptimal, but they should give }
  466. { good results }
  467. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  468. { for ansi/wide strings, we need at least one register }
  469. if is_ansistring(p^.left^.resulttype) or
  470. is_widestring(p^.left^.resulttype) then
  471. p^.registers32:=max(p^.registers32,1);
  472. { need we an extra register when doing the restore ? }
  473. if (p^.left^.registers32<=p^.right^.registers32) and
  474. { only if the node needs less than 3 registers }
  475. { two for the right node and one for the }
  476. { left address }
  477. (p^.registers32<3) then
  478. inc(p^.registers32);
  479. { need we an extra register for the index ? }
  480. if (p^.right^.location.loc<>LOC_REGISTER)
  481. { only if the right node doesn't need a register }
  482. and (p^.right^.registers32<1) then
  483. inc(p^.registers32);
  484. { not correct, but what works better ?
  485. if p^.left^.registers32>0 then
  486. p^.registers32:=max(p^.registers32,2)
  487. else
  488. min. one register
  489. p^.registers32:=max(p^.registers32,1);
  490. }
  491. end;
  492. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  493. {$ifdef SUPPORT_MMX}
  494. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  495. {$endif SUPPORT_MMX}
  496. if p^.left^.location.loc in [LOC_CREGISTER,LOC_REFERENCE] then
  497. p^.location.loc:=LOC_REFERENCE
  498. else
  499. p^.location.loc:=LOC_MEM;
  500. end;
  501. {*****************************************************************************
  502. FirstSelf
  503. *****************************************************************************}
  504. procedure firstself(var p : ptree);
  505. begin
  506. if (p^.resulttype^.deftype=classrefdef) or
  507. ((p^.resulttype^.deftype=objectdef)
  508. and pobjectdef(p^.resulttype)^.is_class
  509. ) then
  510. p^.location.loc:=LOC_CREGISTER
  511. else
  512. p^.location.loc:=LOC_REFERENCE;
  513. end;
  514. {*****************************************************************************
  515. FirstWithN
  516. *****************************************************************************}
  517. procedure firstwith(var p : ptree);
  518. var
  519. symtable : pwithsymtable;
  520. i : longint;
  521. begin
  522. if assigned(p^.left) and assigned(p^.right) then
  523. begin
  524. firstpass(p^.left);
  525. if codegenerror then
  526. exit;
  527. symtable:=p^.withsymtable;
  528. for i:=1 to p^.tablecount do
  529. begin
  530. if (p^.left^.treetype=loadn) and
  531. (p^.left^.symtable=aktprocsym^.definition^.localst) then
  532. symtable^.direct_with:=true;
  533. symtable^.withnode:=p;
  534. symtable:=pwithsymtable(symtable^.next);
  535. end;
  536. firstpass(p^.right);
  537. if codegenerror then
  538. exit;
  539. left_right_max(p);
  540. p^.resulttype:=voiddef;
  541. end
  542. else
  543. begin
  544. { optimization }
  545. disposetree(p);
  546. p:=nil;
  547. end;
  548. end;
  549. end.
  550. {
  551. $Log$
  552. Revision 1.32 1999-11-06 14:34:30 peter
  553. * truncated log to 20 revs
  554. Revision 1.31 1999/10/26 12:30:46 peter
  555. * const parameter is now checked
  556. * better and generic check if a node can be used for assigning
  557. * export fixes
  558. * procvar equal works now (it never had worked at least from 0.99.8)
  559. * defcoll changed to linkedlist with pparaitem so it can easily be
  560. walked both directions
  561. Revision 1.30 1999/10/13 10:40:55 peter
  562. * subscript support for tp_procvar
  563. Revision 1.29 1999/09/27 23:45:02 peter
  564. * procinfo is now a pointer
  565. * support for result setting in sub procedure
  566. Revision 1.28 1999/09/17 17:14:12 peter
  567. * @procvar fixes for tp mode
  568. * @<id>:= gives now an error
  569. Revision 1.27 1999/09/11 11:10:39 florian
  570. * fix of my previous commit, make cycle was broken
  571. Revision 1.26 1999/09/11 09:08:34 florian
  572. * fixed bug 596
  573. * fixed some problems with procedure variables and procedures of object,
  574. especially in TP mode. Procedure of object doesn't apply only to classes,
  575. it is also allowed for objects !!
  576. Revision 1.25 1999/08/23 23:34:15 pierre
  577. * one more register needed if hnewn with CREGISTER
  578. Revision 1.24 1999/08/05 16:53:25 peter
  579. * V_Fatal=1, all other V_ are also increased
  580. * Check for local procedure when assigning procvar
  581. * fixed comment parsing because directives
  582. * oldtp mode directives better supported
  583. * added some messages to errore.msg
  584. Revision 1.23 1999/08/04 00:23:44 florian
  585. * renamed i386asm and i386base to cpuasm and cpubase
  586. Revision 1.22 1999/08/03 22:03:35 peter
  587. * moved bitmask constants to sets
  588. * some other type/const renamings
  589. Revision 1.21 1999/07/16 10:04:39 peter
  590. * merged
  591. Revision 1.20 1999/07/05 20:25:41 peter
  592. * merged
  593. Revision 1.19 1999/07/05 16:24:17 peter
  594. * merged
  595. Revision 1.18.2.4 1999/07/16 09:54:59 peter
  596. * @procvar support in tp7 mode works again
  597. Revision 1.18.2.3 1999/07/05 20:06:47 peter
  598. * give error instead of warning for ln(0) and sqrt(0)
  599. Revision 1.18.2.2 1999/07/05 16:22:56 peter
  600. * error if @constant
  601. Revision 1.18.2.1 1999/06/28 00:33:53 pierre
  602. * better error position bug0269
  603. Revision 1.18 1999/06/03 09:34:12 peter
  604. * better methodpointer check for proc->procvar
  605. Revision 1.17 1999/05/27 19:45:24 peter
  606. * removed oldasm
  607. * plabel -> pasmlabel
  608. * -a switches to source writing automaticly
  609. * assembler readers OOPed
  610. * asmsymbol automaticly external
  611. * jumptables and other label fixes for asm readers
  612. Revision 1.16 1999/05/18 09:52:21 peter
  613. * procedure of object and addrn fixes
  614. }