pass_1.pas 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. procinfo,
  35. cgbase,symdef
  36. {$ifdef extdebug}
  37. ,verbose,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 (nf_pass1_done in p.flags) then
  103. exit;
  104. if not(nf_error in p.flags) then
  105. begin
  106. oldcodegenerror:=codegenerror;
  107. oldpos:=aktfilepos;
  108. oldlocalswitches:=aktlocalswitches;
  109. codegenerror:=false;
  110. aktfilepos:=p.fileinfo;
  111. aktlocalswitches:=p.localswitches;
  112. { checks make always a call }
  113. if ([cs_check_range,cs_check_overflow,cs_check_stack] * aktlocalswitches <> []) then
  114. include(current_procinfo.flags,pi_do_call);
  115. { determine the resulttype if not done }
  116. if (p.resulttype.def=nil) then
  117. begin
  118. aktfilepos:=p.fileinfo;
  119. aktlocalswitches:=p.localswitches;
  120. hp:=p.det_resulttype;
  121. { should the node be replaced? }
  122. if assigned(hp) then
  123. begin
  124. p.free;
  125. { run resulttypepass }
  126. resulttypepass(hp);
  127. { switch to new node }
  128. p:=hp;
  129. end;
  130. if codegenerror then
  131. begin
  132. include(p.flags,nf_error);
  133. { default to errortype if no type is set yet }
  134. if p.resulttype.def=nil then
  135. p.resulttype:=generrortype;
  136. end;
  137. aktlocalswitches:=oldlocalswitches;
  138. aktfilepos:=oldpos;
  139. codegenerror:=codegenerror or oldcodegenerror;
  140. end;
  141. if not(nf_error in p.flags) then
  142. begin
  143. { first pass }
  144. aktfilepos:=p.fileinfo;
  145. aktlocalswitches:=p.localswitches;
  146. hp:=p.pass_1;
  147. { should the node be replaced? }
  148. if assigned(hp) then
  149. begin
  150. p.free;
  151. { run firstpass }
  152. firstpass(hp);
  153. { switch to new node }
  154. p:=hp;
  155. end;
  156. if codegenerror then
  157. include(p.flags,nf_error)
  158. else
  159. begin
  160. {$ifdef EXTDEBUG}
  161. if (p.expectloc=LOC_INVALID) then
  162. Comment(V_Warning,'Expectloc is not set in firstpass: '+nodetype2str[p.nodetype]);
  163. {$endif EXTDEBUG}
  164. end;
  165. end;
  166. include(p.flags,nf_pass1_done);
  167. codegenerror:=codegenerror or oldcodegenerror;
  168. aktlocalswitches:=oldlocalswitches;
  169. aktfilepos:=oldpos;
  170. end
  171. else
  172. codegenerror:=true;
  173. end;
  174. function do_firstpass(var p : tnode) : boolean;
  175. begin
  176. codegenerror:=false;
  177. firstpass(p);
  178. {$ifdef state_tracking}
  179. writeln('TRACKSTART');
  180. writeln('before');
  181. writenode(p);
  182. do_track_state_pass(p);
  183. writeln('after');
  184. writenode(p);
  185. writeln('TRACKDONE');
  186. {$endif}
  187. do_firstpass:=codegenerror;
  188. end;
  189. {$ifdef state_tracking}
  190. procedure do_track_state_pass(p:Tnode);
  191. begin
  192. aktstate:=Tstate_storage.create;
  193. p.track_state_pass(true);
  194. aktstate.destroy;
  195. end;
  196. {$endif}
  197. end.
  198. {
  199. $Log$
  200. Revision 1.33 2004-05-23 15:06:21 peter
  201. * implicit_finally flag must be set in pass1
  202. * add check whether the implicit frame is generated when expected
  203. Revision 1.32 2003/10/01 20:34:49 peter
  204. * procinfo unit contains tprocinfo
  205. * cginfo renamed to cgbase
  206. * moved cgmessage to verbose
  207. * fixed ppc and sparc compiles
  208. Revision 1.31 2003/09/23 17:56:05 peter
  209. * locals and paras are allocated in the code generation
  210. * tvarsym.localloc contains the location of para/local when
  211. generating code for the current procedure
  212. Revision 1.30 2003/04/22 23:50:23 peter
  213. * firstpass uses expectloc
  214. * checks if there are differences between the expectloc and
  215. location.loc from secondpass in EXTDEBUG
  216. Revision 1.29 2002/12/17 22:19:33 peter
  217. * fixed pushing of records>8 bytes with stdcall
  218. * simplified hightree loading
  219. Revision 1.28 2002/09/05 19:28:30 peter
  220. * removed repetitive pass counting
  221. * display heapsize also for extdebug
  222. Revision 1.27 2002/07/19 12:55:27 daniel
  223. * Further developed state tracking in whilerepeatn
  224. Revision 1.26 2002/07/19 11:41:36 daniel
  225. * State tracker work
  226. * The whilen and repeatn are now completely unified into whilerepeatn. This
  227. allows the state tracker to change while nodes automatically into
  228. repeat nodes.
  229. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  230. 'not(a>b)' is optimized into 'a<=b'.
  231. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  232. by removing the notn and later switchting the true and falselabels. The
  233. same is done with 'repeat until not a'.
  234. Revision 1.25 2002/07/14 18:00:44 daniel
  235. + Added the beginning of a state tracker. This will track the values of
  236. variables through procedures and optimize things away.
  237. Revision 1.24 2002/06/16 08:15:54 carl
  238. * commented out uncompilable debug code
  239. Revision 1.23 2002/05/18 13:34:11 peter
  240. * readded missing revisions
  241. Revision 1.22 2002/05/16 19:46:42 carl
  242. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  243. + try to fix temp allocation (still in ifdef)
  244. + generic constructor calls
  245. + start of tassembler / tmodulebase class cleanup
  246. Revision 1.20 2002/04/04 19:06:00 peter
  247. * removed unused units
  248. * use tlocation.size in cg.a_*loc*() routines
  249. Revision 1.19 2002/03/31 20:26:35 jonas
  250. + a_loadfpu_* and a_loadmm_* methods in tcg
  251. * register allocation is now handled by a class and is mostly processor
  252. independent (+rgobj.pas and i386/rgcpu.pas)
  253. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  254. * some small improvements and fixes to the optimizer
  255. * some register allocation fixes
  256. * some fpuvaroffset fixes in the unary minus node
  257. * push/popusedregisters is now called rg.save/restoreusedregisters and
  258. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  259. also better optimizable)
  260. * fixed and optimized register saving/restoring for new/dispose nodes
  261. * LOC_FPU locations now also require their "register" field to be set to
  262. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  263. - list field removed of the tnode class because it's not used currently
  264. and can cause hard-to-find bugs
  265. }