nld.pas 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415
  1. {
  2. $Id$
  3. Copyright (c) 2000-2002 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 fpcdefs.inc}
  20. interface
  21. uses
  22. node,
  23. {$ifdef state_tracking}
  24. nstate,
  25. {$endif}
  26. symconst,symppu,symbase,symtype,symsym,symdef;
  27. type
  28. tloadnode = class(tunarynode)
  29. symtableentry : tsym;
  30. symtable : tsymtable;
  31. procdef : tprocdef;
  32. constructor create(v : tsym;st : tsymtable);virtual;
  33. constructor create_procvar(v : tsym;d:tprocdef;st : tsymtable);virtual;
  34. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  35. procedure ppuwrite(ppufile:tcompilerppufile);override;
  36. procedure derefimpl;override;
  37. procedure set_mp(p:tnode);
  38. function getcopy : tnode;override;
  39. function pass_1 : tnode;override;
  40. function det_resulttype:tnode;override;
  41. procedure mark_write;override;
  42. function docompare(p: tnode): boolean; override;
  43. procedure printnodedata(var t:text);override;
  44. end;
  45. tloadnodeclass = class of tloadnode;
  46. { different assignment types }
  47. tassigntype = (at_normal,at_plus,at_minus,at_star,at_slash);
  48. tassignmentnode = class(tbinarynode)
  49. assigntype : tassigntype;
  50. constructor create(l,r : tnode);virtual;
  51. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  52. procedure ppuwrite(ppufile:tcompilerppufile);override;
  53. function getcopy : tnode;override;
  54. function pass_1 : tnode;override;
  55. function det_resulttype:tnode;override;
  56. {$ifdef state_tracking}
  57. function track_state_pass(exec_known:boolean):boolean;override;
  58. {$endif state_tracking}
  59. function docompare(p: tnode): boolean; override;
  60. end;
  61. tassignmentnodeclass = class of tassignmentnode;
  62. tarrayconstructorrangenode = class(tbinarynode)
  63. constructor create(l,r : tnode);virtual;
  64. function pass_1 : tnode;override;
  65. function det_resulttype:tnode;override;
  66. end;
  67. tarrayconstructorrangenodeclass = class of tarrayconstructorrangenode;
  68. tarrayconstructornode = class(tbinarynode)
  69. constructor create(l,r : tnode);virtual;
  70. function getcopy : tnode;override;
  71. function pass_1 : tnode;override;
  72. function det_resulttype:tnode;override;
  73. function docompare(p: tnode): boolean; override;
  74. procedure force_type(tt:ttype);
  75. end;
  76. tarrayconstructornodeclass = class of tarrayconstructornode;
  77. ttypenode = class(tnode)
  78. allowed : boolean;
  79. restype : ttype;
  80. constructor create(t : ttype);virtual;
  81. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  82. procedure ppuwrite(ppufile:tcompilerppufile);override;
  83. procedure derefimpl;override;
  84. function pass_1 : tnode;override;
  85. function det_resulttype:tnode;override;
  86. function docompare(p: tnode): boolean; override;
  87. end;
  88. ttypenodeclass = class of ttypenode;
  89. trttinode = class(tnode)
  90. l1,l2 : longint;
  91. rttitype : trttitype;
  92. rttidef : tstoreddef;
  93. constructor create(def:tstoreddef;rt:trttitype);virtual;
  94. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  95. procedure ppuwrite(ppufile:tcompilerppufile);override;
  96. procedure derefimpl;override;
  97. function getcopy : tnode;override;
  98. function pass_1 : tnode;override;
  99. procedure pass_2;override;
  100. function det_resulttype:tnode;override;
  101. function docompare(p: tnode): boolean; override;
  102. end;
  103. trttinodeclass = class of trttinode;
  104. var
  105. cloadnode : tloadnodeclass;
  106. cassignmentnode : tassignmentnodeclass;
  107. carrayconstructorrangenode : tarrayconstructorrangenodeclass;
  108. carrayconstructornode : tarrayconstructornodeclass;
  109. ctypenode : ttypenodeclass;
  110. crttinode : trttinodeclass;
  111. procedure load_procvar_from_calln(var p1:tnode);
  112. function load_high_value(vs:tvarsym):tnode;
  113. function load_self:tnode;
  114. function is_self_node(p:tnode):boolean;
  115. implementation
  116. uses
  117. cutils,verbose,globtype,globals,systems,
  118. symtable,paramgr,defutil,defcmp,
  119. htypechk,pass_1,
  120. ncon,ninl,ncnv,nmem,ncal,cpubase,rgobj,cginfo,cgbase
  121. ,symnot
  122. ;
  123. {*****************************************************************************
  124. Helpers
  125. *****************************************************************************}
  126. procedure load_procvar_from_calln(var p1:tnode);
  127. var
  128. p2 : tnode;
  129. begin
  130. if p1.nodetype<>calln then
  131. internalerror(200212251);
  132. { was it a procvar, then we simply remove the calln and
  133. reuse the right }
  134. if assigned(tcallnode(p1).right) then
  135. begin
  136. p2:=tcallnode(p1).right;
  137. tcallnode(p1).right:=nil;
  138. end
  139. else
  140. begin
  141. p2:=cloadnode.create_procvar(tcallnode(p1).symtableprocentry,
  142. tprocdef(tcallnode(p1).procdefinition),tcallnode(p1).symtableproc);
  143. { when the methodpointer is typen we've something like:
  144. tobject.create. Then only the address is needed of the
  145. method without a self pointer }
  146. if assigned(tcallnode(p1).methodpointer) and
  147. (tcallnode(p1).methodpointer.nodetype<>typen) then
  148. begin
  149. tloadnode(p2).set_mp(tcallnode(p1).methodpointer);
  150. tcallnode(p1).methodpointer:=nil;
  151. end;
  152. end;
  153. resulttypepass(p2);
  154. p1.free;
  155. p1:=p2;
  156. end;
  157. function load_high_value(vs:tvarsym):tnode;
  158. var
  159. srsym : tsym;
  160. srsymtable : tsymtable;
  161. begin
  162. result:=nil;
  163. srsymtable:=vs.owner;
  164. if vo_is_local_copy in vs.varoptions then
  165. begin
  166. { next symtable is always the para symtable }
  167. srsymtable:=srsymtable.next;
  168. if not(srsymtable.symtabletype in [parasymtable,inlineparasymtable]) then
  169. internalerror(200212171);
  170. end;
  171. srsym:=searchsymonlyin(srsymtable,'high'+vs.name);
  172. if assigned(srsym) then
  173. result:=cloadnode.create(srsym,srsymtable)
  174. else
  175. CGMessage(cg_e_illegal_expression);
  176. end;
  177. function load_self:tnode;
  178. var
  179. srsym : tsym;
  180. srsymtable : tsymtable;
  181. begin
  182. result:=nil;
  183. searchsym('self',srsym,srsymtable);
  184. if assigned(srsym) then
  185. result:=cloadnode.create(srsym,srsymtable)
  186. else
  187. CGMessage(cg_e_illegal_expression);
  188. end;
  189. function is_self_node(p:tnode):boolean;
  190. begin
  191. is_self_node:=(p.nodetype=loadn) and
  192. (tloadnode(p).symtableentry.typ=varsym) and
  193. (vo_is_self in tvarsym(tloadnode(p).symtableentry).varoptions);
  194. end;
  195. {*****************************************************************************
  196. TLOADNODE
  197. *****************************************************************************}
  198. constructor tloadnode.create(v : tsym;st : tsymtable);
  199. begin
  200. inherited create(loadn,nil);
  201. if not assigned(v) then
  202. internalerror(200108121);
  203. symtableentry:=v;
  204. symtable:=st;
  205. procdef:=nil;
  206. end;
  207. constructor tloadnode.create_procvar(v : tsym;d:tprocdef;st : tsymtable);
  208. begin
  209. inherited create(loadn,nil);
  210. if not assigned(v) then
  211. internalerror(200108121);
  212. symtableentry:=v;
  213. symtable:=st;
  214. procdef:=d;
  215. end;
  216. constructor tloadnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  217. begin
  218. inherited ppuload(t,ppufile);
  219. symtableentry:=tsym(ppufile.getderef);
  220. symtable:=nil;
  221. procdef:=tprocdef(ppufile.getderef);
  222. end;
  223. procedure tloadnode.ppuwrite(ppufile:tcompilerppufile);
  224. begin
  225. inherited ppuwrite(ppufile);
  226. ppufile.putderef(symtableentry);
  227. ppufile.putderef(procdef);
  228. end;
  229. procedure tloadnode.derefimpl;
  230. begin
  231. inherited derefimpl;
  232. resolvesym(pointer(symtableentry));
  233. symtable:=symtableentry.owner;
  234. resolvedef(pointer(procdef));
  235. end;
  236. procedure tloadnode.set_mp(p:tnode);
  237. begin
  238. { typen nodes should not be set }
  239. if p.nodetype=typen then
  240. internalerror(200301042);
  241. left:=p;
  242. end;
  243. function tloadnode.getcopy : tnode;
  244. var
  245. n : tloadnode;
  246. begin
  247. n:=tloadnode(inherited getcopy);
  248. n.symtable:=symtable;
  249. n.symtableentry:=symtableentry;
  250. result:=n;
  251. end;
  252. function tloadnode.det_resulttype:tnode;
  253. begin
  254. result:=nil;
  255. { handle first absolute as it will replace the symtableentry }
  256. if symtableentry.typ=absolutesym then
  257. begin
  258. { force the resulttype to the type of the absolute }
  259. resulttype:=tabsolutesym(symtableentry).vartype;
  260. { replace the symtableentry when it points to a var, else
  261. we are finished }
  262. if (tabsolutesym(symtableentry).abstyp=tovar) then
  263. begin
  264. symtableentry:=tabsolutesym(symtableentry).ref;
  265. symtable:=symtableentry.owner;
  266. include(flags,nf_absolute);
  267. end
  268. else
  269. exit;
  270. end;
  271. case symtableentry.typ of
  272. constsym:
  273. begin
  274. if tconstsym(symtableentry).consttyp=constresourcestring then
  275. resulttype:=cansistringtype
  276. else
  277. internalerror(22799);
  278. end;
  279. varsym :
  280. begin
  281. { if it's refered by absolute then it's used }
  282. if nf_absolute in flags then
  283. tvarsym(symtableentry).varstate:=vs_used;
  284. { fix self type which is declared as voidpointer in the
  285. definition }
  286. if vo_is_self in tvarsym(symtableentry).varoptions then
  287. begin
  288. if (po_classmethod in tprocdef(symtableentry.owner.defowner).procoptions) or
  289. (po_staticmethod in tprocdef(symtableentry.owner.defowner).procoptions) then
  290. begin
  291. resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
  292. resulttype.setdef(tclassrefdef.create(resulttype));
  293. end
  294. else
  295. resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
  296. end
  297. else
  298. resulttype:=tvarsym(symtableentry).vartype;
  299. end;
  300. typedconstsym :
  301. if not(nf_absolute in flags) then
  302. resulttype:=ttypedconstsym(symtableentry).typedconsttype;
  303. procsym :
  304. begin
  305. if not assigned(procdef) then
  306. begin
  307. if Tprocsym(symtableentry).procdef_count>1 then
  308. CGMessage(parser_e_no_overloaded_procvars);
  309. procdef:=tprocsym(symtableentry).first_procdef;
  310. end;
  311. { Delphi returns Pointer as type }
  312. if not(m_tp_procvar in aktmodeswitches) then
  313. resulttype.setdef(procdef)
  314. else
  315. resulttype:=voidpointertype;
  316. { process methodpointer }
  317. if assigned(left) then
  318. resulttypepass(left);
  319. end;
  320. else
  321. internalerror(200104141);
  322. end;
  323. end;
  324. procedure Tloadnode.mark_write;
  325. begin
  326. include(flags,nf_write);
  327. end;
  328. function tloadnode.pass_1 : tnode;
  329. begin
  330. result:=nil;
  331. expectloc:=LOC_REFERENCE;
  332. registers32:=0;
  333. registersfpu:=0;
  334. {$ifdef SUPPORT_MMX}
  335. registersmmx:=0;
  336. {$endif SUPPORT_MMX}
  337. case symtableentry.typ of
  338. absolutesym :
  339. ;
  340. constsym:
  341. begin
  342. if tconstsym(symtableentry).consttyp=constresourcestring then
  343. begin
  344. include(current_procinfo.flags,pi_needs_implicit_finally);
  345. expectloc:=LOC_CREFERENCE;
  346. end;
  347. end;
  348. varsym :
  349. begin
  350. if (symtable.symtabletype in [parasymtable,localsymtable]) and
  351. (current_procdef.parast.symtablelevel>symtable.symtablelevel) then
  352. begin
  353. { if the variable is in an other stackframe then we need
  354. a register to dereference }
  355. if symtable.symtablelevel>normal_function_level then
  356. begin
  357. registers32:=1;
  358. { further, the variable can't be put into a register }
  359. tvarsym(symtableentry).varoptions:=
  360. tvarsym(symtableentry).varoptions-[vo_fpuregable,vo_regable];
  361. end;
  362. end;
  363. if (tvarsym(symtableentry).varspez=vs_const) then
  364. expectloc:=LOC_CREFERENCE;
  365. { we need a register for call by reference parameters }
  366. if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
  367. ((tvarsym(symtableentry).varspez=vs_const) and
  368. paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,pocall_none)) or
  369. { call by value open arrays are also indirect addressed }
  370. is_open_array(tvarsym(symtableentry).vartype.def) then
  371. registers32:=1;
  372. if ([vo_is_thread_var,vo_is_dll_var]*tvarsym(symtableentry).varoptions)<>[] then
  373. registers32:=1;
  374. if nf_write in flags then
  375. Tvarsym(symtableentry).trigger_notifications(vn_onwrite)
  376. else
  377. Tvarsym(symtableentry).trigger_notifications(vn_onread);
  378. { count variable references }
  379. if rg.t_times<1 then
  380. inc(tvarsym(symtableentry).refs)
  381. else
  382. inc(tvarsym(symtableentry).refs,rg.t_times);
  383. end;
  384. typedconstsym :
  385. ;
  386. procsym :
  387. begin
  388. { method pointer ? }
  389. if assigned(left) then
  390. begin
  391. expectloc:=LOC_CREFERENCE;
  392. firstpass(left);
  393. registers32:=max(registers32,left.registers32);
  394. registersfpu:=max(registersfpu,left.registersfpu);
  395. {$ifdef SUPPORT_MMX}
  396. registersmmx:=max(registersmmx,left.registersmmx);
  397. {$endif SUPPORT_MMX}
  398. end;
  399. end;
  400. else
  401. internalerror(200104143);
  402. end;
  403. end;
  404. function tloadnode.docompare(p: tnode): boolean;
  405. begin
  406. docompare :=
  407. inherited docompare(p) and
  408. (symtableentry = tloadnode(p).symtableentry) and
  409. (symtable = tloadnode(p).symtable);
  410. end;
  411. procedure Tloadnode.printnodedata(var t:text);
  412. begin
  413. inherited printnodedata(t);
  414. writeln(t,printnodeindention,'symbol = ',symtableentry.name);
  415. end;
  416. {*****************************************************************************
  417. TASSIGNMENTNODE
  418. *****************************************************************************}
  419. constructor tassignmentnode.create(l,r : tnode);
  420. begin
  421. inherited create(assignn,l,r);
  422. l.mark_write;
  423. assigntype:=at_normal;
  424. end;
  425. constructor tassignmentnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  426. begin
  427. inherited ppuload(t,ppufile);
  428. assigntype:=tassigntype(ppufile.getbyte);
  429. end;
  430. procedure tassignmentnode.ppuwrite(ppufile:tcompilerppufile);
  431. begin
  432. inherited ppuwrite(ppufile);
  433. ppufile.putbyte(byte(assigntype));
  434. end;
  435. function tassignmentnode.getcopy : tnode;
  436. var
  437. n : tassignmentnode;
  438. begin
  439. n:=tassignmentnode(inherited getcopy);
  440. n.assigntype:=assigntype;
  441. getcopy:=n;
  442. end;
  443. function tassignmentnode.det_resulttype:tnode;
  444. var
  445. hp : tnode;
  446. useshelper : boolean;
  447. original_size : longint;
  448. begin
  449. result:=nil;
  450. resulttype:=voidtype;
  451. original_size := 0;
  452. { must be made unique }
  453. set_unique(left);
  454. resulttypepass(left);
  455. if is_ansistring(left.resulttype.def) then
  456. begin
  457. { fold <ansistring>:=<ansistring>+<char|shortstring|ansistring> }
  458. if (right.nodetype=addn) and
  459. left.isequal(tbinarynode(right).left) and
  460. { don't fold multiple concatenations else we could get trouble
  461. with multiple uses of s
  462. }
  463. (tbinarynode(right).left.nodetype<>addn) and
  464. (tbinarynode(right).right.nodetype<>addn) then
  465. begin
  466. { don't do a resulttypepass(right), since then the addnode }
  467. { may insert typeconversions that make this optimization }
  468. { opportunity quite difficult to detect (JM) }
  469. resulttypepass(tbinarynode(right).left);
  470. resulttypepass(tbinarynode(right).right);
  471. if (is_char(tbinarynode(right).right.resulttype.def) or
  472. is_shortstring(tbinarynode(right).right.resulttype.def) or
  473. is_ansistring(tbinarynode(right).right.resulttype.def)) then
  474. begin
  475. { remove property flag so it'll not trigger an error }
  476. exclude(left.flags,nf_isproperty);
  477. { generate call to helper }
  478. hp:=ccallparanode.create(tbinarynode(right).right,
  479. ccallparanode.create(left,nil));
  480. if is_char(tbinarynode(right).right.resulttype.def) then
  481. result:=ccallnode.createintern('fpc_ansistr_append_char',hp)
  482. else if is_shortstring(tbinarynode(right).right.resulttype.def) then
  483. result:=ccallnode.createintern('fpc_ansistr_append_shortstring',hp)
  484. else
  485. result:=ccallnode.createintern('fpc_ansistr_append_ansistring',hp);
  486. tbinarynode(right).right:=nil;
  487. left:=nil;
  488. exit;
  489. end;
  490. end;
  491. end;
  492. resulttypepass(right);
  493. set_varstate(left,false);
  494. set_varstate(right,true);
  495. { set_funcret_is_valid(left); }
  496. if codegenerror then
  497. exit;
  498. { assignments to open arrays aren't allowed }
  499. if is_open_array(left.resulttype.def) then
  500. CGMessage(type_e_mismatch);
  501. { test if node can be assigned, properties are allowed }
  502. valid_for_assignment(left);
  503. { assigning nil to a dynamic array clears the array }
  504. if is_dynamic_array(left.resulttype.def) and
  505. (right.nodetype=niln) then
  506. begin
  507. hp:=ccallparanode.create(caddrnode.create
  508. (crttinode.create(tstoreddef(left.resulttype.def),initrtti)),
  509. ccallparanode.create(ctypeconvnode.create_explicit(left,voidpointertype),nil));
  510. result := ccallnode.createintern('fpc_dynarray_clear',hp);
  511. left:=nil;
  512. exit;
  513. end;
  514. { shortstring helpers can do the conversion directly,
  515. so treat them separatly }
  516. if (is_shortstring(left.resulttype.def)) then
  517. begin
  518. { test for s:=s+anything ... }
  519. { the problem is for
  520. s:=s+s+s;
  521. this is broken here !! }
  522. {$ifdef newoptimizations2}
  523. { the above is fixed now, but still problem with s := s + f(); if }
  524. { f modifies s (bad programming, so only enable if uncertain }
  525. { optimizations are on) (JM) }
  526. if (cs_UncertainOpts in aktglobalswitches) then
  527. begin
  528. hp := right;
  529. while hp.treetype=addn do
  530. hp:=hp.left;
  531. if left.docompare(hp) then
  532. begin
  533. concat_string:=true;
  534. hp:=right;
  535. while hp.treetype=addn do
  536. begin
  537. hp.use_strconcat:=true;
  538. hp:=hp.left;
  539. end;
  540. end;
  541. end;
  542. {$endif newoptimizations2}
  543. { insert typeconv, except for chars that are handled in
  544. secondpass and except for ansi/wide string that can
  545. be converted immediatly }
  546. if not(is_char(right.resulttype.def) or
  547. (right.resulttype.def.deftype=stringdef)) then
  548. inserttypeconv(right,left.resulttype);
  549. if right.resulttype.def.deftype=stringdef then
  550. begin
  551. useshelper:=true;
  552. { convert constant strings to shortstrings. But
  553. skip empty constant strings, that will be handled
  554. in secondpass }
  555. if (right.nodetype=stringconstn) then
  556. begin
  557. { verify if range fits within shortstring }
  558. { just emit a warning, delphi gives an }
  559. { error, only if the type definition of }
  560. { of the string is less < 255 characters }
  561. if not is_open_string(left.resulttype.def) and
  562. (tstringconstnode(right).len > tstringdef(left.resulttype.def).len) then
  563. cgmessage(type_w_string_too_long);
  564. inserttypeconv(right,left.resulttype);
  565. if (tstringconstnode(right).len=0) then
  566. useshelper:=false;
  567. end;
  568. if useshelper then
  569. begin
  570. hp:=ccallparanode.create
  571. (right,
  572. ccallparanode.create(cinlinenode.create
  573. (in_high_x,false,left.getcopy),nil));
  574. result:=ccallnode.createinternreturn('fpc_'+tstringdef(right.resulttype.def).stringtypname+'_to_shortstr',hp,left);
  575. left:=nil;
  576. right:=nil;
  577. exit;
  578. end;
  579. end;
  580. end
  581. else
  582. begin
  583. { get the size before the type conversion - check for all nodes }
  584. if assigned(right.resulttype.def) and (right.nodetype in [loadn,vecn,calln]) then
  585. original_size := right.resulttype.def.size;
  586. inserttypeconv(right,left.resulttype);
  587. end;
  588. { check if the assignment may cause a range check error }
  589. { if its not explicit, and only if the values are }
  590. { ordinals, enumdef and floatdef }
  591. if (right.nodetype = typeconvn) and
  592. not (nf_explicit in ttypeconvnode(right).flags) then
  593. begin
  594. if assigned(left.resulttype.def) and
  595. (left.resulttype.def.deftype in [enumdef,orddef,floatdef]) then
  596. begin
  597. if (original_size <> 0) and (left.resulttype.def.size < original_size) then
  598. begin
  599. if (cs_check_range in aktlocalswitches) then
  600. Message(type_w_smaller_possible_range_check)
  601. else
  602. Message(type_h_smaller_possible_range_check);
  603. end;
  604. end;
  605. end;
  606. { call helpers for interface }
  607. if is_interfacecom(left.resulttype.def) then
  608. begin
  609. hp:=ccallparanode.create(ctypeconvnode.create_explicit
  610. (right,voidpointertype),
  611. ccallparanode.create(ctypeconvnode.create_explicit
  612. (left,voidpointertype),nil));
  613. result:=ccallnode.createintern('fpc_intf_assign',hp);
  614. left:=nil;
  615. right:=nil;
  616. exit;
  617. end;
  618. { check if local proc/func is assigned to procvar }
  619. if right.resulttype.def.deftype=procvardef then
  620. test_local_to_procvar(tprocvardef(right.resulttype.def),left.resulttype.def);
  621. end;
  622. function tassignmentnode.pass_1 : tnode;
  623. begin
  624. result:=nil;
  625. expectloc:=LOC_VOID;
  626. firstpass(left);
  627. firstpass(right);
  628. if codegenerror then
  629. exit;
  630. registers32:=left.registers32+right.registers32;
  631. registersfpu:=max(left.registersfpu,right.registersfpu);
  632. {$ifdef SUPPORT_MMX}
  633. registersmmx:=max(left.registersmmx,right.registersmmx);
  634. {$endif SUPPORT_MMX}
  635. end;
  636. function tassignmentnode.docompare(p: tnode): boolean;
  637. begin
  638. docompare :=
  639. inherited docompare(p) and
  640. (assigntype = tassignmentnode(p).assigntype);
  641. end;
  642. {$ifdef state_tracking}
  643. function Tassignmentnode.track_state_pass(exec_known:boolean):boolean;
  644. var se:Tstate_entry;
  645. begin
  646. track_state_pass:=false;
  647. if exec_known then
  648. begin
  649. track_state_pass:=right.track_state_pass(exec_known);
  650. {Force a new resulttype pass.}
  651. right.resulttype.def:=nil;
  652. do_resulttypepass(right);
  653. resulttypepass(right);
  654. aktstate.store_fact(left.getcopy,right.getcopy);
  655. end
  656. else
  657. aktstate.delete_fact(left);
  658. end;
  659. {$endif}
  660. {*****************************************************************************
  661. TARRAYCONSTRUCTORRANGENODE
  662. *****************************************************************************}
  663. constructor tarrayconstructorrangenode.create(l,r : tnode);
  664. begin
  665. inherited create(arrayconstructorrangen,l,r);
  666. end;
  667. function tarrayconstructorrangenode.det_resulttype:tnode;
  668. begin
  669. result:=nil;
  670. resulttypepass(left);
  671. resulttypepass(right);
  672. set_varstate(left,true);
  673. set_varstate(right,true);
  674. if codegenerror then
  675. exit;
  676. resulttype:=left.resulttype;
  677. end;
  678. function tarrayconstructorrangenode.pass_1 : tnode;
  679. begin
  680. firstpass(left);
  681. firstpass(right);
  682. expectloc:=LOC_CREFERENCE;
  683. calcregisters(self,0,0,0);
  684. result:=nil;
  685. end;
  686. {****************************************************************************
  687. TARRAYCONSTRUCTORNODE
  688. *****************************************************************************}
  689. constructor tarrayconstructornode.create(l,r : tnode);
  690. begin
  691. inherited create(arrayconstructorn,l,r);
  692. end;
  693. function tarrayconstructornode.getcopy : tnode;
  694. var
  695. n : tarrayconstructornode;
  696. begin
  697. n:=tarrayconstructornode(inherited getcopy);
  698. result:=n;
  699. end;
  700. function tarrayconstructornode.det_resulttype:tnode;
  701. var
  702. htype : ttype;
  703. hp : tarrayconstructornode;
  704. len : longint;
  705. varia : boolean;
  706. begin
  707. result:=nil;
  708. { are we allowing array constructor? Then convert it to a set }
  709. if not allow_array_constructor then
  710. begin
  711. hp:=tarrayconstructornode(getcopy);
  712. arrayconstructor_to_set(tnode(hp));
  713. result:=hp;
  714. exit;
  715. end;
  716. { only pass left tree, right tree contains next construct if any }
  717. htype.reset;
  718. len:=0;
  719. varia:=false;
  720. if assigned(left) then
  721. begin
  722. hp:=self;
  723. while assigned(hp) do
  724. begin
  725. resulttypepass(hp.left);
  726. set_varstate(hp.left,true);
  727. if (htype.def=nil) then
  728. htype:=hp.left.resulttype
  729. else
  730. begin
  731. if ((nf_novariaallowed in flags) or (not varia)) and
  732. (not equal_defs(htype.def,hp.left.resulttype.def)) then
  733. begin
  734. varia:=true;
  735. end;
  736. end;
  737. inc(len);
  738. hp:=tarrayconstructornode(hp.right);
  739. end;
  740. end;
  741. if not assigned(htype.def) then
  742. htype:=voidtype;
  743. resulttype.setdef(tarraydef.create(0,len-1,s32bittype));
  744. tarraydef(resulttype.def).setelementtype(htype);
  745. tarraydef(resulttype.def).IsConstructor:=true;
  746. tarraydef(resulttype.def).IsVariant:=varia;
  747. end;
  748. procedure tarrayconstructornode.force_type(tt:ttype);
  749. var
  750. hp : tarrayconstructornode;
  751. begin
  752. tarraydef(resulttype.def).setelementtype(tt);
  753. tarraydef(resulttype.def).IsConstructor:=true;
  754. tarraydef(resulttype.def).IsVariant:=false;
  755. if assigned(left) then
  756. begin
  757. hp:=self;
  758. while assigned(hp) do
  759. begin
  760. inserttypeconv(hp.left,tt);
  761. hp:=tarrayconstructornode(hp.right);
  762. end;
  763. end;
  764. end;
  765. function tarrayconstructornode.pass_1 : tnode;
  766. var
  767. thp,
  768. chp,
  769. hp : tarrayconstructornode;
  770. dovariant : boolean;
  771. htype : ttype;
  772. orgflags : tnodeflags;
  773. begin
  774. dovariant:=(nf_forcevaria in flags) or tarraydef(resulttype.def).isvariant;
  775. result:=nil;
  776. { only pass left tree, right tree contains next construct if any }
  777. if assigned(left) then
  778. begin
  779. hp:=self;
  780. while assigned(hp) do
  781. begin
  782. firstpass(hp.left);
  783. { Insert typeconvs for array of const }
  784. if dovariant then
  785. begin
  786. case hp.left.resulttype.def.deftype of
  787. enumdef :
  788. begin
  789. hp.left:=ctypeconvnode.create_explicit(hp.left,s32bittype);
  790. firstpass(hp.left);
  791. end;
  792. arraydef :
  793. begin
  794. hp.left:=ctypeconvnode.create(hp.left,charpointertype);
  795. firstpass(hp.left);
  796. end;
  797. orddef :
  798. begin
  799. if is_integer(hp.left.resulttype.def) and
  800. not(is_64bitint(hp.left.resulttype.def)) then
  801. begin
  802. hp.left:=ctypeconvnode.create(hp.left,s32bittype);
  803. firstpass(hp.left);
  804. end;
  805. end;
  806. floatdef :
  807. begin
  808. { C uses 64bit floats }
  809. if nf_cargs in flags then
  810. hp.left:=ctypeconvnode.create(hp.left,s64floattype)
  811. else
  812. hp.left:=ctypeconvnode.create(hp.left,pbestrealtype^);
  813. firstpass(hp.left);
  814. end;
  815. stringdef :
  816. begin
  817. if nf_cargs in flags then
  818. begin
  819. hp.left:=ctypeconvnode.create(hp.left,charpointertype);
  820. firstpass(hp.left);
  821. end;
  822. end;
  823. procvardef :
  824. begin
  825. hp.left:=ctypeconvnode.create(hp.left,voidpointertype);
  826. firstpass(hp.left);
  827. end;
  828. variantdef,
  829. pointerdef,
  830. classrefdef,
  831. objectdef : ;
  832. else
  833. CGMessagePos1(hp.left.fileinfo,type_e_wrong_type_in_array_constructor,hp.left.resulttype.def.typename);
  834. end;
  835. end;
  836. hp:=tarrayconstructornode(hp.right);
  837. end;
  838. { swap the tree for cargs }
  839. if (nf_cargs in flags) and (not(nf_cargswap in flags)) then
  840. begin
  841. chp:=nil;
  842. { save resulttype }
  843. htype:=resulttype;
  844. { we need a copy here, because self is destroyed }
  845. { by firstpass later }
  846. hp:=tarrayconstructornode(getcopy);
  847. { we also need a copy of the nf_ forcevaria flag to restore }
  848. { later) (JM) }
  849. orgflags := flags * [nf_forcevaria];
  850. while assigned(hp) do
  851. begin
  852. thp:=tarrayconstructornode(hp.right);
  853. hp.right:=chp;
  854. chp:=hp;
  855. hp:=thp;
  856. end;
  857. chp.flags := chp.flags+orgflags;
  858. include(chp.flags,nf_cargs);
  859. include(chp.flags,nf_cargswap);
  860. chp.expectloc:=LOC_CREFERENCE;
  861. calcregisters(chp,0,0,0);
  862. chp.resulttype:=htype;
  863. result:=chp;
  864. exit;
  865. end;
  866. end;
  867. { C style has pushed everything on the stack, so
  868. there is no return value }
  869. if (nf_cargs in flags) then
  870. expectloc:=LOC_VOID
  871. else
  872. expectloc:=LOC_CREFERENCE;
  873. { Calculate registers }
  874. calcregisters(self,0,0,0);
  875. end;
  876. function tarrayconstructornode.docompare(p: tnode): boolean;
  877. begin
  878. docompare :=
  879. inherited docompare(p);
  880. end;
  881. {*****************************************************************************
  882. TTYPENODE
  883. *****************************************************************************}
  884. constructor ttypenode.create(t : ttype);
  885. begin
  886. inherited create(typen);
  887. restype:=t;
  888. allowed:=false;
  889. end;
  890. constructor ttypenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  891. begin
  892. inherited ppuload(t,ppufile);
  893. ppufile.gettype(restype);
  894. allowed:=boolean(ppufile.getbyte);
  895. end;
  896. procedure ttypenode.ppuwrite(ppufile:tcompilerppufile);
  897. begin
  898. inherited ppuwrite(ppufile);
  899. ppufile.puttype(restype);
  900. ppufile.putbyte(byte(allowed));
  901. end;
  902. procedure ttypenode.derefimpl;
  903. begin
  904. inherited derefimpl;
  905. restype.resolve;
  906. end;
  907. function ttypenode.det_resulttype:tnode;
  908. begin
  909. result:=nil;
  910. resulttype:=restype;
  911. { check if it's valid }
  912. if restype.def.deftype = errordef then
  913. CGMessage(cg_e_illegal_expression);
  914. end;
  915. function ttypenode.pass_1 : tnode;
  916. begin
  917. result:=nil;
  918. expectloc:=LOC_VOID;
  919. { a typenode can't generate code, so we give here
  920. an error. Else it'll be an abstract error in pass_2.
  921. Only when the allowed flag is set we don't generate
  922. an error }
  923. if not allowed then
  924. Message(parser_e_no_type_not_allowed_here);
  925. end;
  926. function ttypenode.docompare(p: tnode): boolean;
  927. begin
  928. docompare :=
  929. inherited docompare(p);
  930. end;
  931. {*****************************************************************************
  932. TRTTINODE
  933. *****************************************************************************}
  934. constructor trttinode.create(def:tstoreddef;rt:trttitype);
  935. begin
  936. inherited create(rttin);
  937. rttidef:=def;
  938. rttitype:=rt;
  939. end;
  940. constructor trttinode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  941. begin
  942. inherited ppuload(t,ppufile);
  943. rttidef:=tstoreddef(ppufile.getderef);
  944. rttitype:=trttitype(ppufile.getbyte);
  945. end;
  946. procedure trttinode.ppuwrite(ppufile:tcompilerppufile);
  947. begin
  948. inherited ppuwrite(ppufile);
  949. ppufile.putderef(rttidef);
  950. ppufile.putbyte(byte(rttitype));
  951. end;
  952. procedure trttinode.derefimpl;
  953. begin
  954. inherited derefimpl;
  955. resolvedef(pointer(rttidef));
  956. end;
  957. function trttinode.getcopy : tnode;
  958. var
  959. n : trttinode;
  960. begin
  961. n:=trttinode(inherited getcopy);
  962. n.rttidef:=rttidef;
  963. n.rttitype:=rttitype;
  964. result:=n;
  965. end;
  966. function trttinode.det_resulttype:tnode;
  967. begin
  968. { rtti information will be returned as a void pointer }
  969. result:=nil;
  970. resulttype:=voidpointertype;
  971. end;
  972. function trttinode.pass_1 : tnode;
  973. begin
  974. result:=nil;
  975. expectloc:=LOC_CREFERENCE;
  976. end;
  977. function trttinode.docompare(p: tnode): boolean;
  978. begin
  979. docompare :=
  980. inherited docompare(p) and
  981. (rttidef = trttinode(p).rttidef) and
  982. (rttitype = trttinode(p).rttitype);
  983. end;
  984. procedure trttinode.pass_2;
  985. begin
  986. location_reset(location,LOC_CREFERENCE,OS_NO);
  987. location.reference.symbol:=rttidef.get_rtti_label(rttitype);
  988. end;
  989. begin
  990. cloadnode:=tloadnode;
  991. cassignmentnode:=tassignmentnode;
  992. carrayconstructorrangenode:=tarrayconstructorrangenode;
  993. carrayconstructornode:=tarrayconstructornode;
  994. ctypenode:=ttypenode;
  995. crttinode:=trttinode;
  996. end.
  997. {
  998. $Log$
  999. Revision 1.92 2003-05-11 14:45:12 peter
  1000. * tloadnode does not support objectsymtable,withsymtable anymore
  1001. * withnode cleanup
  1002. * direct with rewritten to use temprefnode
  1003. Revision 1.91 2003/05/09 17:47:02 peter
  1004. * self moved to hidden parameter
  1005. * removed hdisposen,hnewn,selfn
  1006. Revision 1.90 2003/04/27 11:21:33 peter
  1007. * aktprocdef renamed to current_procdef
  1008. * procinfo renamed to current_procinfo
  1009. * procinfo will now be stored in current_module so it can be
  1010. cleaned up properly
  1011. * gen_main_procsym changed to create_main_proc and release_main_proc
  1012. to also generate a tprocinfo structure
  1013. * fixed unit implicit initfinal
  1014. Revision 1.89 2003/04/27 07:29:50 peter
  1015. * current_procdef cleanup, current_procdef is now always nil when parsing
  1016. a new procdef declaration
  1017. * aktprocsym removed
  1018. * lexlevel removed, use symtable.symtablelevel instead
  1019. * implicit init/final code uses the normal genentry/genexit
  1020. * funcret state checking updated for new funcret handling
  1021. Revision 1.88 2003/04/26 00:28:42 peter
  1022. * removed load_funcret
  1023. Revision 1.87 2003/04/25 20:59:33 peter
  1024. * removed funcretn,funcretsym, function result is now in varsym
  1025. and aliases for result and function name are added using absolutesym
  1026. * vs_hidden parameter for funcret passed in parameter
  1027. * vs_hidden fixes
  1028. * writenode changed to printnode and released from extdebug
  1029. * -vp option added to generate a tree.log with the nodetree
  1030. * nicer printnode for statements, callnode
  1031. Revision 1.86 2003/04/23 20:16:04 peter
  1032. + added currency support based on int64
  1033. + is_64bit for use in cg units instead of is_64bitint
  1034. * removed cgmessage from n386add, replace with internalerrors
  1035. Revision 1.85 2003/04/23 10:10:54 peter
  1036. * procvar is not compared in addrn
  1037. Revision 1.84 2003/04/22 23:50:23 peter
  1038. * firstpass uses expectloc
  1039. * checks if there are differences between the expectloc and
  1040. location.loc from secondpass in EXTDEBUG
  1041. Revision 1.83 2003/04/11 15:01:23 peter
  1042. * fix bug 2438
  1043. Revision 1.82 2003/03/28 19:16:56 peter
  1044. * generic constructor working for i386
  1045. * remove fixed self register
  1046. * esi added as address register for i386
  1047. Revision 1.81 2003/03/11 21:46:24 jonas
  1048. * lots of new regallocator fixes, both in generic and ppc-specific code
  1049. (ppc compiler still can't compile the linux system unit though)
  1050. Revision 1.80 2003/01/07 16:52:58 jonas
  1051. * fixed ansistring+char and ansistring+shortstring optimizations (those
  1052. cases were always handled as ansistring+ansistring due to
  1053. typeconversions inserted by the add-node)
  1054. Revision 1.79 2003/01/05 22:44:14 peter
  1055. * remove a lot of code to support typen in loadn-procsym
  1056. Revision 1.78 2003/01/03 12:15:56 daniel
  1057. * Removed ifdefs around notifications
  1058. ifdefs around for loop optimizations remain
  1059. Revision 1.77 2002/12/31 09:55:58 daniel
  1060. + Notification implementation complete
  1061. + Add for loop code optimization using notifications
  1062. results in 1.5-1.9% speed improvement in nestloop benchmark
  1063. Optimization incomplete, compiler does not cycle yet with
  1064. notifications enabled.
  1065. Revision 1.76 2002/12/30 22:44:53 daniel
  1066. * Some work on notifications
  1067. Revision 1.75 2002/12/27 15:27:25 peter
  1068. * remove property indicator when calling internal helpers
  1069. Revision 1.74 2002/12/24 16:53:19 peter
  1070. * fix for tb0438
  1071. Revision 1.73 2002/12/20 18:14:53 peter
  1072. * fix result of high_tree when high was not available
  1073. Revision 1.72 2002/12/17 22:19:33 peter
  1074. * fixed pushing of records>8 bytes with stdcall
  1075. * simplified hightree loading
  1076. Revision 1.71 2002/12/07 14:27:07 carl
  1077. * 3% memory optimization
  1078. * changed some types
  1079. + added type checking with different size for call node and for
  1080. parameters
  1081. Revision 1.70 2002/12/02 19:38:06 carl
  1082. * fix some errors
  1083. Revision 1.69 2002/11/29 20:02:44 carl
  1084. * warning / hint for possible loss of data in assignment
  1085. Revision 1.68 2002/11/27 20:04:39 peter
  1086. * cdecl array of const fixes
  1087. Revision 1.67 2002/11/27 15:33:47 peter
  1088. * the never ending story of tp procvar hacks
  1089. Revision 1.66 2002/11/25 17:43:20 peter
  1090. * splitted defbase in defutil,symutil,defcmp
  1091. * merged isconvertable and is_equal into compare_defs(_ext)
  1092. * made operator search faster by walking the list only once
  1093. Revision 1.65 2002/11/18 17:31:57 peter
  1094. * pass proccalloption to ret_in_xxx and push_xxx functions
  1095. Revision 1.64 2002/11/15 01:58:52 peter
  1096. * merged changes from 1.0.7 up to 04-11
  1097. - -V option for generating bug report tracing
  1098. - more tracing for option parsing
  1099. - errors for cdecl and high()
  1100. - win32 import stabs
  1101. - win32 records<=8 are returned in eax:edx (turned off by default)
  1102. - heaptrc update
  1103. - more info for temp management in .s file with EXTDEBUG
  1104. Revision 1.63 2002/10/17 12:44:09 florian
  1105. + s:=s+<string type> where s is an ansistring is done via calls to append_ansistring_*
  1106. Revision 1.62 2002/10/05 12:43:25 carl
  1107. * fixes for Delphi 6 compilation
  1108. (warning : Some features do not work under Delphi)
  1109. Revision 1.61 2002/10/03 21:26:08 carl
  1110. + compile-time range checking for strings
  1111. Revision 1.60 2002/09/27 21:13:28 carl
  1112. * low-highval always checked if limit ober 2GB is reached (to avoid overflow)
  1113. Revision 1.59 2002/09/26 15:02:05 florian
  1114. + support of passing variants to "array of const"
  1115. Revision 1.58 2002/09/07 15:25:03 peter
  1116. * old logs removed and tabs fixed
  1117. Revision 1.57 2002/09/03 16:26:26 daniel
  1118. * Make Tprocdef.defs protected
  1119. Revision 1.56 2002/09/01 13:28:37 daniel
  1120. - write_access fields removed in favor of a flag
  1121. Revision 1.55 2002/09/01 08:01:16 daniel
  1122. * Removed sets from Tcallnode.det_resulttype
  1123. + Added read/write notifications of variables. These will be usefull
  1124. for providing information for several optimizations. For example
  1125. the value of the loop variable of a for loop does matter is the
  1126. variable is read after the for loop, but if it's no longer used
  1127. or written, it doesn't matter and this can be used to optimize
  1128. the loop code generation.
  1129. Revision 1.54 2002/08/25 19:25:19 peter
  1130. * sym.insert_in_data removed
  1131. * symtable.insertvardata/insertconstdata added
  1132. * removed insert_in_data call from symtable.insert, it needs to be
  1133. called separatly. This allows to deref the address calculation
  1134. * procedures now calculate the parast addresses after the procedure
  1135. directives are parsed. This fixes the cdecl parast problem
  1136. * push_addr_param has an extra argument that specifies if cdecl is used
  1137. or not
  1138. Revision 1.53 2002/08/19 19:36:43 peter
  1139. * More fixes for cross unit inlining, all tnodes are now implemented
  1140. * Moved pocall_internconst to po_internconst because it is not a
  1141. calling type at all and it conflicted when inlining of these small
  1142. functions was requested
  1143. Revision 1.52 2002/08/18 20:06:23 peter
  1144. * inlining is now also allowed in interface
  1145. * renamed write/load to ppuwrite/ppuload
  1146. * tnode storing in ppu
  1147. * nld,ncon,nbas are already updated for storing in ppu
  1148. Revision 1.51 2002/08/17 22:09:46 florian
  1149. * result type handling in tcgcal.pass_2 overhauled
  1150. * better tnode.dowrite
  1151. * some ppc stuff fixed
  1152. Revision 1.50 2002/08/17 09:23:37 florian
  1153. * first part of procinfo rewrite
  1154. Revision 1.49 2002/07/20 11:57:54 florian
  1155. * types.pas renamed to defbase.pas because D6 contains a types
  1156. unit so this would conflicts if D6 programms are compiled
  1157. + Willamette/SSE2 instructions to assembler added
  1158. Revision 1.48 2002/07/20 07:44:37 daniel
  1159. * Forgot to add a $ifdef extdebug
  1160. Revision 1.47 2002/07/19 12:55:27 daniel
  1161. * Further developed state tracking in whilerepeatn
  1162. Revision 1.46 2002/07/19 11:41:36 daniel
  1163. * State tracker work
  1164. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1165. allows the state tracker to change while nodes automatically into
  1166. repeat nodes.
  1167. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1168. 'not(a>b)' is optimized into 'a<=b'.
  1169. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1170. by removing the notn and later switchting the true and falselabels. The
  1171. same is done with 'repeat until not a'.
  1172. Revision 1.45 2002/07/15 18:03:15 florian
  1173. * readded removed changes
  1174. Revision 1.43 2002/07/11 14:41:28 florian
  1175. * start of the new generic parameter handling
  1176. Revision 1.44 2002/07/14 18:00:44 daniel
  1177. + Added the beginning of a state tracker. This will track the values of
  1178. variables through procedures and optimize things away.
  1179. Revision 1.42 2002/05/18 13:34:10 peter
  1180. * readded missing revisions
  1181. Revision 1.41 2002/05/16 19:46:38 carl
  1182. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1183. + try to fix temp allocation (still in ifdef)
  1184. + generic constructor calls
  1185. + start of tassembler / tmodulebase class cleanup
  1186. Revision 1.39 2002/05/12 16:53:07 peter
  1187. * moved entry and exitcode to ncgutil and cgobj
  1188. * foreach gets extra argument for passing local data to the
  1189. iterator function
  1190. * -CR checks also class typecasts at runtime by changing them
  1191. into as
  1192. * fixed compiler to cycle with the -CR option
  1193. * fixed stabs with elf writer, finally the global variables can
  1194. be watched
  1195. * removed a lot of routines from cga unit and replaced them by
  1196. calls to cgobj
  1197. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1198. u32bit then the other is typecasted also to u32bit without giving
  1199. a rangecheck warning/error.
  1200. * fixed pascal calling method with reversing also the high tree in
  1201. the parast, detected by tcalcst3 test
  1202. Revision 1.38 2002/04/25 20:16:39 peter
  1203. * moved more routines from cga/n386util
  1204. Revision 1.37 2002/04/23 19:16:34 peter
  1205. * add pinline unit that inserts compiler supported functions using
  1206. one or more statements
  1207. * moved finalize and setlength from ninl to pinline
  1208. }