nld.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  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 : psym;st : psymtable);virtual;
  28. function getcopy : tnode;override;
  29. function pass_1 : tnode;override;
  30. end;
  31. { different assignment types }
  32. tassigntype = (at_normal,at_plus,at_minus,at_star,at_slash);
  33. tassignmentnode = class(tbinarynode)
  34. assigntype : tassigntype;
  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,nmem,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. {$ifdef 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. n.left:=mp;
  133. genloadmethodcallnode:=n;
  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 : psym;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:=tnode(pwithsymtable(symtable)^.withrefnode).getcopy;
  177. p1:=gensubscriptnode(pvarsym(symtableentry),p1);
  178. left:=nil;
  179. firstpass(p1);
  180. pass_1:=p1;
  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. include(flags,nf_absolute);
  200. end
  201. else
  202. exit;
  203. end;
  204. case symtableentry^.typ of
  205. funcretsym :
  206. begin
  207. p1:=cfuncretnode.create;
  208. tfuncretnode(p1).funcretprocinfo:=pprocinfo(pfuncretsym(symtableentry)^.funcretprocinfo);
  209. tfuncretnode(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 nf_absolute in flags then
  215. begin
  216. pprocinfo(tfuncretnode(p1).funcretprocinfo)^.funcret_state:=vs_assigned;
  217. p1.resulttype:=resulttype;
  218. end;
  219. left:=nil;
  220. pass_1:=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 nf_absolute in flags 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(nf_absolute in flags) 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. if assigned(left) then
  342. begin
  343. set_unique(left);
  344. { set we the function result? }
  345. set_funcret_is_valid(left);
  346. end;
  347. firstpass(left);
  348. set_varstate(left,false);
  349. if codegenerror then
  350. exit;
  351. { assignements to open arrays aren't allowed }
  352. if is_open_array(left.resulttype) then
  353. CGMessage(type_e_mismatch);
  354. { test if we can avoid copying string to temp
  355. as in s:=s+...; (PM) }
  356. {$ifdef dummyi386}
  357. if ((right.treetype=addn) or (right.treetype=subn)) and
  358. equal_trees(left,right.left) and
  359. (ret_in_acc(left.resulttype)) and
  360. (not cs_rangechecking in aktmoduleswitches^) then
  361. begin
  362. disposetree(right.left);
  363. hp:=right;
  364. right:=right.right;
  365. if hp.treetype=addn then
  366. assigntyp:=at_plus
  367. else
  368. assigntyp:=at_minus;
  369. putnode(hp);
  370. end;
  371. if assigntyp<>at_normal then
  372. begin
  373. { for fpu type there is no faster way }
  374. if is_fpu(left.resulttype) then
  375. case assigntyp of
  376. at_plus : right:=gennode(addn,getcopy(left),right);
  377. at_minus : right:=gennode(subn,getcopy(left),right);
  378. at_star : right:=gennode(muln,getcopy(left),right);
  379. at_slash : right:=gennode(slashn,getcopy(left),right);
  380. end;
  381. end;
  382. {$endif i386}
  383. firstpass(right);
  384. set_varstate(right,true);
  385. if codegenerror then
  386. exit;
  387. { some string functions don't need conversion, so treat them separatly }
  388. if is_shortstring(left.resulttype) and (assigned(right.resulttype)) then
  389. begin
  390. if not (is_shortstring(right.resulttype) or
  391. is_ansistring(right.resulttype) or
  392. is_char(right.resulttype)) then
  393. begin
  394. right:=gentypeconvnode(right,left.resulttype);
  395. firstpass(right);
  396. if codegenerror then
  397. exit;
  398. end;
  399. { we call STRCOPY }
  400. procinfo^.flags:=procinfo^.flags or pi_do_call;
  401. { test for s:=s+anything ... }
  402. { the problem is for
  403. s:=s+s+s;
  404. this is broken here !! }
  405. {$ifdef newoptimizations2}
  406. { the above is fixed now, but still problem with s := s + f(); if }
  407. { f modifies s (bad programming, so only enable if uncertain }
  408. { optimizations are on) (JM) }
  409. if (cs_UncertainOpts in aktglobalswitches) then
  410. begin
  411. hp := right;
  412. while hp.treetype=addn do hp:=hp.left;
  413. if equal_trees(left,hp) and
  414. not multiple_uses(left,right) then
  415. begin
  416. concat_string:=true;
  417. hp:=right;
  418. while hp.treetype=addn do
  419. begin
  420. hp.use_strconcat:=true;
  421. hp:=hp.left;
  422. end;
  423. end;
  424. end;
  425. {$endif newoptimizations2}
  426. end
  427. else
  428. begin
  429. right:=gentypeconvnode(right,left.resulttype);
  430. firstpass(right);
  431. if codegenerror then
  432. exit;
  433. end;
  434. { test if node can be assigned, properties are allowed }
  435. valid_for_assign(left,true);
  436. { check if local proc/func is assigned to procvar }
  437. if right.resulttype^.deftype=procvardef then
  438. test_local_to_procvar(pprocvardef(right.resulttype),left.resulttype);
  439. resulttype:=voiddef;
  440. {
  441. registers32:=max(left.registers32,right.registers32);
  442. registersfpu:=max(left.registersfpu,right.registersfpu);
  443. }
  444. registers32:=left.registers32+right.registers32;
  445. registersfpu:=max(left.registersfpu,right.registersfpu);
  446. {$ifdef SUPPORT_MMX}
  447. registersmmx:=max(left.registersmmx,right.registersmmx);
  448. {$endif SUPPORT_MMX}
  449. end;
  450. {*****************************************************************************
  451. TFUNCRETNODE
  452. *****************************************************************************}
  453. constructor tfuncretnode.create;
  454. begin
  455. inherited create(funcretn);
  456. funcretprocinfo:=nil;
  457. end;
  458. function tfuncretnode.getcopy : tnode;
  459. var
  460. n : tfuncretnode;
  461. begin
  462. n:=tfuncretnode(inherited getcopy);
  463. n.funcretprocinfo:=funcretprocinfo;
  464. {$ifdef NEWST}
  465. n.retsym:=retsym;
  466. {$else NEWST}
  467. n.rettype:=rettype;
  468. {$endif NEWST}
  469. getcopy:=n;
  470. end;
  471. function tfuncretnode.pass_1 : tnode;
  472. begin
  473. resulttype:=rettype.def;
  474. location.loc:=LOC_REFERENCE;
  475. if ret_in_param(rettype.def) or
  476. (procinfo<>pprocinfo(funcretprocinfo)) then
  477. registers32:=1;
  478. end;
  479. {*****************************************************************************
  480. TARRAYCONSTRUCTRANGENODE
  481. *****************************************************************************}
  482. constructor tarrayconstructorrangenode.create(l,r : tnode);
  483. begin
  484. inherited create(arrayconstructn,l,r);
  485. end;
  486. function tarrayconstructorrangenode.pass_1 : tnode;
  487. begin
  488. firstpass(left);
  489. set_varstate(left,true);
  490. firstpass(right);
  491. set_varstate(right,true);
  492. calcregisters(self,0,0,0);
  493. resulttype:=left.resulttype;
  494. end;
  495. {****************************************************************************
  496. TARRAYCONSTRUCTNODE
  497. *****************************************************************************}
  498. constructor tarrayconstructnode.create(l,r : tnode);
  499. begin
  500. inherited create(arrayconstructn,l,r);
  501. constructdef:=nil;
  502. end;
  503. function tarrayconstructnode.getcopy : tnode;
  504. var
  505. n : tarrayconstructnode;
  506. begin
  507. n:=tarrayconstructnode(inherited getcopy);
  508. n.constructdef:=constructdef;
  509. end;
  510. function tarrayconstructnode.pass_1 : tnode;
  511. var
  512. pd : pdef;
  513. thp,
  514. chp,
  515. hp : tarrayconstructnode;
  516. len : longint;
  517. varia : boolean;
  518. procedure postprocess(t : tnode);
  519. begin
  520. calcregisters(tbinarynode(t),0,0,0);
  521. { looks a little bit dangerous to me }
  522. { len-1 gives problems with is_open_array if len=0, }
  523. { is_open_array checks now for isconstructor (FK) }
  524. { if no type is set then we set the type to voiddef to overcome a
  525. 0 addressing }
  526. if not assigned(pd) then
  527. pd:=voiddef;
  528. { skip if already done ! (PM) }
  529. if not assigned(t.resulttype) or
  530. (t.resulttype^.deftype<>arraydef) or
  531. not parraydef(t.resulttype)^.IsConstructor or
  532. (parraydef(t.resulttype)^.lowrange<>0) or
  533. (parraydef(t.resulttype)^.highrange<>len-1) then
  534. t.resulttype:=new(parraydef,init(0,len-1,s32bitdef));
  535. parraydef(t.resulttype)^.elementtype.def:=pd;
  536. parraydef(t.resulttype)^.IsConstructor:=true;
  537. parraydef(t.resulttype)^.IsVariant:=varia;
  538. t.location.loc:=LOC_MEM;
  539. end;
  540. begin
  541. { are we allowing array constructor? Then convert it to a set }
  542. if not allow_array_constructor then
  543. begin
  544. hp:=tarrayconstructnode(getcopy);
  545. arrayconstructor_to_set(hp);
  546. firstpass(hp);
  547. pass_1:=hp;
  548. exit;
  549. end;
  550. { only pass left tree, right tree contains next construct if any }
  551. pd:=constructdef;
  552. len:=0;
  553. varia:=false;
  554. if assigned(left) then
  555. begin
  556. hp:=self;
  557. while assigned(hp) do
  558. begin
  559. firstpass(hp.left);
  560. set_varstate(hp.left,true);
  561. if (not get_para_resulttype) and
  562. (not(nf_novariaallowed in flags)) then
  563. begin
  564. case hp.left.resulttype^.deftype of
  565. enumdef :
  566. begin
  567. hp.left:=gentypeconvnode(hp.left,s32bitdef);
  568. firstpass(hp.left);
  569. end;
  570. orddef :
  571. begin
  572. if is_integer(hp.left.resulttype) and
  573. not(is_64bitint(hp.left.resulttype)) then
  574. begin
  575. hp.left:=gentypeconvnode(hp.left,s32bitdef);
  576. firstpass(hp.left);
  577. end;
  578. end;
  579. floatdef :
  580. begin
  581. hp.left:=gentypeconvnode(hp.left,bestrealdef^);
  582. firstpass(hp.left);
  583. end;
  584. stringdef :
  585. begin
  586. if nf_cargs in flags then
  587. begin
  588. hp.left:=gentypeconvnode(hp.left,charpointerdef);
  589. firstpass(hp.left);
  590. end;
  591. end;
  592. procvardef :
  593. begin
  594. hp.left:=gentypeconvnode(hp.left,voidpointerdef);
  595. firstpass(hp.left);
  596. end;
  597. pointerdef,
  598. classrefdef,
  599. objectdef : ;
  600. else
  601. CGMessagePos1(hp.left.fileinfo,type_e_wrong_type_in_array_constructor,hp.left.resulttype^.typename);
  602. end;
  603. end;
  604. if (pd=nil) then
  605. pd:=hp.left.resulttype
  606. else
  607. begin
  608. if ((nf_novariaallowed in flags) or (not varia)) and
  609. (not is_equal(pd,hp.left.resulttype)) then
  610. begin
  611. { if both should be equal try inserting a conversion }
  612. if nf_novariaallowed in flags then
  613. begin
  614. hp.left:=gentypeconvnode(hp.left,pd);
  615. firstpass(hp.left);
  616. end;
  617. varia:=true;
  618. end;
  619. end;
  620. inc(len);
  621. hp:=tarrayconstructnode(hp.right);
  622. end;
  623. { swap the tree for cargs }
  624. if (nf_cargs in flags) and (not(nf_cargswap in flags)) then
  625. begin
  626. chp:=nil;
  627. { we need a copy here, because self is destroyed }
  628. { by firstpass later }
  629. hp:=tarrayconstructnode(getcopy);
  630. while assigned(hp) do
  631. begin
  632. thp:=tarrayconstructnode(hp.right);
  633. hp.right:=chp;
  634. chp:=hp;
  635. hp:=thp;
  636. end;
  637. include(chp.flags,nf_cargs);
  638. include(chp.flags,nf_cargswap);
  639. postprocess(chp);
  640. pass_1:=chp;
  641. exit;
  642. end;
  643. end;
  644. postprocess(self);
  645. end;
  646. {*****************************************************************************
  647. TTYPENODE
  648. *****************************************************************************}
  649. constructor ttypenode.create(t : pdef;sym:ptypesym);
  650. begin
  651. inherited create(typen);
  652. resulttype:=generrordef;
  653. typenodetype:=t;
  654. typenodesym:=sym;
  655. end;
  656. function ttypenode.getcopy : tnode;
  657. var
  658. n : ttypenode;
  659. begin
  660. n:=ttypenode(inherited getcopy);
  661. n.typenodetype:=typenodetype;
  662. n.typenodesym:=typenodesym;
  663. end;
  664. function ttypenode.pass_1 : tnode;
  665. begin
  666. pass_1:=nil;
  667. { do nothing, resulttype is already set }
  668. end;
  669. begin
  670. cloadnode:=tloadnode;
  671. cassignmentnode:=tassignmentnode;
  672. cfuncretnode:=tfuncretnode;
  673. carrayconstructorrangenode:=tarrayconstructorrangenode;
  674. carrayconstructnode:=tarrayconstructnode;
  675. ctypenode:=ttypenode;
  676. end.
  677. {
  678. $Log$
  679. Revision 1.5 2000-10-01 19:48:24 peter
  680. * lot of compile updates for cg11
  681. Revision 1.4 2000/09/28 19:49:52 florian
  682. *** empty log message ***
  683. Revision 1.3 2000/09/27 18:14:31 florian
  684. * fixed a lot of syntax errors in the n*.pas stuff
  685. Revision 1.2 2000/09/25 15:37:14 florian
  686. * more fixes
  687. Revision 1.1 2000/09/25 14:55:05 florian
  688. * initial revision
  689. }