pass_1.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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.34 2004-06-20 08:55:30 florian
  201. * logs truncated
  202. Revision 1.33 2004/05/23 15:06:21 peter
  203. * implicit_finally flag must be set in pass1
  204. * add check whether the implicit frame is generated when expected
  205. }