2
0

pass_1.pas 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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,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. oldpos : tfileposinfo;
  50. hp : tnode;
  51. begin
  52. if (p.resultdef=nil) then
  53. begin
  54. oldcodegenerror:=codegenerror;
  55. oldpos:=current_filepos;
  56. oldlocalswitches:=current_settings.localswitches;
  57. codegenerror:=false;
  58. current_filepos:=p.fileinfo;
  59. current_settings.localswitches:=p.localswitches;
  60. hp:=p.pass_typecheck;
  61. { should the node be replaced? }
  62. if assigned(hp) then
  63. begin
  64. p.free;
  65. { run typecheckpass }
  66. typecheckpass(hp);
  67. { switch to new node }
  68. p:=hp;
  69. end;
  70. current_settings.localswitches:=oldlocalswitches;
  71. current_filepos:=oldpos;
  72. if codegenerror then
  73. begin
  74. include(p.flags,nf_error);
  75. { default to errortype if no type is set yet }
  76. if p.resultdef=nil then
  77. p.resultdef:=generrordef;
  78. end;
  79. codegenerror:=codegenerror or oldcodegenerror;
  80. end
  81. else
  82. begin
  83. { update the codegenerror boolean with the previous result of this node }
  84. if (nf_error in p.flags) then
  85. codegenerror:=true;
  86. end;
  87. end;
  88. function do_typecheckpass(var p : tnode) : boolean;
  89. begin
  90. codegenerror:=false;
  91. typecheckpass(p);
  92. do_typecheckpass:=codegenerror;
  93. end;
  94. procedure firstpass(var p : tnode);
  95. var
  96. oldcodegenerror : boolean;
  97. oldlocalswitches : tlocalswitches;
  98. oldpos : tfileposinfo;
  99. hp : tnode;
  100. begin
  101. if (nf_pass1_done in p.flags) then
  102. exit;
  103. if not(nf_error in p.flags) then
  104. begin
  105. oldcodegenerror:=codegenerror;
  106. oldpos:=current_filepos;
  107. oldlocalswitches:=current_settings.localswitches;
  108. codegenerror:=false;
  109. current_filepos:=p.fileinfo;
  110. current_settings.localswitches:=p.localswitches;
  111. { checks make always a call }
  112. if ([cs_check_range,cs_check_overflow,cs_check_stack] * current_settings.localswitches <> []) then
  113. include(current_procinfo.flags,pi_do_call);
  114. { determine the resultdef if not done }
  115. if (p.resultdef=nil) then
  116. begin
  117. current_filepos:=p.fileinfo;
  118. current_settings.localswitches:=p.localswitches;
  119. hp:=p.pass_typecheck;
  120. { should the node be replaced? }
  121. if assigned(hp) then
  122. begin
  123. p.free;
  124. { run typecheckpass }
  125. typecheckpass(hp);
  126. { switch to new node }
  127. p:=hp;
  128. end;
  129. if codegenerror then
  130. begin
  131. include(p.flags,nf_error);
  132. { default to errortype if no type is set yet }
  133. if p.resultdef=nil then
  134. p.resultdef:=generrordef;
  135. end;
  136. current_settings.localswitches:=oldlocalswitches;
  137. current_filepos:=oldpos;
  138. codegenerror:=codegenerror or oldcodegenerror;
  139. end;
  140. if not(nf_error in p.flags) then
  141. begin
  142. { first pass }
  143. current_filepos:=p.fileinfo;
  144. current_settings.localswitches:=p.localswitches;
  145. hp:=p.pass_1;
  146. { should the node be replaced? }
  147. if assigned(hp) then
  148. begin
  149. p.free;
  150. { run firstpass }
  151. firstpass(hp);
  152. { switch to new node }
  153. p:=hp;
  154. end;
  155. if codegenerror then
  156. include(p.flags,nf_error)
  157. else
  158. begin
  159. {$ifdef EXTDEBUG}
  160. if (p.expectloc=LOC_INVALID) then
  161. Comment(V_Warning,'Expectloc is not set in firstpass: '+nodetype2str[p.nodetype]);
  162. {$endif EXTDEBUG}
  163. end;
  164. end;
  165. include(p.flags,nf_pass1_done);
  166. codegenerror:=codegenerror or oldcodegenerror;
  167. current_settings.localswitches:=oldlocalswitches;
  168. current_filepos:=oldpos;
  169. end
  170. else
  171. codegenerror:=true;
  172. end;
  173. function do_firstpass(var p : tnode) : boolean;
  174. begin
  175. codegenerror:=false;
  176. firstpass(p);
  177. {$ifdef state_tracking}
  178. writeln('TRACKSTART');
  179. writeln('before');
  180. writenode(p);
  181. do_track_state_pass(p);
  182. writeln('after');
  183. writenode(p);
  184. writeln('TRACKDONE');
  185. {$endif}
  186. do_firstpass:=codegenerror;
  187. end;
  188. {$ifdef state_tracking}
  189. procedure do_track_state_pass(p:Tnode);
  190. begin
  191. aktstate:=Tstate_storage.create;
  192. p.track_state_pass(true);
  193. aktstate.destroy;
  194. end;
  195. {$endif}
  196. end.