pass_1.pas 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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. ;
  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. { run firstpass }
  147. firstpass(hp);
  148. { switch to new node }
  149. p:=hp;
  150. end;
  151. if codegenerror then
  152. include(p.flags,nf_error)
  153. else
  154. begin
  155. {$ifdef EXTDEBUG}
  156. if (p.expectloc=LOC_INVALID) then
  157. Comment(V_Warning,'Expectloc is not set in firstpass: '+nodetype2str[p.nodetype]);
  158. {$endif EXTDEBUG}
  159. end;
  160. end;
  161. codegenerror:=codegenerror or oldcodegenerror;
  162. aktlocalswitches:=oldlocalswitches;
  163. aktfilepos:=oldpos;
  164. end
  165. else
  166. codegenerror:=true;
  167. end;
  168. function do_firstpass(var p : tnode) : boolean;
  169. begin
  170. codegenerror:=false;
  171. firstpass(p);
  172. {$ifdef state_tracking}
  173. writeln('TRACKSTART');
  174. writeln('before');
  175. writenode(p);
  176. do_track_state_pass(p);
  177. writeln('after');
  178. writenode(p);
  179. writeln('TRACKDONE');
  180. {$endif}
  181. do_firstpass:=codegenerror;
  182. end;
  183. {$ifdef state_tracking}
  184. procedure do_track_state_pass(p:Tnode);
  185. begin
  186. aktstate:=Tstate_storage.create;
  187. p.track_state_pass(true);
  188. aktstate.destroy;
  189. end;
  190. {$endif}
  191. end.
  192. {
  193. $Log$
  194. Revision 1.31 2003-09-23 17:56:05 peter
  195. * locals and paras are allocated in the code generation
  196. * tvarsym.localloc contains the location of para/local when
  197. generating code for the current procedure
  198. Revision 1.30 2003/04/22 23:50:23 peter
  199. * firstpass uses expectloc
  200. * checks if there are differences between the expectloc and
  201. location.loc from secondpass in EXTDEBUG
  202. Revision 1.29 2002/12/17 22:19:33 peter
  203. * fixed pushing of records>8 bytes with stdcall
  204. * simplified hightree loading
  205. Revision 1.28 2002/09/05 19:28:30 peter
  206. * removed repetitive pass counting
  207. * display heapsize also for extdebug
  208. Revision 1.27 2002/07/19 12:55:27 daniel
  209. * Further developed state tracking in whilerepeatn
  210. Revision 1.26 2002/07/19 11:41:36 daniel
  211. * State tracker work
  212. * The whilen and repeatn are now completely unified into whilerepeatn. This
  213. allows the state tracker to change while nodes automatically into
  214. repeat nodes.
  215. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  216. 'not(a>b)' is optimized into 'a<=b'.
  217. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  218. by removing the notn and later switchting the true and falselabels. The
  219. same is done with 'repeat until not a'.
  220. Revision 1.25 2002/07/14 18:00:44 daniel
  221. + Added the beginning of a state tracker. This will track the values of
  222. variables through procedures and optimize things away.
  223. Revision 1.24 2002/06/16 08:15:54 carl
  224. * commented out uncompilable debug code
  225. Revision 1.23 2002/05/18 13:34:11 peter
  226. * readded missing revisions
  227. Revision 1.22 2002/05/16 19:46:42 carl
  228. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  229. + try to fix temp allocation (still in ifdef)
  230. + generic constructor calls
  231. + start of tassembler / tmodulebase class cleanup
  232. Revision 1.20 2002/04/04 19:06:00 peter
  233. * removed unused units
  234. * use tlocation.size in cg.a_*loc*() routines
  235. Revision 1.19 2002/03/31 20:26:35 jonas
  236. + a_loadfpu_* and a_loadmm_* methods in tcg
  237. * register allocation is now handled by a class and is mostly processor
  238. independent (+rgobj.pas and i386/rgcpu.pas)
  239. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  240. * some small improvements and fixes to the optimizer
  241. * some register allocation fixes
  242. * some fpuvaroffset fixes in the unary minus node
  243. * push/popusedregisters is now called rg.save/restoreusedregisters and
  244. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  245. also better optimizable)
  246. * fixed and optimized register saving/restoring for new/dispose nodes
  247. * LOC_FPU locations now also require their "register" field to be set to
  248. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  249. - list field removed of the tnode class because it's not used currently
  250. and can cause hard-to-find bugs
  251. }