tcmem.pas 26 KB

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