tcmem.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  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. { what are we getting the address from an absolute sym? }
  256. hp:=p^.left;
  257. while assigned(hp) and (hp^.treetype in [vecn,derefn,subscriptn]) do
  258. hp:=hp^.left;
  259. if assigned(hp) and (hp^.treetype=loadn) and
  260. ((hp^.symtableentry^.typ=absolutesym) and
  261. pabsolutesym(hp^.symtableentry)^.absseg) then
  262. begin
  263. if not(cs_typed_addresses in aktlocalswitches) then
  264. p^.resulttype:=voidfarpointerdef
  265. else
  266. p^.resulttype:=new(ppointerdef,initfardef(p^.left^.resulttype));
  267. end
  268. else
  269. begin
  270. if not(cs_typed_addresses in aktlocalswitches) then
  271. p^.resulttype:=voidpointerdef
  272. else
  273. p^.resulttype:=new(ppointerdef,initdef(p^.left^.resulttype));
  274. end;
  275. end;
  276. end;
  277. firstpass(p^.left);
  278. { this is like the function addr }
  279. inc(parsing_para_level);
  280. set_varstate(p^.left,false);
  281. dec(parsing_para_level);
  282. if codegenerror then
  283. exit;
  284. { don't allow constants }
  285. if is_constnode(p^.left) then
  286. begin
  287. aktfilepos:=p^.left^.fileinfo;
  288. CGMessage(type_e_no_addr_of_constant);
  289. end
  290. else
  291. begin
  292. { we should allow loc_mem for @string }
  293. if not(p^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) then
  294. begin
  295. aktfilepos:=p^.left^.fileinfo;
  296. CGMessage(cg_e_illegal_expression);
  297. end;
  298. end;
  299. p^.registers32:=p^.left^.registers32;
  300. p^.registersfpu:=p^.left^.registersfpu;
  301. {$ifdef SUPPORT_MMX}
  302. p^.registersmmx:=p^.left^.registersmmx;
  303. {$endif SUPPORT_MMX}
  304. if p^.registers32<1 then
  305. p^.registers32:=1;
  306. { is this right for object of methods ?? }
  307. p^.location.loc:=LOC_REGISTER;
  308. end;
  309. {*****************************************************************************
  310. FirstDoubleAddr
  311. *****************************************************************************}
  312. procedure firstdoubleaddr(var p : ptree);
  313. begin
  314. make_not_regable(p^.left);
  315. firstpass(p^.left);
  316. inc(parsing_para_level);
  317. set_varstate(p^.left,false);
  318. dec(parsing_para_level);
  319. if p^.resulttype=nil then
  320. p^.resulttype:=voidpointerdef;
  321. if codegenerror then
  322. exit;
  323. if (p^.left^.resulttype^.deftype)<>procvardef then
  324. CGMessage(cg_e_illegal_expression);
  325. if (p^.left^.location.loc<>LOC_REFERENCE) then
  326. CGMessage(cg_e_illegal_expression);
  327. p^.registers32:=p^.left^.registers32;
  328. p^.registersfpu:=p^.left^.registersfpu;
  329. {$ifdef SUPPORT_MMX}
  330. p^.registersmmx:=p^.left^.registersmmx;
  331. {$endif SUPPORT_MMX}
  332. if p^.registers32<1 then
  333. p^.registers32:=1;
  334. p^.location.loc:=LOC_REGISTER;
  335. end;
  336. {*****************************************************************************
  337. FirstDeRef
  338. *****************************************************************************}
  339. procedure firstderef(var p : ptree);
  340. begin
  341. firstpass(p^.left);
  342. set_varstate(p^.left,true);
  343. if codegenerror then
  344. begin
  345. p^.resulttype:=generrordef;
  346. exit;
  347. end;
  348. p^.registers32:=max(p^.left^.registers32,1);
  349. p^.registersfpu:=p^.left^.registersfpu;
  350. {$ifdef SUPPORT_MMX}
  351. p^.registersmmx:=p^.left^.registersmmx;
  352. {$endif SUPPORT_MMX}
  353. if p^.left^.resulttype^.deftype<>pointerdef then
  354. CGMessage(cg_e_invalid_qualifier);
  355. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.pointertype.def;
  356. p^.location.loc:=LOC_REFERENCE;
  357. end;
  358. {*****************************************************************************
  359. FirstSubScript
  360. *****************************************************************************}
  361. procedure firstsubscript(var p : ptree);
  362. begin
  363. firstpass(p^.left);
  364. if codegenerror then
  365. begin
  366. p^.resulttype:=generrordef;
  367. exit;
  368. end;
  369. p^.resulttype:=p^.vs^.vartype.def;
  370. p^.registers32:=p^.left^.registers32;
  371. p^.registersfpu:=p^.left^.registersfpu;
  372. {$ifdef SUPPORT_MMX}
  373. p^.registersmmx:=p^.left^.registersmmx;
  374. {$endif SUPPORT_MMX}
  375. { classes must be dereferenced implicit }
  376. if (p^.left^.resulttype^.deftype=objectdef) and
  377. pobjectdef(p^.left^.resulttype)^.is_class then
  378. begin
  379. if p^.registers32=0 then
  380. p^.registers32:=1;
  381. p^.location.loc:=LOC_REFERENCE;
  382. end
  383. else
  384. begin
  385. if (p^.left^.location.loc<>LOC_MEM) and
  386. (p^.left^.location.loc<>LOC_REFERENCE) then
  387. CGMessage(cg_e_illegal_expression);
  388. set_location(p^.location,p^.left^.location);
  389. end;
  390. end;
  391. {*****************************************************************************
  392. FirstVec
  393. *****************************************************************************}
  394. procedure firstvec(var p : ptree);
  395. var
  396. harr : pdef;
  397. ct : tconverttype;
  398. {$ifdef consteval}
  399. tcsym : ptypedconstsym;
  400. {$endif}
  401. begin
  402. firstpass(p^.left);
  403. firstpass(p^.right);
  404. if codegenerror then
  405. exit;
  406. { range check only for arrays }
  407. if (p^.left^.resulttype^.deftype=arraydef) then
  408. begin
  409. if (isconvertable(p^.right^.resulttype,parraydef(p^.left^.resulttype)^.rangetype.def,
  410. ct,ordconstn,false)=0) and
  411. not(is_equal(p^.right^.resulttype,parraydef(p^.left^.resulttype)^.rangetype.def)) then
  412. CGMessage(type_e_mismatch);
  413. end;
  414. { Never convert a boolean or a char !}
  415. { maybe type conversion }
  416. if (p^.right^.resulttype^.deftype<>enumdef) and
  417. not(is_char(p^.right^.resulttype)) and
  418. not(is_boolean(p^.right^.resulttype)) then
  419. begin
  420. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  421. firstpass(p^.right);
  422. if codegenerror then
  423. exit;
  424. end;
  425. { determine return type }
  426. if not assigned(p^.resulttype) then
  427. if p^.left^.resulttype^.deftype=arraydef then
  428. p^.resulttype:=parraydef(p^.left^.resulttype)^.elementtype.def
  429. else if (p^.left^.resulttype^.deftype=pointerdef) then
  430. begin
  431. { convert pointer to array }
  432. harr:=new(parraydef,init(0,$7fffffff,s32bitdef));
  433. parraydef(harr)^.elementtype.def:=ppointerdef(p^.left^.resulttype)^.pointertype.def;
  434. p^.left:=gentypeconvnode(p^.left,harr);
  435. firstpass(p^.left);
  436. if codegenerror then
  437. begin
  438. exit;
  439. end;
  440. p^.resulttype:=parraydef(harr)^.elementtype.def
  441. end
  442. else if p^.left^.resulttype^.deftype=stringdef then
  443. begin
  444. { indexed access to strings }
  445. case pstringdef(p^.left^.resulttype)^.string_typ of
  446. {
  447. st_widestring : p^.resulttype:=cwchardef;
  448. }
  449. st_ansistring : p^.resulttype:=cchardef;
  450. st_longstring : p^.resulttype:=cchardef;
  451. st_shortstring : p^.resulttype:=cchardef;
  452. end;
  453. end
  454. else
  455. CGMessage(type_e_mismatch);
  456. { the register calculation is easy if a const index is used }
  457. if p^.right^.treetype=ordconstn then
  458. begin
  459. {$ifdef consteval}
  460. { constant evaluation }
  461. if (p^.left^.treetype=loadn) and
  462. (p^.left^.symtableentry^.typ=typedconstsym) then
  463. begin
  464. tcsym:=ptypedconstsym(p^.left^.symtableentry);
  465. if tcsym^.defintion^.typ=stringdef then
  466. begin
  467. end;
  468. end;
  469. {$endif}
  470. p^.registers32:=p^.left^.registers32;
  471. { for ansi/wide strings, we need at least one register }
  472. if is_ansistring(p^.left^.resulttype) or
  473. is_widestring(p^.left^.resulttype) then
  474. p^.registers32:=max(p^.registers32,1);
  475. end
  476. else
  477. begin
  478. { this rules are suboptimal, but they should give }
  479. { good results }
  480. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  481. { for ansi/wide strings, we need at least one register }
  482. if is_ansistring(p^.left^.resulttype) or
  483. is_widestring(p^.left^.resulttype) then
  484. p^.registers32:=max(p^.registers32,1);
  485. { need we an extra register when doing the restore ? }
  486. if (p^.left^.registers32<=p^.right^.registers32) and
  487. { only if the node needs less than 3 registers }
  488. { two for the right node and one for the }
  489. { left address }
  490. (p^.registers32<3) then
  491. inc(p^.registers32);
  492. { need we an extra register for the index ? }
  493. if (p^.right^.location.loc<>LOC_REGISTER)
  494. { only if the right node doesn't need a register }
  495. and (p^.right^.registers32<1) then
  496. inc(p^.registers32);
  497. { not correct, but what works better ?
  498. if p^.left^.registers32>0 then
  499. p^.registers32:=max(p^.registers32,2)
  500. else
  501. min. one register
  502. p^.registers32:=max(p^.registers32,1);
  503. }
  504. end;
  505. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  506. {$ifdef SUPPORT_MMX}
  507. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  508. {$endif SUPPORT_MMX}
  509. if p^.left^.location.loc in [LOC_CREGISTER,LOC_REFERENCE] then
  510. p^.location.loc:=LOC_REFERENCE
  511. else
  512. p^.location.loc:=LOC_MEM;
  513. end;
  514. {*****************************************************************************
  515. FirstSelf
  516. *****************************************************************************}
  517. procedure firstself(var p : ptree);
  518. begin
  519. if (p^.resulttype^.deftype=classrefdef) or
  520. ((p^.resulttype^.deftype=objectdef)
  521. and pobjectdef(p^.resulttype)^.is_class
  522. ) then
  523. p^.location.loc:=LOC_CREGISTER
  524. else
  525. p^.location.loc:=LOC_REFERENCE;
  526. end;
  527. {*****************************************************************************
  528. FirstWithN
  529. *****************************************************************************}
  530. procedure firstwith(var p : ptree);
  531. var
  532. symtable : pwithsymtable;
  533. i : longint;
  534. begin
  535. if assigned(p^.left) and assigned(p^.right) then
  536. begin
  537. firstpass(p^.left);
  538. { is this correct ? At least after is like if used
  539. set_varstate(p^.left,false);
  540. already done in _with_statment }
  541. p^.left^.varstateset:=false;
  542. set_varstate(p^.left,true);
  543. if codegenerror then
  544. exit;
  545. symtable:=p^.withsymtable;
  546. for i:=1 to p^.tablecount do
  547. begin
  548. if (p^.left^.treetype=loadn) and
  549. (p^.left^.symtable=aktprocsym^.definition^.localst) then
  550. symtable^.direct_with:=true;
  551. symtable^.withnode:=p;
  552. symtable:=pwithsymtable(symtable^.next);
  553. end;
  554. firstpass(p^.right);
  555. if codegenerror then
  556. exit;
  557. left_right_max(p);
  558. p^.resulttype:=voiddef;
  559. end
  560. else
  561. begin
  562. { optimization }
  563. disposetree(p);
  564. p:=nil;
  565. end;
  566. end;
  567. end.
  568. {
  569. $Log$
  570. Revision 1.42 2000-02-17 14:53:43 florian
  571. * some updates for the newcg
  572. Revision 1.41 2000/02/09 13:23:08 peter
  573. * log truncated
  574. Revision 1.40 2000/01/10 16:38:43 pierre
  575. * suppress wrong warning for with vars
  576. Revision 1.39 2000/01/10 00:42:44 pierre
  577. * fix for bug 776
  578. Revision 1.38 2000/01/07 09:36:24 pierre
  579. * With argument is set as used to avoid unnecessary warnings
  580. Revision 1.37 2000/01/07 01:14:46 peter
  581. * updated copyright to 2000
  582. Revision 1.36 1999/11/30 10:40:58 peter
  583. + ttype, tsymlist
  584. Revision 1.35 1999/11/29 22:36:48 florian
  585. * problem with taking the address of abstract procedures fixed
  586. Revision 1.34 1999/11/18 15:34:51 pierre
  587. * Notes/Hints for local syms changed to
  588. Set_varstate function
  589. Revision 1.33 1999/11/17 17:05:07 pierre
  590. * Notes/hints changes
  591. Revision 1.32 1999/11/06 14:34:30 peter
  592. * truncated log to 20 revs
  593. Revision 1.31 1999/10/26 12:30:46 peter
  594. * const parameter is now checked
  595. * better and generic check if a node can be used for assigning
  596. * export fixes
  597. * procvar equal works now (it never had worked at least from 0.99.8)
  598. * defcoll changed to linkedlist with pparaitem so it can easily be
  599. walked both directions
  600. Revision 1.30 1999/10/13 10:40:55 peter
  601. * subscript support for tp_procvar
  602. Revision 1.29 1999/09/27 23:45:02 peter
  603. * procinfo is now a pointer
  604. * support for result setting in sub procedure
  605. Revision 1.28 1999/09/17 17:14:12 peter
  606. * @procvar fixes for tp mode
  607. * @<id>:= gives now an error
  608. Revision 1.27 1999/09/11 11:10:39 florian
  609. * fix of my previous commit, make cycle was broken
  610. Revision 1.26 1999/09/11 09:08:34 florian
  611. * fixed bug 596
  612. * fixed some problems with procedure variables and procedures of object,
  613. especially in TP mode. Procedure of object doesn't apply only to classes,
  614. it is also allowed for objects !!
  615. Revision 1.25 1999/08/23 23:34:15 pierre
  616. * one more register needed if hnewn with CREGISTER
  617. Revision 1.24 1999/08/05 16:53:25 peter
  618. * V_Fatal=1, all other V_ are also increased
  619. * Check for local procedure when assigning procvar
  620. * fixed comment parsing because directives
  621. * oldtp mode directives better supported
  622. * added some messages to errore.msg
  623. Revision 1.23 1999/08/04 00:23:44 florian
  624. * renamed i386asm and i386base to cpuasm and cpubase
  625. Revision 1.22 1999/08/03 22:03:35 peter
  626. * moved bitmask constants to sets
  627. * some other type/const renamings
  628. }