pass_1.pas 9.1 KB

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