tcmem.pas 25 KB

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