tcmem.pas 26 KB

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