pass_1.pas 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit handles the pass_typecheck and node conversion pass
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit pass_1;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node;
  22. procedure typecheckpass(var p : tnode);
  23. function do_typecheckpass(var p : tnode) : boolean;
  24. procedure firstpass(var p : tnode);
  25. function do_firstpass(var p : tnode) : boolean;
  26. {$ifdef state_tracking}
  27. procedure do_track_state_pass(p:Tnode);
  28. {$endif}
  29. implementation
  30. uses
  31. globtype,comphook,systems,cclasses,
  32. cutils,globals,
  33. procinfo,
  34. cgbase,symdef
  35. {$ifdef extdebug}
  36. ,verbose,htypechk
  37. {$endif extdebug}
  38. {$ifdef state_tracking}
  39. ,nstate
  40. {$endif}
  41. ;
  42. {*****************************************************************************
  43. Global procedures
  44. *****************************************************************************}
  45. procedure typecheckpass(var p : tnode);
  46. var
  47. oldcodegenerror : boolean;
  48. oldlocalswitches : tlocalswitches;
  49. oldverbosity : longint;
  50. oldpos : tfileposinfo;
  51. hp : tnode;
  52. begin
  53. if (p.resultdef=nil) then
  54. begin
  55. oldcodegenerror:=codegenerror;
  56. oldpos:=current_filepos;
  57. oldlocalswitches:=current_settings.localswitches;
  58. oldverbosity:=status.verbosity;
  59. codegenerror:=false;
  60. current_filepos:=p.fileinfo;
  61. current_settings.localswitches:=p.localswitches;
  62. status.verbosity:=p.verbosity;
  63. hp:=p.pass_typecheck;
  64. { should the node be replaced? }
  65. if assigned(hp) then
  66. begin
  67. p.free;
  68. { run typecheckpass }
  69. typecheckpass(hp);
  70. { switch to new node }
  71. p:=hp;
  72. end;
  73. current_settings.localswitches:=oldlocalswitches;
  74. current_filepos:=oldpos;
  75. status.verbosity:=oldverbosity;
  76. if codegenerror then
  77. begin
  78. include(p.flags,nf_error);
  79. { default to errortype if no type is set yet }
  80. if p.resultdef=nil then
  81. p.resultdef:=generrordef;
  82. end;
  83. codegenerror:=codegenerror or oldcodegenerror;
  84. end
  85. else
  86. begin
  87. { update the codegenerror boolean with the previous result of this node }
  88. if (nf_error in p.flags) then
  89. codegenerror:=true;
  90. end;
  91. end;
  92. function do_typecheckpass(var p : tnode) : boolean;
  93. begin
  94. codegenerror:=false;
  95. typecheckpass(p);
  96. do_typecheckpass:=codegenerror;
  97. end;
  98. procedure firstpass(var p : tnode);
  99. var
  100. oldcodegenerror : boolean;
  101. oldlocalswitches : tlocalswitches;
  102. oldpos : tfileposinfo;
  103. oldverbosity: longint;
  104. hp : tnode;
  105. begin
  106. if (nf_pass1_done in p.flags) then
  107. exit;
  108. if not(nf_error in p.flags) then
  109. begin
  110. oldcodegenerror:=codegenerror;
  111. oldpos:=current_filepos;
  112. oldlocalswitches:=current_settings.localswitches;
  113. oldverbosity:=status.verbosity;
  114. codegenerror:=false;
  115. current_filepos:=p.fileinfo;
  116. current_settings.localswitches:=p.localswitches;
  117. status.verbosity:=p.verbosity;
  118. { checks make always a call }
  119. if ([cs_check_range,cs_check_overflow,cs_check_stack] * current_settings.localswitches <> []) then
  120. include(current_procinfo.flags,pi_do_call);
  121. { determine the resultdef if not done }
  122. if (p.resultdef=nil) then
  123. begin
  124. hp:=p.pass_typecheck;
  125. { should the node be replaced? }
  126. if assigned(hp) then
  127. begin
  128. p.free;
  129. { run typecheckpass }
  130. typecheckpass(hp);
  131. { switch to new node }
  132. p:=hp;
  133. end;
  134. if codegenerror then
  135. begin
  136. include(p.flags,nf_error);
  137. { default to errortype if no type is set yet }
  138. if p.resultdef=nil then
  139. p.resultdef:=generrordef;
  140. end;
  141. codegenerror:=codegenerror or oldcodegenerror;
  142. end;
  143. if not(nf_error in p.flags) then
  144. begin
  145. { first pass }
  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. else
  157. begin
  158. { inlining happens in pass_1 and can cause new }
  159. { simplify opportunities }
  160. hp:=p.simplify;
  161. if assigned(hp) then
  162. begin
  163. p.free;
  164. firstpass(hp);
  165. p:=hp;
  166. end;
  167. end;
  168. if codegenerror then
  169. include(p.flags,nf_error)
  170. else
  171. begin
  172. {$ifdef EXTDEBUG}
  173. if (p.expectloc=LOC_INVALID) then
  174. Comment(V_Warning,'Expectloc is not set in firstpass: '+nodetype2str[p.nodetype]);
  175. {$endif EXTDEBUG}
  176. end;
  177. end;
  178. include(p.flags,nf_pass1_done);
  179. codegenerror:=codegenerror or oldcodegenerror;
  180. current_settings.localswitches:=oldlocalswitches;
  181. current_filepos:=oldpos;
  182. status.verbosity:=oldverbosity;
  183. end
  184. else
  185. codegenerror:=true;
  186. end;
  187. function do_firstpass(var p : tnode) : boolean;
  188. begin
  189. codegenerror:=false;
  190. firstpass(p);
  191. {$ifdef state_tracking}
  192. writeln('TRACKSTART');
  193. writeln('before');
  194. writenode(p);
  195. do_track_state_pass(p);
  196. writeln('after');
  197. writenode(p);
  198. writeln('TRACKDONE');
  199. {$endif}
  200. do_firstpass:=codegenerror;
  201. end;
  202. {$ifdef state_tracking}
  203. procedure do_track_state_pass(p:Tnode);
  204. begin
  205. aktstate:=Tstate_storage.create;
  206. p.track_state_pass(true);
  207. aktstate.destroy;
  208. end;
  209. {$endif}
  210. end.