nld.pas 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. {
  2. $Id$
  3. Copyright (c) 2000 by Florian Klaempfl
  4. Type checking and register allocation for load/assignment 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 nld;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node,symtable;
  23. type
  24. tloadnode = class(tunarynode)
  25. symtableentry : psym;
  26. symtable : psymtable;
  27. constructor create(v : pvarsym;st : psymtable);virtual;
  28. function getcopy : tnode;override;
  29. function pass_1 : tnode;override;
  30. end;
  31. { different assignment types }
  32. tassigntyp = (at_normal,at_plus,at_minus,at_star,at_slash);
  33. tassignmentnode = class(tbinarynode)
  34. assigntyp : tassigntyp;
  35. constructor create(l,r : tnode);virtual;
  36. function getcopy : tnode;override;
  37. function pass_1 : tnode;override;
  38. end;
  39. tfuncretnode = class(tnode)
  40. funcretprocinfo : pointer;
  41. {$IFDEF NEWST}
  42. retsym : Psym;
  43. {$ELSE}
  44. rettype : ttype;
  45. {$ENDIF}
  46. constructor create;virtual;
  47. function getcopy : tnode;override;
  48. function pass_1 : tnode;override;
  49. end;
  50. tarrayconstructorrangenode = class(tbinarynode)
  51. constructor create(l,r : tnode);virtual;
  52. function pass_1 : tnode;override;
  53. end;
  54. tarrayconstructnode = class(tbinarynode)
  55. constructdef : pdef;
  56. constructor create(l,r : tnode);virtual;
  57. function getcopy : tnode;
  58. function pass_1 : tnode;override;
  59. end;
  60. ttypenode = class(tnode)
  61. typenodetype : pdef;
  62. typenodesym:ptypesym;
  63. constructor create(t : pdef;sym:ptypesym);virtual;
  64. function getcopy : tnode;override;
  65. function pass_1 : tnode;override;
  66. end;
  67. var
  68. cloadnode : class of tloadnode;
  69. cassignmentnode : class of tassignmentnode;
  70. cfuncretnode : class of tfuncretnode;
  71. carrayconstructorrangenode : class of tarrayconstructorrangenode;
  72. carrayconstructnode : class of tarrayconstructnode;
  73. ctypenode : class of ttypenode;
  74. function genloadnode(v : pvarsym;st : psymtable) : tloadnode;
  75. function gentypenode(t : pdef;sym:ptypesym) : ttypenode;
  76. function genloadcallnode(v: pprocsym;st: psymtable): tloadnode;
  77. function genloadmethodcallnode(v: pprocsym;st: psymtable; mp: tnode): tloadnode;
  78. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : tloadnode;
  79. implementation
  80. uses
  81. cutils,cobjects,verbose,globtype,globals,systems,
  82. symconst,aasm,types,
  83. htypechk,pass_1,
  84. ncnv,cpubase
  85. {$ifdef newcg}
  86. ,cgbase
  87. ,tgobj
  88. ,tgcpu
  89. {$else newcg}
  90. ,hcodegen
  91. {$ifdef i386}
  92. ,tgeni386
  93. {$endif}
  94. {$endif newcg}
  95. ;
  96. function genloadnode(v : pvarsym;st : psymtable) : tloadnode;
  97. var
  98. n : tloadnode;
  99. begin
  100. n:=cloadnode.create(v,st);
  101. {$fidef NEWST}
  102. n.resulttype:=v^.definition;
  103. {$else NEWST}
  104. n.resulttype:=v^.vartype.def;
  105. {$endif NEWST}
  106. genloadnode:=n:
  107. end;
  108. function genloadcallnode(v: pprocsym;st: psymtable): tloadnode;
  109. var
  110. n : tloadnode;
  111. begin
  112. n:=cloadnode.create(v,st);
  113. {$ifdef NEWST}
  114. n.resulttype:=nil; {We don't know which overloaded procedure is
  115. wanted...}
  116. {$else NEWST}
  117. n.resulttype:=v^.definition;
  118. {$endif NEWST}
  119. genloadcallnode:=n;
  120. end;
  121. function genloadmethodcallnode(v: pprocsym;st: psymtable; mp: tnode): tloadnode;
  122. var
  123. n : tloadnode;
  124. begin
  125. n:=cloadnode.create(v,st);
  126. {$ifdef NEWST}
  127. n.resulttype:=nil; {We don't know which overloaded procedure is
  128. wanted...}
  129. {$else NEWST}
  130. n.resulttype:=v^.definition;
  131. {$endif NEWST}
  132. p^.left:=mp;
  133. genloadmethodcallnode:=v;
  134. end;
  135. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : tloadnode;
  136. var
  137. n : tloadnode;
  138. begin
  139. n:=cloadnode.create(sym,st);
  140. {$ifdef NEWST}
  141. n.resulttype:=sym^.definition;
  142. {$else NEWST}
  143. n.resulttype:=sym^.typedconsttype.def;
  144. {$endif NEWST}
  145. gentypedconstloadnode:=n;
  146. end;
  147. function gentypenode(t : pdef;sym:ptypesym) : ttypenode;
  148. begin
  149. gentypenode:=ctypenode.create(t,sym);
  150. end;
  151. {*****************************************************************************
  152. TLOADNODE
  153. *****************************************************************************}
  154. constructor tloadnode.create(v : pvarsym;st : psymtable);
  155. begin
  156. inherited create(loadn,nil);
  157. symtableentry:=v;
  158. symtable:=st;
  159. end;
  160. function tloadnode.getcopy : tnode;
  161. var
  162. n : tloadnode;
  163. begin
  164. n:=tloadnode(inherited getcopy);
  165. n.symtable:=symtable;
  166. n.symtableentry:=symtableentry;
  167. end;
  168. function tloadnode.pass_1 : tnode;
  169. var
  170. p1 : tnode;
  171. begin
  172. if (symtable^.symtabletype=withsymtable) and
  173. (pwithsymtable(symtable)^.direct_with) and
  174. (symtableentry^.typ=varsym) then
  175. begin
  176. p1:=getcopy(ptree(pwithsymtable(symtable)^.withrefnode));
  177. p1:=gensubscriptnode(pvarsym(symtableentry),p1);
  178. putnode(p);
  179. p:=p1;
  180. firstpass(p);
  181. exit;
  182. end;
  183. location.loc:=LOC_REFERENCE;
  184. registers32:=0;
  185. registersfpu:=0;
  186. {$ifdef SUPPORT_MMX}
  187. registersmmx:=0;
  188. {$endif SUPPORT_MMX}
  189. { handle first absolute as it will replace the symtableentry }
  190. if symtableentry^.typ=absolutesym then
  191. begin
  192. resulttype:=pabsolutesym(symtableentry)^.vartype.def;
  193. { replace the symtableentry when it points to a var, else
  194. we are finished }
  195. if pabsolutesym(symtableentry)^.abstyp=tovar then
  196. begin
  197. symtableentry:=pabsolutesym(symtableentry)^.ref;
  198. symtable:=symtableentry^.owner;
  199. is_absolute:=true;
  200. end
  201. else
  202. exit;
  203. end;
  204. case symtableentry^.typ of
  205. funcretsym :
  206. begin
  207. p1:=genzeronode(funcretn);
  208. p1.funcretprocinfo:=pprocinfo(pfuncretsym(symtableentry)^.funcretprocinfo);
  209. p1.rettype:=pfuncretsym(symtableentry)^.rettype;
  210. firstpass(p1);
  211. { if it's refered as absolute then we need to have the
  212. type of the absolute instead of the function return,
  213. the function return is then also assigned }
  214. if is_absolute then
  215. begin
  216. pprocinfo(p1.funcretprocinfo)^.funcret_state:=vs_assigned;
  217. p1.resulttype:=resulttype;
  218. end;
  219. putnode(p);
  220. p:=p1;
  221. end;
  222. constsym:
  223. begin
  224. if pconstsym(symtableentry)^.consttyp=constresourcestring then
  225. begin
  226. resulttype:=cansistringdef;
  227. { we use ansistrings so no fast exit here }
  228. if assigned(procinfo) then
  229. procinfo^.no_fast_exit:=true;
  230. location.loc:=LOC_MEM;
  231. end
  232. else
  233. internalerror(22799);
  234. end;
  235. varsym :
  236. begin
  237. { if it's refered by absolute then it's used }
  238. if is_absolute then
  239. pvarsym(symtableentry)^.varstate:=vs_used
  240. else
  241. if (resulttype=nil) then
  242. resulttype:=pvarsym(symtableentry)^.vartype.def;
  243. if (symtable^.symtabletype in [parasymtable,localsymtable]) and
  244. (lexlevel>symtable^.symtablelevel) then
  245. begin
  246. { if the variable is in an other stackframe then we need
  247. a register to dereference }
  248. if (symtable^.symtablelevel)>0 then
  249. begin
  250. registers32:=1;
  251. { further, the variable can't be put into a register }
  252. pvarsym(symtableentry)^.varoptions:=
  253. pvarsym(symtableentry)^.varoptions-[vo_fpuregable,vo_regable];
  254. end;
  255. end;
  256. if (pvarsym(symtableentry)^.varspez=vs_const) then
  257. location.loc:=LOC_MEM;
  258. { we need a register for call by reference parameters }
  259. if (pvarsym(symtableentry)^.varspez in [vs_var,vs_out]) or
  260. ((pvarsym(symtableentry)^.varspez=vs_const) and
  261. push_addr_param(pvarsym(symtableentry)^.vartype.def)) or
  262. { call by value open arrays are also indirect addressed }
  263. is_open_array(pvarsym(symtableentry)^.vartype.def) then
  264. registers32:=1;
  265. if symtable^.symtabletype=withsymtable then
  266. inc(registers32);
  267. if ([vo_is_thread_var,vo_is_dll_var]*pvarsym(symtableentry)^.varoptions)<>[] then
  268. registers32:=1;
  269. { a class variable is a pointer !!!
  270. yes, but we have to resolve the reference in an
  271. appropriate tree node (FK)
  272. if (pvarsym(symtableentry)^.definition^.deftype=objectdef) and
  273. ((pobjectdef(pvarsym(symtableentry)^.definition)^.options and oo_is_class)<>0) then
  274. registers32:=1;
  275. }
  276. { count variable references }
  277. { this will create problem with local var set by
  278. under_procedures
  279. if (assigned(pvarsym(symtableentry)^.owner) and assigned(aktprocsym)
  280. and ((pvarsym(symtableentry)^.owner = aktprocsym^.definition^.localst)
  281. or (pvarsym(symtableentry)^.owner = aktprocsym^.definition^.localst))) then }
  282. if t_times<1 then
  283. inc(pvarsym(symtableentry)^.refs)
  284. else
  285. inc(pvarsym(symtableentry)^.refs,t_times);
  286. end;
  287. typedconstsym :
  288. if not is_absolute then
  289. resulttype:=ptypedconstsym(symtableentry)^.typedconsttype.def;
  290. procsym :
  291. begin
  292. if assigned(pprocsym(symtableentry)^.definition^.nextoverloaded) then
  293. CGMessage(parser_e_no_overloaded_procvars);
  294. resulttype:=pprocsym(symtableentry)^.definition;
  295. { if the owner of the procsym is a object, }
  296. { left must be set, if left isn't set }
  297. { it can be only self }
  298. { this code is only used in TP procvar mode }
  299. if (m_tp_procvar in aktmodeswitches) and
  300. not(assigned(left)) and
  301. (pprocsym(symtableentry)^.owner^.symtabletype=objectsymtable) then
  302. left:=genselfnode(pobjectdef(symtableentry^.owner^.defowner));
  303. { method pointer ? }
  304. if assigned(left) then
  305. begin
  306. firstpass(left);
  307. registers32:=max(registers32,left.registers32);
  308. registersfpu:=max(registersfpu,left.registersfpu);
  309. {$ifdef SUPPORT_MMX}
  310. registersmmx:=max(registersmmx,left.registersmmx);
  311. {$endif SUPPORT_MMX}
  312. end;
  313. end;
  314. else
  315. internalerror(3);
  316. end;
  317. end;
  318. {*****************************************************************************
  319. TASSIGNMENTNODE
  320. *****************************************************************************}
  321. constructor tassignmentnode.create(l,r : tnode);
  322. begin
  323. inherited create(assignn,l,r);
  324. assigntype:=at_normal;
  325. end;
  326. function tassignmentnode.getcopy : tnode;
  327. var
  328. n : tassignmentnode;
  329. begin
  330. n:=tassignmentnode(inherited getcopy);
  331. n.assigntype:=assigntype;
  332. getcopy:=n;
  333. end;
  334. function tassignmentnode.pass_1 : tnode;
  335. {$ifdef newoptimizations2}
  336. var
  337. hp : tnode;
  338. {$endif newoptimizations2}
  339. begin
  340. { must be made unique }
  341. set_unique(left);
  342. { set we the function result? }
  343. set_funcret_is_valid(left);
  344. firstpass(left);
  345. set_varstate(left,false);
  346. if codegenerror then
  347. exit;
  348. { assignements to open arrays aren't allowed }
  349. if is_open_array(left.resulttype) then
  350. CGMessage(type_e_mismatch);
  351. { test if we can avoid copying string to temp
  352. as in s:=s+...; (PM) }
  353. {$ifdef dummyi386}
  354. if ((right.treetype=addn) or (right.treetype=subn)) and
  355. equal_trees(left,right.left) and
  356. (ret_in_acc(left.resulttype)) and
  357. (not cs_rangechecking in aktmoduleswitches^) then
  358. begin
  359. disposetree(right.left);
  360. hp:=right;
  361. right:=right.right;
  362. if hp.treetype=addn then
  363. assigntyp:=at_plus
  364. else
  365. assigntyp:=at_minus;
  366. putnode(hp);
  367. end;
  368. if assigntyp<>at_normal then
  369. begin
  370. { for fpu type there is no faster way }
  371. if is_fpu(left.resulttype) then
  372. case assigntyp of
  373. at_plus : right:=gennode(addn,getcopy(left),right);
  374. at_minus : right:=gennode(subn,getcopy(left),right);
  375. at_star : right:=gennode(muln,getcopy(left),right);
  376. at_slash : right:=gennode(slashn,getcopy(left),right);
  377. end;
  378. end;
  379. {$endif i386}
  380. firstpass(right);
  381. set_varstate(right,true);
  382. if codegenerror then
  383. exit;
  384. { some string functions don't need conversion, so treat them separatly }
  385. if is_shortstring(left.resulttype) and (assigned(right.resulttype)) then
  386. begin
  387. if not (is_shortstring(right.resulttype) or
  388. is_ansistring(right.resulttype) or
  389. is_char(right.resulttype)) then
  390. begin
  391. right:=gentypeconvnode(right,left.resulttype);
  392. firstpass(right);
  393. if codegenerror then
  394. exit;
  395. end;
  396. { we call STRCOPY }
  397. procinfo^.flags:=procinfo^.flags or pi_do_call;
  398. { test for s:=s+anything ... }
  399. { the problem is for
  400. s:=s+s+s;
  401. this is broken here !! }
  402. {$ifdef newoptimizations2}
  403. { the above is fixed now, but still problem with s := s + f(); if }
  404. { f modifies s (bad programming, so only enable if uncertain }
  405. { optimizations are on) (JM) }
  406. if (cs_UncertainOpts in aktglobalswitches) then
  407. begin
  408. hp := right;
  409. while hp.treetype=addn do hp:=hp.left;
  410. if equal_trees(left,hp) and
  411. not multiple_uses(left,right) then
  412. begin
  413. concat_string:=true;
  414. hp:=right;
  415. while hp.treetype=addn do
  416. begin
  417. hp.use_strconcat:=true;
  418. hp:=hp.left;
  419. end;
  420. end;
  421. end;
  422. {$endif newoptimizations2}
  423. end
  424. else
  425. begin
  426. right:=gentypeconvnode(right,left.resulttype);
  427. firstpass(right);
  428. if codegenerror then
  429. exit;
  430. end;
  431. { test if node can be assigned, properties are allowed }
  432. valid_for_assign(left,true);
  433. { check if local proc/func is assigned to procvar }
  434. if right.resulttype^.deftype=procvardef then
  435. test_local_to_procvar(pprocvardef(right.resulttype),left.resulttype);
  436. resulttype:=voiddef;
  437. {
  438. registers32:=max(left.registers32,right.registers32);
  439. registersfpu:=max(left.registersfpu,right.registersfpu);
  440. }
  441. registers32:=left.registers32+right.registers32;
  442. registersfpu:=max(left.registersfpu,right.registersfpu);
  443. {$ifdef SUPPORT_MMX}
  444. registersmmx:=max(left.registersmmx,right.registersmmx);
  445. {$endif SUPPORT_MMX}
  446. end;
  447. {*****************************************************************************
  448. TFUNCRETNODE
  449. *****************************************************************************}
  450. constructor tfuncretnode.create;
  451. begin
  452. inherited create(tfuncretn);
  453. funcretprocinfo:=nil;
  454. n.rettype:=nil;
  455. end;
  456. function tfuncretnode.getcopy : tnode;
  457. var
  458. n : tfuncretnode;
  459. begin
  460. n:=tfuncretnode(inherited getcopy);
  461. n.funcretprocinfo:=funcretprocinfo;
  462. {$ifdef NEWST}
  463. n.retsym:=retsym;
  464. {$else NEWST}
  465. n.rettype:=rettype;
  466. {$endif NEWST}
  467. getcopy:=n;
  468. end;
  469. function tfuncretnode.pass_1 : tnode;
  470. begin
  471. resulttype:=rettype.def;
  472. location.loc:=LOC_REFERENCE;
  473. if ret_in_param(rettype.def) or
  474. (procinfo<>pprocinfo(funcretprocinfo)) then
  475. registers32:=1;
  476. end;
  477. {*****************************************************************************
  478. TARRAYCONSTRUCTRANGENODE
  479. *****************************************************************************}
  480. constructor tarrayconstructrangenode.create(l,r : tnode);
  481. begin
  482. inherited create(arrayconstructn,l,r);
  483. end;
  484. function tarrayconstructrangenode.pass_1 : tnode;
  485. begin
  486. firstpass(left);
  487. left.set_varstate(true);
  488. firstpass(right);
  489. right.set_varstate(true);
  490. calcregisters(p,0,0,0);
  491. resulttype:=left.resulttype;
  492. end;
  493. {****************************************************************************
  494. TARRAYCONSTRUCTNODE
  495. *****************************************************************************}
  496. constructor tarrayconstrucnode.create(l,r : tnode);
  497. begin
  498. inherited create(arrayconstructnode,l,r);
  499. constructdef:=nil;
  500. end;
  501. function tarrayconstrucnode.getcopy : tnode;
  502. var
  503. n : tarrayconstructnode;
  504. begin
  505. n:=tarrayconstructnode(inherited getcopy);
  506. n.constructdef:=constructdef;
  507. end;
  508. function tarrayconstructnode.pass_1 : tnode;
  509. var
  510. pd : pdef;
  511. thp,
  512. chp,
  513. hp : tnode;
  514. len : longint;
  515. varia : boolean;
  516. begin
  517. { are we allowing array constructor? Then convert it to a set }
  518. if not allow_array_constructor then
  519. begin
  520. arrayconstructor_to_set(p);
  521. firstpass(p);
  522. exit;
  523. end;
  524. { only pass left tree, right tree contains next construct if any }
  525. pd:=constructdef;
  526. len:=0;
  527. varia:=false;
  528. if assigned(left) then
  529. begin
  530. hp:=p;
  531. while assigned(hp) do
  532. begin
  533. firstpass(hp.left);
  534. hp.left.set_varstate(true);
  535. if (not get_para_resulttype) and (not novariaallowed) then
  536. begin
  537. case hp.left.resulttype^.deftype of
  538. enumdef :
  539. begin
  540. hp.left:=gentypeconvnode(hp.left,s32bitdef);
  541. firstpass(hp.left);
  542. end;
  543. orddef :
  544. begin
  545. if is_integer(hp.left.resulttype) and
  546. not(is_64bitint(hp.left.resulttype)) then
  547. begin
  548. hp.left:=gentypeconvnode(hp.left,s32bitdef);
  549. firstpass(hp.left);
  550. end;
  551. end;
  552. floatdef :
  553. begin
  554. hp.left:=gentypeconvnode(hp.left,bestrealdef^);
  555. firstpass(hp.left);
  556. end;
  557. stringdef :
  558. begin
  559. if cargs then
  560. begin
  561. hp.left:=gentypeconvnode(hp.left,charpointerdef);
  562. firstpass(hp.left);
  563. end;
  564. end;
  565. procvardef :
  566. begin
  567. hp.left:=gentypeconvnode(hp.left,voidpointerdef);
  568. firstpass(hp.left);
  569. end;
  570. pointerdef,
  571. classrefdef,
  572. objectdef : ;
  573. else
  574. CGMessagePos1(hp.left.fileinfo,type_e_wrong_type_in_array_constructor,hp.left.resulttype^.typename);
  575. end;
  576. end;
  577. if (pd=nil) then
  578. pd:=hp.left.resulttype
  579. else
  580. begin
  581. if ((novariaallowed) or (not varia)) and
  582. (not is_equal(pd,hp.left.resulttype)) then
  583. begin
  584. { if both should be equal try inserting a conversion }
  585. if novariaallowed then
  586. begin
  587. hp.left:=gentypeconvnode(hp.left,pd);
  588. firstpass(hp.left);
  589. end;
  590. varia:=true;
  591. end;
  592. end;
  593. inc(len);
  594. hp:=hp.right;
  595. end;
  596. { swap the tree for cargs }
  597. if cargs and (not cargswap) then
  598. begin
  599. chp:=nil;
  600. hp:=p;
  601. while assigned(hp) do
  602. begin
  603. thp:=hp.right;
  604. hp.right:=chp;
  605. chp:=hp;
  606. hp:=thp;
  607. end;
  608. p:=chp;
  609. cargs:=true;
  610. cargswap:=true;
  611. end;
  612. end;
  613. calcregisters(p,0,0,0);
  614. { looks a little bit dangerous to me }
  615. { len-1 gives problems with is_open_array if len=0, }
  616. { is_open_array checks now for isconstructor (FK) }
  617. { if no type is set then we set the type to voiddef to overcome a
  618. 0 addressing }
  619. if not assigned(pd) then
  620. pd:=voiddef;
  621. { skip if already done ! (PM) }
  622. if not assigned(resulttype) or
  623. (resulttype^.deftype<>arraydef) or
  624. not parraydef(resulttype)^.IsConstructor or
  625. (parraydef(resulttype)^.lowrange<>0) or
  626. (parraydef(resulttype)^.highrange<>len-1) then
  627. resulttype:=new(parraydef,init(0,len-1,s32bitdef));
  628. parraydef(resulttype)^.elementtype.def:=pd;
  629. parraydef(resulttype)^.IsConstructor:=true;
  630. parraydef(resulttype)^.IsVariant:=varia;
  631. location.loc:=LOC_MEM;
  632. end;
  633. {*****************************************************************************
  634. TTYPENODE
  635. *****************************************************************************}
  636. constructor ttypenode.create(t : pdef;sym:ptypesym);
  637. begin
  638. inherited create(typen);
  639. resulttype:=generrordef;
  640. typenodetype:=t;
  641. typenodesym:=sym;
  642. end;
  643. function ttypenode.getcopy : tnode;
  644. var
  645. n : ttypenode;
  646. begin
  647. n:=ttypenode(inherited getcopy);
  648. n.typenodetype:=typenodetype;
  649. n.typenodesym:=typenodesym;
  650. end;
  651. function ttypenode.pass_1 : tnode;
  652. begin
  653. pass_1:=nil;
  654. { do nothing, resulttype is already set }
  655. end;
  656. begin
  657. cloadnode:=tloadnode;
  658. cassignmentnode:=tassignmentnode;
  659. cfuncretnode:=tfuncretnode;
  660. carrayconstructorrangenode:=tarrayconstructorrangenode;
  661. carrayconstructnode:=tarrayconstructnode;
  662. ctypenode:=ttypenode;
  663. end.
  664. {
  665. $Log$
  666. Revision 1.2 2000-09-25 15:37:14 florian
  667. * more fixes
  668. Revision 1.1 2000/09/25 14:55:05 florian
  669. * initial revision
  670. }