pass_1.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit handles the typecheck and node conversion pass
  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 pass_1;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node;
  23. procedure resulttypepass(var p : tnode);
  24. function do_resulttypepass(var p : tnode) : boolean;
  25. procedure firstpass(var p : tnode);
  26. function do_firstpass(var p : tnode) : boolean;
  27. {$ifdef state_tracking}
  28. procedure do_track_state_pass(p:Tnode);
  29. {$endif}
  30. implementation
  31. uses
  32. globtype,systems,cclasses,
  33. cutils,globals,
  34. cgbase,symdef,
  35. {$ifdef extdebug}
  36. htypechk,
  37. {$endif extdebug}
  38. {$ifdef state_tracking}
  39. nstate,
  40. {$endif}
  41. tgobj
  42. ;
  43. {*****************************************************************************
  44. Global procedures
  45. *****************************************************************************}
  46. procedure resulttypepass(var p : tnode);
  47. var
  48. oldcodegenerror : boolean;
  49. oldlocalswitches : tlocalswitches;
  50. oldpos : tfileposinfo;
  51. hp : tnode;
  52. begin
  53. if (p.resulttype.def=nil) then
  54. begin
  55. oldcodegenerror:=codegenerror;
  56. oldpos:=aktfilepos;
  57. oldlocalswitches:=aktlocalswitches;
  58. codegenerror:=false;
  59. aktfilepos:=p.fileinfo;
  60. aktlocalswitches:=p.localswitches;
  61. hp:=p.det_resulttype;
  62. { should the node be replaced? }
  63. if assigned(hp) then
  64. begin
  65. p.free;
  66. { run resulttypepass }
  67. resulttypepass(hp);
  68. { switch to new node }
  69. p:=hp;
  70. end;
  71. aktlocalswitches:=oldlocalswitches;
  72. aktfilepos:=oldpos;
  73. if codegenerror then
  74. begin
  75. include(p.flags,nf_error);
  76. { default to errortype if no type is set yet }
  77. if p.resulttype.def=nil then
  78. p.resulttype:=generrortype;
  79. end;
  80. codegenerror:=codegenerror or oldcodegenerror;
  81. end
  82. else
  83. begin
  84. { update the codegenerror boolean with the previous result of this node }
  85. if (nf_error in p.flags) then
  86. codegenerror:=true;
  87. end;
  88. end;
  89. function do_resulttypepass(var p : tnode) : boolean;
  90. begin
  91. codegenerror:=false;
  92. resulttypepass(p);
  93. do_resulttypepass:=codegenerror;
  94. end;
  95. procedure firstpass(var p : tnode);
  96. var
  97. oldcodegenerror : boolean;
  98. oldlocalswitches : tlocalswitches;
  99. oldpos : tfileposinfo;
  100. hp : tnode;
  101. begin
  102. if not(nf_error in p.flags) then
  103. begin
  104. oldcodegenerror:=codegenerror;
  105. oldpos:=aktfilepos;
  106. oldlocalswitches:=aktlocalswitches;
  107. codegenerror:=false;
  108. aktfilepos:=p.fileinfo;
  109. aktlocalswitches:=p.localswitches;
  110. { determine the resulttype if not done }
  111. if (p.resulttype.def=nil) then
  112. begin
  113. aktfilepos:=p.fileinfo;
  114. aktlocalswitches:=p.localswitches;
  115. hp:=p.det_resulttype;
  116. { should the node be replaced? }
  117. if assigned(hp) then
  118. begin
  119. p.free;
  120. { run resulttypepass }
  121. resulttypepass(hp);
  122. { switch to new node }
  123. p:=hp;
  124. end;
  125. if codegenerror then
  126. begin
  127. include(p.flags,nf_error);
  128. { default to errortype if no type is set yet }
  129. if p.resulttype.def=nil then
  130. p.resulttype:=generrortype;
  131. end;
  132. aktlocalswitches:=oldlocalswitches;
  133. aktfilepos:=oldpos;
  134. codegenerror:=codegenerror or oldcodegenerror;
  135. end;
  136. if not(nf_error in p.flags) then
  137. begin
  138. { first pass }
  139. aktfilepos:=p.fileinfo;
  140. aktlocalswitches:=p.localswitches;
  141. hp:=p.pass_1;
  142. { should the node be replaced? }
  143. if assigned(hp) then
  144. begin
  145. p.free;
  146. p:=hp;
  147. end;
  148. if codegenerror then
  149. include(p.flags,nf_error);
  150. end;
  151. codegenerror:=codegenerror or oldcodegenerror;
  152. aktlocalswitches:=oldlocalswitches;
  153. aktfilepos:=oldpos;
  154. end
  155. else
  156. codegenerror:=true;
  157. end;
  158. function do_firstpass(var p : tnode) : boolean;
  159. begin
  160. codegenerror:=false;
  161. firstpass(p);
  162. {$ifdef state_tracking}
  163. writeln('TRACKSTART');
  164. writeln('before');
  165. writenode(p);
  166. do_track_state_pass(p);
  167. writeln('after');
  168. writenode(p);
  169. writeln('TRACKDONE');
  170. {$endif}
  171. do_firstpass:=codegenerror;
  172. end;
  173. {$ifdef state_tracking}
  174. procedure do_track_state_pass(p:Tnode);
  175. begin
  176. aktstate:=Tstate_storage.create;
  177. p.track_state_pass(true);
  178. aktstate.destroy;
  179. end;
  180. {$endif}
  181. end.
  182. {
  183. $Log$
  184. Revision 1.28 2002-09-05 19:28:30 peter
  185. * removed repetitive pass counting
  186. * display heapsize also for extdebug
  187. Revision 1.27 2002/07/19 12:55:27 daniel
  188. * Further developed state tracking in whilerepeatn
  189. Revision 1.26 2002/07/19 11:41:36 daniel
  190. * State tracker work
  191. * The whilen and repeatn are now completely unified into whilerepeatn. This
  192. allows the state tracker to change while nodes automatically into
  193. repeat nodes.
  194. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  195. 'not(a>b)' is optimized into 'a<=b'.
  196. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  197. by removing the notn and later switchting the true and falselabels. The
  198. same is done with 'repeat until not a'.
  199. Revision 1.25 2002/07/14 18:00:44 daniel
  200. + Added the beginning of a state tracker. This will track the values of
  201. variables through procedures and optimize things away.
  202. Revision 1.24 2002/06/16 08:15:54 carl
  203. * commented out uncompilable debug code
  204. Revision 1.23 2002/05/18 13:34:11 peter
  205. * readded missing revisions
  206. Revision 1.22 2002/05/16 19:46:42 carl
  207. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  208. + try to fix temp allocation (still in ifdef)
  209. + generic constructor calls
  210. + start of tassembler / tmodulebase class cleanup
  211. Revision 1.20 2002/04/04 19:06:00 peter
  212. * removed unused units
  213. * use tlocation.size in cg.a_*loc*() routines
  214. Revision 1.19 2002/03/31 20:26:35 jonas
  215. + a_loadfpu_* and a_loadmm_* methods in tcg
  216. * register allocation is now handled by a class and is mostly processor
  217. independent (+rgobj.pas and i386/rgcpu.pas)
  218. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  219. * some small improvements and fixes to the optimizer
  220. * some register allocation fixes
  221. * some fpuvaroffset fixes in the unary minus node
  222. * push/popusedregisters is now called rg.save/restoreusedregisters and
  223. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  224. also better optimizable)
  225. * fixed and optimized register saving/restoring for new/dispose nodes
  226. * LOC_FPU locations now also require their "register" field to be set to
  227. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  228. - list field removed of the tnode class because it's not used currently
  229. and can cause hard-to-find bugs
  230. }