adlint 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (465) hide show
  1. data/AUTHORS +27 -0
  2. data/COPYING +674 -0
  3. data/ChangeLog +820 -0
  4. data/INSTALL +78 -0
  5. data/MANIFEST +464 -0
  6. data/NEWS +38 -0
  7. data/README +74 -0
  8. data/Rakefile +167 -0
  9. data/TODO +29 -0
  10. data/bin/adlint +141 -0
  11. data/bin/adlint_chk +129 -0
  12. data/bin/adlint_cma +122 -0
  13. data/bin/adlint_sma +129 -0
  14. data/bin/adlintize +286 -0
  15. data/etc/conf.d/fallback/cinit.erb +11 -0
  16. data/etc/conf.d/fallback/traits.erb +216 -0
  17. data/etc/conf.d/i686-cygwin/cinit-gcc_4.3.4.erb +149 -0
  18. data/etc/conf.d/i686-cygwin/traits-gcc_4.3.4.erb +227 -0
  19. data/etc/conf.d/i686-devkit/cinit-gcc_4.5.2.erb +224 -0
  20. data/etc/conf.d/i686-devkit/traits-gcc_4.5.2.erb +226 -0
  21. data/etc/conf.d/i686-linux/cinit-gcc_4.5.1.erb +219 -0
  22. data/etc/conf.d/i686-linux/traits-gcc_4.5.1.erb +224 -0
  23. data/etc/conf.d/i686-mingw/cinit-gcc_4.6.1.erb +234 -0
  24. data/etc/conf.d/i686-mingw/traits-gcc_4.6.1.erb +226 -0
  25. data/etc/conf.d/noarch/GNUmakefile.erb +119 -0
  26. data/etc/conf.d/noarch/adlint_all_bat.erb +9 -0
  27. data/etc/conf.d/noarch/adlint_all_sh.erb +10 -0
  28. data/etc/conf.d/noarch/pinit.erb +11 -0
  29. data/etc/mesg.d/en_US/messages.yml +784 -0
  30. data/etc/mesg.d/ja_JP/messages.yml +784 -0
  31. data/lib/adlint/analyzer.rb +294 -0
  32. data/lib/adlint/c/branch.rb +251 -0
  33. data/lib/adlint/c/builtin.rb +92 -0
  34. data/lib/adlint/c/code.rb +490 -0
  35. data/lib/adlint/c/const.rb +465 -0
  36. data/lib/adlint/c/conv.rb +212 -0
  37. data/lib/adlint/c/ctrlexpr.rb +949 -0
  38. data/lib/adlint/c/domain.rb +7499 -0
  39. data/lib/adlint/c/environ.rb +133 -0
  40. data/lib/adlint/c/expr.rb +1725 -0
  41. data/lib/adlint/c/format.rb +3209 -0
  42. data/lib/adlint/c/interp.rb +1740 -0
  43. data/lib/adlint/c/lexer.rb +241 -0
  44. data/lib/adlint/c/mediator.rb +313 -0
  45. data/lib/adlint/c/message.rb +13597 -0
  46. data/lib/adlint/c/metric.rb +765 -0
  47. data/lib/adlint/c/object.rb +1018 -0
  48. data/lib/adlint/c/parser.rb +3800 -0
  49. data/lib/adlint/c/parser.y +2054 -0
  50. data/lib/adlint/c/phase.rb +712 -0
  51. data/lib/adlint/c/resolver.rb +270 -0
  52. data/lib/adlint/c/scanner.rb +248 -0
  53. data/lib/adlint/c/scope.rb +74 -0
  54. data/lib/adlint/c/syntax.rb +4279 -0
  55. data/lib/adlint/c/type.rb +7506 -0
  56. data/lib/adlint/c/util.rb +91 -0
  57. data/lib/adlint/c/value.rb +2310 -0
  58. data/lib/adlint/c.rb +56 -0
  59. data/lib/adlint/code.rb +500 -0
  60. data/lib/adlint/cpp/code.rb +189 -0
  61. data/lib/adlint/cpp/constexpr.rb +721 -0
  62. data/lib/adlint/cpp/constexpr.y +389 -0
  63. data/lib/adlint/cpp/eval.rb +1012 -0
  64. data/lib/adlint/cpp/lexer.rb +860 -0
  65. data/lib/adlint/cpp/macro.rb +637 -0
  66. data/lib/adlint/cpp/message.rb +992 -0
  67. data/lib/adlint/cpp/phase.rb +176 -0
  68. data/lib/adlint/cpp/scanner.rb +93 -0
  69. data/lib/adlint/cpp/source.rb +169 -0
  70. data/lib/adlint/cpp/subst.rb +300 -0
  71. data/lib/adlint/cpp/syntax.rb +1412 -0
  72. data/lib/adlint/cpp/util.rb +97 -0
  73. data/lib/adlint/cpp.rb +43 -0
  74. data/lib/adlint/driver.rb +147 -0
  75. data/lib/adlint/error.rb +179 -0
  76. data/lib/adlint/lang.rb +97 -0
  77. data/lib/adlint/ld/message.rb +259 -0
  78. data/lib/adlint/ld/metric.rb +57 -0
  79. data/lib/adlint/ld/object.rb +542 -0
  80. data/lib/adlint/ld/phase.rb +193 -0
  81. data/lib/adlint/ld/typedef.rb +109 -0
  82. data/lib/adlint/ld/util.rb +88 -0
  83. data/lib/adlint/ld.rb +37 -0
  84. data/lib/adlint/lexer.rb +293 -0
  85. data/lib/adlint/message.rb +368 -0
  86. data/lib/adlint/metric.rb +805 -0
  87. data/lib/adlint/monitor.rb +144 -0
  88. data/lib/adlint/phase.rb +90 -0
  89. data/lib/adlint/prelude.rb +314 -0
  90. data/lib/adlint/report.rb +617 -0
  91. data/lib/adlint/source.rb +155 -0
  92. data/lib/adlint/symbol.rb +127 -0
  93. data/lib/adlint/token.rb +215 -0
  94. data/lib/adlint/traits.rb +643 -0
  95. data/lib/adlint/util.rb +524 -0
  96. data/lib/adlint/version.rb +71 -0
  97. data/lib/adlint.rb +66 -0
  98. data/share/HEADER +45 -0
  99. data/share/demo/Makefile +110 -0
  100. data/share/demo/ambig_operator/ambig_operator.c +289 -0
  101. data/share/demo/arg_points_unset/arg_points_unset.c +37 -0
  102. data/share/demo/array_range/array_range.c +62 -0
  103. data/share/demo/bad_bitfields/bad_bitfields.c +74 -0
  104. data/share/demo/bad_brace/bad_brace.c +19 -0
  105. data/share/demo/bad_charset/abcde$.h +0 -0
  106. data/share/demo/bad_charset/bad_charset.c +22 -0
  107. data/share/demo/bad_comment/bad_comment.c +3 -0
  108. data/share/demo/bad_const/bad_const.c +19 -0
  109. data/share/demo/bad_conv/bad_conv.c +48 -0
  110. data/share/demo/bad_indent/bad_indent.c +50 -0
  111. data/share/demo/bad_init/bad_init.c +49 -0
  112. data/share/demo/bad_macro/bad_macro.c +97 -0
  113. data/share/demo/bitwise_expr/bitwise_expr.c +19 -0
  114. data/share/demo/call_by_value/call_by_value.c +26 -0
  115. data/share/demo/cross_ref/cross_ref.c +21 -0
  116. data/share/demo/dangling_else/dangling_else.c +20 -0
  117. data/share/demo/dead_code/dead_code.c +237 -0
  118. data/share/demo/deep_nest/deep_nest.c +57 -0
  119. data/share/demo/dense_switch/dense_switch.c +62 -0
  120. data/share/demo/direct_recur/direct_recur.c +15 -0
  121. data/share/demo/div_by_zero/div_by_zero.c +35 -0
  122. data/share/demo/dos_source/dos_source.c +7 -0
  123. data/share/demo/funptr_cast/funptr_cast.c +26 -0
  124. data/share/demo/goto_stmt/goto_stmt.c +19 -0
  125. data/share/demo/id_hiding/id_hiding.c +19 -0
  126. data/share/demo/ill_defined/ill_defined.c +13 -0
  127. data/share/demo/implicit_conv/implicit_conv.c +60 -0
  128. data/share/demo/implicit_int/implicit_int.c +14 -0
  129. data/share/demo/incomplete_type/incomplete_type.c +49 -0
  130. data/share/demo/indirect_recur/indirect_recur_1.c +14 -0
  131. data/share/demo/indirect_recur/indirect_recur_1.h +7 -0
  132. data/share/demo/indirect_recur/indirect_recur_2.c +12 -0
  133. data/share/demo/indirect_recur/indirect_recur_2.h +6 -0
  134. data/share/demo/indirect_recur/indirect_recur_3.c +6 -0
  135. data/share/demo/indirect_recur/indirect_recur_3.h +6 -0
  136. data/share/demo/indirect_recur/indirect_recur_4.c +25 -0
  137. data/share/demo/intro_demo/intro_demo.c +76 -0
  138. data/share/demo/intro_demo/intro_demo.h +12 -0
  139. data/share/demo/intro_demo/useless_header.h +5 -0
  140. data/share/demo/invalid_call/invalid_call.c +32 -0
  141. data/share/demo/kandr_fundef/kandr_fundef.c +10 -0
  142. data/share/demo/line_comment/line_comment.c +12 -0
  143. data/share/demo/local_decl/local_decl.c +9 -0
  144. data/share/demo/logical_trick/logical_trick.c +36 -0
  145. data/share/demo/long_sym/long_sym.c +5 -0
  146. data/share/demo/loop_var/loop_var.c +92 -0
  147. data/share/demo/malloc_or_die/malloc_or_die.c +43 -0
  148. data/share/demo/may_be_null/may_be_null.c +52 -0
  149. data/share/demo/may_be_null_arith/may_be_null_arith.c +15 -0
  150. data/share/demo/may_be_unset/may_be_unset.c +34 -0
  151. data/share/demo/mmapped_io/mmapped_io.c +23 -0
  152. data/share/demo/multi_break/multi_break.c +33 -0
  153. data/share/demo/multi_decl/multi_decl_1.c +17 -0
  154. data/share/demo/multi_decl/multi_decl_1.h +6 -0
  155. data/share/demo/multi_decl/multi_decl_2.c +13 -0
  156. data/share/demo/multi_decl/multi_decl_2.h +6 -0
  157. data/share/demo/multi_decl/multi_decl_3.c +22 -0
  158. data/share/demo/multi_def/multi_def_1.c +36 -0
  159. data/share/demo/multi_def/multi_def_1.h +6 -0
  160. data/share/demo/multi_def/multi_def_2.c +22 -0
  161. data/share/demo/multi_def/multi_def_2.h +6 -0
  162. data/share/demo/multi_def/multi_def_3.c +6 -0
  163. data/share/demo/multi_typedef/multi_typedef.c +11 -0
  164. data/share/demo/multi_typedef/multi_typedef_1.h +1 -0
  165. data/share/demo/multi_typedef/multi_typedef_2.h +1 -0
  166. data/share/demo/must_be_false/must_be_false.c +53 -0
  167. data/share/demo/must_be_null/must_be_null.c +13 -0
  168. data/share/demo/must_be_null_arith/must_be_null_arith.c +14 -0
  169. data/share/demo/must_be_true/must_be_true.c +21 -0
  170. data/share/demo/no_eof_nl/no_eof_nl.c +4 -0
  171. data/share/demo/no_void_arg/no_void_arg.c +14 -0
  172. data/share/demo/null_stmt/null_stmt.c +19 -0
  173. data/share/demo/octal_const/octal_const.c +20 -0
  174. data/share/demo/output_by_param/output_by_param.c +17 -0
  175. data/share/demo/overflow/overflow.c +74 -0
  176. data/share/demo/press_release/press_release.c +40 -0
  177. data/share/demo/retn_lvar_addr/retn_lvar_addr.c +47 -0
  178. data/share/demo/shift_expr/shift_expr.c +14 -0
  179. data/share/demo/should_be_typedef/should_be_typedef.c +51 -0
  180. data/share/demo/static_paths/static_paths.c +153 -0
  181. data/share/demo/static_vars/static_vars.c +39 -0
  182. data/share/demo/tag_hiding/tag_hiding.c +18 -0
  183. data/share/demo/tricky_incdec/tricky_incdec.c +12 -0
  184. data/share/demo/undefined_macro/undefined_macro.c +17 -0
  185. data/share/demo/uninit_vars/uninit_vars.c +28 -0
  186. data/share/demo/union_type/union_type.c +23 -0
  187. data/share/demo/unmatch_decl/unmatch_decl_1.c +12 -0
  188. data/share/demo/unmatch_decl/unmatch_decl_1.h +8 -0
  189. data/share/demo/unmatch_decl/unmatch_decl_2.c +10 -0
  190. data/share/demo/unmatch_decl/unmatch_decl_2.h +8 -0
  191. data/share/demo/unmatch_decl/unmatch_decl_3.c +7 -0
  192. data/share/demo/unmatch_paren_macro/unmatch_paren_macro.c +15 -0
  193. data/share/demo/unreachable/unreachable.c +34 -0
  194. data/share/demo/useless_exp_funs/useless_exp_funs_1.c +14 -0
  195. data/share/demo/useless_exp_funs/useless_exp_funs_1.h +1 -0
  196. data/share/demo/useless_exp_funs/useless_exp_funs_2.c +6 -0
  197. data/share/demo/useless_exp_vars/useless_export_1.c +8 -0
  198. data/share/demo/useless_exp_vars/useless_export_1.h +1 -0
  199. data/share/demo/useless_exp_vars/useless_export_2.c +7 -0
  200. data/share/demo/useless_expr/useless_expr.c +17 -0
  201. data/share/demo/useless_funs/useless_funs_1.c +21 -0
  202. data/share/demo/useless_funs/useless_funs_1.h +8 -0
  203. data/share/demo/useless_funs/useless_funs_2.c +6 -0
  204. data/share/demo/useless_header/useless_header.c +9 -0
  205. data/share/demo/useless_header/useless_header_1.h +12 -0
  206. data/share/demo/useless_header/useless_header_2.h +6 -0
  207. data/share/demo/useless_header/useless_header_3.h +9 -0
  208. data/share/demo/useless_header/useless_header_4.h +3 -0
  209. data/share/demo/useless_vars/useless_vars.c +17 -0
  210. data/share/demo/va_funcall/va_funcall.c +25 -0
  211. data/share/demo/various_fundef/various_fundef.c +36 -0
  212. data/share/demo/wchar_wstring/wchar_wstring.c +7 -0
  213. data/share/demo/wrap_around/wrap_around.c +38 -0
  214. data/share/doc/Makefile +16 -0
  215. data/share/doc/adlint_on_adqua.png +0 -0
  216. data/share/doc/adlint_on_eclipse_en.png +0 -0
  217. data/share/doc/adlint_on_eclipse_ja.png +0 -0
  218. data/share/doc/adlint_on_vim_en.png +0 -0
  219. data/share/doc/adlint_on_vim_ja.png +0 -0
  220. data/share/doc/developers_guide_ja.html +171 -0
  221. data/share/doc/developers_guide_ja.texi +87 -0
  222. data/share/doc/gen_mesg_sections.rb +39 -0
  223. data/share/doc/samples/GNUmakefile +162 -0
  224. data/share/doc/samples/adlint_traits.yml +238 -0
  225. data/share/doc/texinfo.css +22 -0
  226. data/share/doc/users_guide_en.html +39975 -0
  227. data/share/doc/users_guide_en.texi +32640 -0
  228. data/share/doc/users_guide_ja.html +40505 -0
  229. data/share/doc/users_guide_ja.texi +33189 -0
  230. data/share/logo/adlint-110.png +0 -0
  231. data/share/logo/adlint-524.png +0 -0
  232. data/share/logo/adlint.svg +4637 -0
  233. data/share/sample/README +6 -0
  234. data/share/sample/bison-2.5/adlint/GNUmakefile +170 -0
  235. data/share/sample/bison-2.5/adlint/adlint_traits.yml +225 -0
  236. data/share/sample/bison-2.5/adlint/lib/GNUmakefile +198 -0
  237. data/share/sample/bison-2.5/adlint/lib/adlint_cinit.h +228 -0
  238. data/share/sample/bison-2.5/adlint/lib/adlint_pinit.h +21 -0
  239. data/share/sample/bison-2.5/adlint/lib/adlint_traits.yml +238 -0
  240. data/share/sample/bison-2.5/adlint/src/GNUmakefile +166 -0
  241. data/share/sample/bison-2.5/adlint/src/adlint_cinit.h +228 -0
  242. data/share/sample/bison-2.5/adlint/src/adlint_pinit.h +21 -0
  243. data/share/sample/bison-2.5/adlint/src/adlint_traits.yml +239 -0
  244. data/share/sample/ctags-5.8/adlint/GNUmakefile +169 -0
  245. data/share/sample/ctags-5.8/adlint/adlint_cinit.h +219 -0
  246. data/share/sample/ctags-5.8/adlint/adlint_pinit.h +13 -0
  247. data/share/sample/ctags-5.8/adlint/adlint_traits.yml +225 -0
  248. data/share/sample/flex-2.5.35/adlint/GNUmakefile +140 -0
  249. data/share/sample/flex-2.5.35/adlint/adlint_cinit.h +219 -0
  250. data/share/sample/flex-2.5.35/adlint/adlint_pinit.h +14 -0
  251. data/share/sample/flex-2.5.35/adlint/adlint_traits.yml +225 -0
  252. data/share/sample/ruby-1.9.3-p0/adlint/GNUmakefile +314 -0
  253. data/share/sample/ruby-1.9.3-p0/adlint/adlint_traits.yml +225 -0
  254. data/share/sample/ruby-1.9.3-p0/adlint/core/GNUmakefile +204 -0
  255. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_cinit.h +228 -0
  256. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_pinit.h +28 -0
  257. data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_traits.yml +240 -0
  258. data/share/sample/ruby-1.9.3-p0/adlint/enc/GNUmakefile +163 -0
  259. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_cinit.h +228 -0
  260. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_pinit.h +24 -0
  261. data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_traits.yml +240 -0
  262. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/GNUmakefile +149 -0
  263. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_cinit.h +228 -0
  264. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_pinit.h +24 -0
  265. data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_traits.yml +240 -0
  266. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/GNUmakefile +131 -0
  267. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_cinit.h +228 -0
  268. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_pinit.h +24 -0
  269. data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_traits.yml +241 -0
  270. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/GNUmakefile +131 -0
  271. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_cinit.h +228 -0
  272. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_pinit.h +24 -0
  273. data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_traits.yml +241 -0
  274. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/GNUmakefile +131 -0
  275. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_cinit.h +228 -0
  276. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_pinit.h +24 -0
  277. data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_traits.yml +241 -0
  278. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/GNUmakefile +131 -0
  279. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_cinit.h +228 -0
  280. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_pinit.h +24 -0
  281. data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_traits.yml +241 -0
  282. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/GNUmakefile +134 -0
  283. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_cinit.h +228 -0
  284. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_pinit.h +24 -0
  285. data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_traits.yml +241 -0
  286. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/GNUmakefile +131 -0
  287. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_cinit.h +228 -0
  288. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_pinit.h +24 -0
  289. data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_traits.yml +241 -0
  290. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/GNUmakefile +131 -0
  291. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_cinit.h +228 -0
  292. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_pinit.h +24 -0
  293. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_traits.yml +241 -0
  294. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/GNUmakefile +131 -0
  295. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_cinit.h +228 -0
  296. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_pinit.h +24 -0
  297. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_traits.yml +242 -0
  298. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/GNUmakefile +132 -0
  299. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_cinit.h +228 -0
  300. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_pinit.h +24 -0
  301. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_traits.yml +242 -0
  302. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/GNUmakefile +132 -0
  303. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_cinit.h +228 -0
  304. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_pinit.h +24 -0
  305. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_traits.yml +242 -0
  306. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/GNUmakefile +132 -0
  307. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_cinit.h +228 -0
  308. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_pinit.h +24 -0
  309. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_traits.yml +242 -0
  310. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/GNUmakefile +132 -0
  311. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_cinit.h +228 -0
  312. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_pinit.h +24 -0
  313. data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_traits.yml +242 -0
  314. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/GNUmakefile +134 -0
  315. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_cinit.h +228 -0
  316. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_pinit.h +24 -0
  317. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_traits.yml +241 -0
  318. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/GNUmakefile +140 -0
  319. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_cinit.h +228 -0
  320. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_pinit.h +24 -0
  321. data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_traits.yml +242 -0
  322. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/GNUmakefile +131 -0
  323. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_cinit.h +228 -0
  324. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_pinit.h +24 -0
  325. data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_traits.yml +241 -0
  326. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/GNUmakefile +131 -0
  327. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_cinit.h +228 -0
  328. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_pinit.h +24 -0
  329. data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_traits.yml +241 -0
  330. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/GNUmakefile +131 -0
  331. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_cinit.h +228 -0
  332. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_pinit.h +24 -0
  333. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_traits.yml +241 -0
  334. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/GNUmakefile +134 -0
  335. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_cinit.h +228 -0
  336. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_pinit.h +24 -0
  337. data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_traits.yml +242 -0
  338. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/GNUmakefile +131 -0
  339. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_cinit.h +228 -0
  340. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_pinit.h +24 -0
  341. data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_traits.yml +241 -0
  342. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/GNUmakefile +131 -0
  343. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_cinit.h +228 -0
  344. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_pinit.h +24 -0
  345. data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_traits.yml +241 -0
  346. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/GNUmakefile +131 -0
  347. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_cinit.h +228 -0
  348. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_pinit.h +24 -0
  349. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_traits.yml +241 -0
  350. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/GNUmakefile +131 -0
  351. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_cinit.h +228 -0
  352. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_pinit.h +24 -0
  353. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_traits.yml +241 -0
  354. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/GNUmakefile +131 -0
  355. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_cinit.h +228 -0
  356. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_pinit.h +24 -0
  357. data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_traits.yml +241 -0
  358. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/GNUmakefile +131 -0
  359. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_cinit.h +228 -0
  360. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_pinit.h +24 -0
  361. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_traits.yml +241 -0
  362. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/GNUmakefile +131 -0
  363. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_cinit.h +228 -0
  364. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_pinit.h +24 -0
  365. data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_traits.yml +241 -0
  366. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/GNUmakefile +131 -0
  367. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_cinit.h +228 -0
  368. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_pinit.h +24 -0
  369. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_traits.yml +241 -0
  370. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/GNUmakefile +131 -0
  371. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_cinit.h +228 -0
  372. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_pinit.h +24 -0
  373. data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_traits.yml +241 -0
  374. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/GNUmakefile +131 -0
  375. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_cinit.h +228 -0
  376. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_pinit.h +24 -0
  377. data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_traits.yml +241 -0
  378. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/GNUmakefile +162 -0
  379. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_cinit.h +228 -0
  380. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_pinit.h +24 -0
  381. data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_traits.yml +241 -0
  382. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/GNUmakefile +131 -0
  383. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_cinit.h +228 -0
  384. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_pinit.h +24 -0
  385. data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_traits.yml +241 -0
  386. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/GNUmakefile +135 -0
  387. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_cinit.h +228 -0
  388. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_pinit.h +24 -0
  389. data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_traits.yml +241 -0
  390. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/GNUmakefile +131 -0
  391. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_cinit.h +228 -0
  392. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_pinit.h +24 -0
  393. data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_traits.yml +241 -0
  394. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/GNUmakefile +131 -0
  395. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_cinit.h +228 -0
  396. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_pinit.h +24 -0
  397. data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_traits.yml +241 -0
  398. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/GNUmakefile +131 -0
  399. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_cinit.h +228 -0
  400. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_pinit.h +24 -0
  401. data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_traits.yml +241 -0
  402. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/GNUmakefile +131 -0
  403. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_cinit.h +228 -0
  404. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_pinit.h +24 -0
  405. data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_traits.yml +241 -0
  406. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/GNUmakefile +132 -0
  407. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_cinit.h +228 -0
  408. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_pinit.h +24 -0
  409. data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_traits.yml +241 -0
  410. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/GNUmakefile +144 -0
  411. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_cinit.h +228 -0
  412. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_pinit.h +24 -0
  413. data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_traits.yml +241 -0
  414. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/GNUmakefile +131 -0
  415. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_cinit.h +228 -0
  416. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_pinit.h +24 -0
  417. data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_traits.yml +241 -0
  418. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/GNUmakefile +131 -0
  419. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_cinit.h +228 -0
  420. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_pinit.h +24 -0
  421. data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_traits.yml +241 -0
  422. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/GNUmakefile +140 -0
  423. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_cinit.h +228 -0
  424. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_pinit.h +24 -0
  425. data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_traits.yml +241 -0
  426. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/GNUmakefile +131 -0
  427. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_cinit.h +228 -0
  428. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_pinit.h +24 -0
  429. data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_traits.yml +241 -0
  430. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/GNUmakefile +131 -0
  431. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_cinit.h +228 -0
  432. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_pinit.h +24 -0
  433. data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_traits.yml +241 -0
  434. data/share/sample/screen-4.0.3/adlint/GNUmakefile +162 -0
  435. data/share/sample/screen-4.0.3/adlint/adlint_cinit.h +228 -0
  436. data/share/sample/screen-4.0.3/adlint/adlint_pinit.h +21 -0
  437. data/share/sample/screen-4.0.3/adlint/adlint_traits.yml +238 -0
  438. data/share/sample/vim-7.3/adlint/vim/GNUmakefile +185 -0
  439. data/share/sample/vim-7.3/adlint/vim/adlint_cinit.h +228 -0
  440. data/share/sample/vim-7.3/adlint/vim/adlint_pinit.h +25 -0
  441. data/share/sample/vim-7.3/adlint/vim/adlint_traits.yml +250 -0
  442. data/share/sample/vim-7.3/adlint/xxd/GNUmakefile +131 -0
  443. data/share/sample/vim-7.3/adlint/xxd/adlint_cinit.h +228 -0
  444. data/share/sample/vim-7.3/adlint/xxd/adlint_pinit.h +24 -0
  445. data/share/sample/vim-7.3/adlint/xxd/adlint_traits.yml +237 -0
  446. data/share/sample/zsh-4.3.15/adlint/GNUmakefile +146 -0
  447. data/share/sample/zsh-4.3.15/adlint/adlint_traits.yml +225 -0
  448. data/share/sample/zsh-4.3.15/adlint/builtins/GNUmakefile +132 -0
  449. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_cinit.h +228 -0
  450. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_pinit.h +24 -0
  451. data/share/sample/zsh-4.3.15/adlint/builtins/adlint_traits.yml +240 -0
  452. data/share/sample/zsh-4.3.15/adlint/core/GNUmakefile +153 -0
  453. data/share/sample/zsh-4.3.15/adlint/core/adlint_cinit.h +228 -0
  454. data/share/sample/zsh-4.3.15/adlint/core/adlint_pinit.h +23 -0
  455. data/share/sample/zsh-4.3.15/adlint/core/adlint_traits.yml +239 -0
  456. data/share/sample/zsh-4.3.15/adlint/modules/GNUmakefile +147 -0
  457. data/share/sample/zsh-4.3.15/adlint/modules/adlint_cinit.h +228 -0
  458. data/share/sample/zsh-4.3.15/adlint/modules/adlint_pinit.h +24 -0
  459. data/share/sample/zsh-4.3.15/adlint/modules/adlint_traits.yml +240 -0
  460. data/share/sample/zsh-4.3.15/adlint/zle/GNUmakefile +144 -0
  461. data/share/sample/zsh-4.3.15/adlint/zle/adlint_cinit.h +228 -0
  462. data/share/sample/zsh-4.3.15/adlint/zle/adlint_pinit.h +24 -0
  463. data/share/sample/zsh-4.3.15/adlint/zle/adlint_traits.yml +239 -0
  464. data/spec/MUST_WRITE_SPECS_WITH_RSPEC +0 -0
  465. metadata +532 -0
@@ -0,0 +1,1740 @@
1
+ # Kernel of the abstract interpreter of C language.
2
+ #
3
+ # Author:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
4
+ # Copyright:: Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
5
+ # License:: GPLv3+: GNU General Public License version 3 or later
6
+ #
7
+ # Owner:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
8
+
9
+ #--
10
+ # ___ ____ __ ___ _________
11
+ # / | / _ |/ / / / | / /__ __/ Source Code Static Analyzer
12
+ # / /| | / / / / / / / |/ / / / AdLint - Advanced Lint
13
+ # / __ |/ /_/ / /___/ / /| / / /
14
+ # /_/ |_|_____/_____/_/_/ |_/ /_/ Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
15
+ #
16
+ # This file is part of AdLint.
17
+ #
18
+ # AdLint is free software: you can redistribute it and/or modify it under the
19
+ # terms of the GNU General Public License as published by the Free Software
20
+ # Foundation, either version 3 of the License, or (at your option) any later
21
+ # version.
22
+ #
23
+ # AdLint is distributed in the hope that it will be useful, but WITHOUT ANY
24
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
25
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
26
+ #
27
+ # You should have received a copy of the GNU General Public License along with
28
+ # AdLint. If not, see <http://www.gnu.org/licenses/>.
29
+ #
30
+ #++
31
+
32
+ require "adlint/monitor"
33
+ require "adlint/c/environ"
34
+ require "adlint/c/resolver"
35
+ require "adlint/c/mediator"
36
+ require "adlint/c/syntax"
37
+ require "adlint/c/expr"
38
+ require "adlint/c/conv"
39
+ require "adlint/c/util"
40
+
41
+ module AdLint #:nodoc:
42
+ module C #:nodoc:
43
+
44
+ class Interpreter
45
+ include InterpreterMediator
46
+ include Conversion
47
+
48
+ def initialize(type_table)
49
+ type_table = type_table
50
+ @environment = Environment.new(type_table)
51
+ @type_resolver = DynamicTypeResolver.new(type_table, self)
52
+
53
+ @sub_interpreters = [
54
+ TranslationUnitInterpreter.new(self),
55
+ DeclarationInterpreter.new(self),
56
+ ParameterDefinitionInterpreter.new(self),
57
+ FunctionInterpreter.new(self),
58
+ SwitchStatementInterpreter.new(self),
59
+ StatementInterpreter.new(self),
60
+ ExpressionInterpreter.new(self)
61
+ ]
62
+
63
+ @suppress_notification = false
64
+ end
65
+
66
+ attr_reader :environment
67
+ attr_reader :type_resolver
68
+
69
+ extend Pluggable
70
+
71
+ # NOTE: Notified when the interpreter evaluates an initializer of
72
+ # variable-definition.
73
+ def_plugin :on_variable_initialized
74
+
75
+ # NOTE: Notified when the interpreter evaluates a variable-definition.
76
+ def_plugin :on_variable_defined
77
+
78
+ # NOTE: Notified when the interpreter evaluates a function-declaration.
79
+ def_plugin :on_function_declared
80
+
81
+ # NOTE: Notified when the interpreter evaluates a variable-declaration.
82
+ def_plugin :on_variable_declared
83
+
84
+ # NOTE: Notified when the interpreter evaluates a struct-type-declaration.
85
+ def_plugin :on_struct_declared
86
+
87
+ # NOTE: Notified when the interpreter evaluates a union-type-declaration.
88
+ def_plugin :on_union_declared
89
+
90
+ # NOTE: Notified when the interpreter evaluates a enum-type-declaration.
91
+ def_plugin :on_enum_declared
92
+
93
+ # NOTE: Notified when the interpreter evaluates a typedef-declaration.
94
+ def_plugin :on_typedef_declared
95
+
96
+ # NOTE: Notified when the interpreter starts execution of a
97
+ # function-definition.
98
+ def_plugin :on_function_started
99
+
100
+ # NOTE: Notified when the interpreter ends execution of a
101
+ # function-definition.
102
+ def_plugin :on_function_ended
103
+
104
+ # NOTE: Notified when the interpreter evaluates a parameter-definition at
105
+ # beginning of execution of a function-definition.
106
+ def_plugin :on_parameter_defined
107
+
108
+ # NOTE: Notified when the interpreter evaluates an expression which results
109
+ # a named variable.
110
+ def_plugin :on_variable_referred
111
+
112
+ # NOTE: Notified when the interpreter evaluates an expression which results
113
+ # a constant temporary variable.
114
+ def_plugin :on_constant_referred
115
+
116
+ # NOTE: Notified when the interpreter refer to a value of a variable while
117
+ # evaluating an expression.
118
+ def_plugin :on_variable_value_referred
119
+
120
+ # NOTE: Notified when the interpreter overwrite a value of a variable while
121
+ # evaluating an expression.
122
+ def_plugin :on_variable_value_updated
123
+
124
+ # NOTE: Notified when the interpreter refer to a function object while
125
+ # evaluating an expression.
126
+ def_plugin :on_function_referred
127
+
128
+ # NOTE: Notified when the interpreter evaluates a sizeof-expression.
129
+ def_plugin :on_sizeof_expr_evaled
130
+
131
+ # NOTE: Notified when the interpreter evaluates a sizeof-type-expression.
132
+ def_plugin :on_sizeof_type_expr_evaled
133
+
134
+ # NOTE: Notified when the interpreter evaluates a cast-expression.
135
+ def_plugin :on_explicit_conv_performed
136
+
137
+ # NOTE: Notified when the interpreter performs an implicit type conversion
138
+ # while evaluating an expression.
139
+ def_plugin :on_implicit_conv_performed
140
+
141
+ # NOTE: Notified when the interpreter evaluates an
142
+ # array-subscript-expression.
143
+ def_plugin :on_array_subscript_expr_evaled
144
+
145
+ # NOTE: Notified when the interpreter evaluates a function-call-expression.
146
+ def_plugin :on_function_call_expr_evaled
147
+
148
+ # NOTE: Notified when the interpreter evaluates an
149
+ # unary-arithmetic-expression.
150
+ def_plugin :on_unary_arithmetic_expr_evaled
151
+
152
+ # NOTE: Notified when the interpreter evaluates a
153
+ # multiplicative-expression.
154
+ def_plugin :on_multiplicative_expr_evaled
155
+
156
+ # NOTE: Notified when the interpreter evaluates an additive-expression.
157
+ def_plugin :on_additive_expr_evaled
158
+
159
+ # NOTE: Notified when the interpreter evaluates a shift-expression.
160
+ def_plugin :on_shift_expr_evaled
161
+
162
+ # NOTE: Notified when the interpreter evaluates a relational-expression.
163
+ def_plugin :on_relational_expr_evaled
164
+
165
+ # NOTE: Notified when the interpreter evaluates an equality-expression.
166
+ def_plugin :on_equality_expr_evaled
167
+
168
+ # NOTE: Notified when the interpreter evaluates a bitwise and-expression.
169
+ def_plugin :on_and_expr_evaled
170
+
171
+ # NOTE: Notified when the interpreter evaluates an exclusive-or-expression.
172
+ def_plugin :on_exclusive_or_expr_evaled
173
+
174
+ # NOTE: Notified when the interpreter evaluates a bitwise
175
+ # inclusive-or-expression.
176
+ def_plugin :on_inclusive_or_expr_evaled
177
+
178
+ # NOTE: Notified when the interpreter evaluates a logical-and-expression.
179
+ def_plugin :on_logical_and_expr_evaled
180
+
181
+ # NOTE: Notified when the interpreter evaluates a logical-or-expression.
182
+ def_plugin :on_logical_or_expr_evaled
183
+
184
+ # NOTE: Notified when the interpreter evaluates a conditional-expression.
185
+ def_plugin :on_conditional_expr_evaled
186
+
187
+ # NOTE: Notified when the interpreter evaluates an indirection-expression.
188
+ def_plugin :on_indirection_expr_evaled
189
+
190
+ # NOTE: Notified when the interpreter evaluates a
191
+ # member-access-by-value-expression or a
192
+ # member-access-by-pointer-expression.
193
+ def_plugin :on_member_access_expr_evaled
194
+
195
+ # NOTE: Notified when the interpreter evaluates a
196
+ # prefix-increment-expression.
197
+ def_plugin :on_prefix_increment_expr_evaled
198
+
199
+ # NOTE: Notified when the interpreter evaluates a
200
+ # postfix-increment-expression.
201
+ def_plugin :on_postfix_increment_expr_evaled
202
+
203
+ # NOTE: Notified when the interpreter evaluates a
204
+ # prefix-decrement-expression.
205
+ def_plugin :on_prefix_decrement_expr_evaled
206
+
207
+ # NOTE: Notified when the interpreter evaluates a
208
+ # postfix-decrement-expression.
209
+ def_plugin :on_postfix_decrement_expr_evaled
210
+
211
+ # NOTE: Notified when the interpreter evaluates a
212
+ # simple-assignment-expression or a compound-assignment-expression.
213
+ def_plugin :on_assignment_expr_evaled
214
+
215
+ # NOTE: Notified when the interpreter starts execution of a
216
+ # while-statement.
217
+ def_plugin :on_while_stmt_started
218
+
219
+ # NOTE: Notified when the interpreter ends execution of a while-statement.
220
+ def_plugin :on_while_stmt_ended
221
+
222
+ # NOTE: Notified when the interpreter starts execution of a do-statement.
223
+ def_plugin :on_do_stmt_started
224
+
225
+ # NOTE: Notified when the interpreter ends execution of a do-statement.
226
+ def_plugin :on_do_stmt_ended
227
+
228
+ # NOTE: Notified when the interpreter starts execution of a for-statement.
229
+ def_plugin :on_for_stmt_started
230
+
231
+ # NOTE: Notified when the interpreter ends execution of a for-statement.
232
+ def_plugin :on_for_stmt_ended
233
+
234
+ # NOTE: Notified when the interpreter starts execution of a
235
+ # c99-for-statement.
236
+ def_plugin :on_c99_for_stmt_started
237
+
238
+ # NOTE: Notified when the interpreter ends execution of a
239
+ # c99-for-statement.
240
+ def_plugin :on_c99_for_stmt_ended
241
+
242
+ # NOTE: Notified when the interpreter evaluates a goto-statement.
243
+ def_plugin :on_goto_stmt_evaled
244
+
245
+ # NOTE: Notified when the interpreter evaluates a return-statement.
246
+ def_plugin :on_return_stmt_evaled
247
+
248
+ # NOTE: Notified when the interpreter evaluates a controlling expression of
249
+ # the if-statement.
250
+ def_plugin :on_if_ctrlexpr_evaled
251
+
252
+ # NOTE: Notified when the interpreter evaluates a controlling expression of
253
+ # the if-else-statement.
254
+ def_plugin :on_if_else_ctrlexpr_evaled
255
+
256
+ # NOTE: Notified when the interpreter evaluates a controlling expression of
257
+ # the while-statement.
258
+ def_plugin :on_while_ctrlexpr_evaled
259
+
260
+ # NOTE: Notified when the interpreter evaluates a controlling expression of
261
+ # the do-statement.
262
+ def_plugin :on_do_ctrlexpr_evaled
263
+
264
+ # NOTE: Notified when the interpreter evaluates a controlling expression of
265
+ # the for-statement.
266
+ def_plugin :on_for_ctrlexpr_evaled
267
+
268
+ # NOTE: Notified when the interpreter evaluates a controlling expression of
269
+ # the c99-for-statement.
270
+ def_plugin :on_c99_for_ctrlexpr_evaled
271
+
272
+ # NOTE: Notified when the interpreter defines a generic-label.
273
+ def_plugin :on_label_defined
274
+
275
+ # NOTE: Notified when the interpreter starts execution of a
276
+ # compound-statement.
277
+ def_plugin :on_block_started
278
+
279
+ # NOTE: Notified when the interpreter ends execution of a
280
+ # compound-statement.
281
+ def_plugin :on_block_ended
282
+
283
+ # NOTE: Notified when the interpreter forks execution paths of a
284
+ # function-definition.
285
+ def_plugin :on_branch_started
286
+
287
+ # NOTE: Notified when the interpreter joins execution paths of a
288
+ # function-definition.
289
+ def_plugin :on_branch_ended
290
+
291
+ # NOTE: Notified when the interpreter starts execution of a
292
+ # translation-unit.
293
+ def_plugin :on_translation_unit_started
294
+
295
+ # NOTE: Notified when the interpreter ends execution of a translation-unit.
296
+ def_plugin :on_translation_unit_ended
297
+
298
+ def execute(node, *options)
299
+ if options.include?(:suppress_notification)
300
+ @suppress_notification = true
301
+ end
302
+
303
+ node.accept(interpreter_for(node))
304
+
305
+ ensure
306
+ if options.include?(:suppress_notification)
307
+ @suppress_notification = false
308
+ end
309
+ end
310
+
311
+ def object_to_variable(object)
312
+ case
313
+ when object.function?
314
+ temporary_variable(pointer_type(object.type), pointer_value_of(object))
315
+ when object.type.array?
316
+ temporary_variable(pointer_type(object.type.base_type),
317
+ pointer_value_of(object))
318
+ else
319
+ object
320
+ end
321
+ end
322
+
323
+ def value_of(object)
324
+ if object.type.array? || object.type.function?
325
+ pointer_value_of(object)
326
+ else
327
+ object.value.to_single_value
328
+ end
329
+ end
330
+
331
+ def pointer_value_of(object)
332
+ ScalarValue.of(object.binding.memory.address)
333
+ end
334
+
335
+ def notify_variable_initialized(variable_definition,
336
+ variable, init_variable)
337
+ unless @suppress_notification
338
+ on_variable_initialized.invoke(variable_definition,
339
+ variable, init_variable)
340
+ end
341
+ end
342
+
343
+ def notify_variable_defined(variable_definition, variable)
344
+ unless @suppress_notification
345
+ on_variable_defined.invoke(variable_definition, variable)
346
+ end
347
+ end
348
+
349
+ def notify_function_declared(function_declaration, function)
350
+ unless @suppress_notification
351
+ on_function_declared.invoke(function_declaration, function)
352
+ end
353
+ end
354
+
355
+ def notify_variable_declared(variable_declaration, variable)
356
+ unless @suppress_notification
357
+ on_variable_declared.invoke(variable_declaration, variable)
358
+ end
359
+ end
360
+
361
+ def notify_struct_declared(struct_type_declaration)
362
+ unless @suppress_notification
363
+ on_struct_declared.invoke(struct_type_declaration)
364
+ end
365
+ end
366
+
367
+ def notify_union_declared(union_type_declaration)
368
+ unless @suppress_notification
369
+ on_union_declared.invoke(union_type_declaration)
370
+ end
371
+ end
372
+
373
+ def notify_enum_declared(enum_type_declaration)
374
+ unless @suppress_notification
375
+ on_enum_declared.invoke(enum_type_declaration)
376
+ end
377
+ end
378
+
379
+ def notify_typedef_declared(typedef_declaration)
380
+ unless @suppress_notification
381
+ on_typedef_declared.invoke(typedef_declaration)
382
+ end
383
+ end
384
+
385
+ def notify_function_started(function_definition)
386
+ unless @suppress_notification
387
+ on_function_started.invoke(function_definition)
388
+ end
389
+ end
390
+
391
+ def notify_function_ended(function_definition)
392
+ unless @suppress_notification
393
+ on_function_ended.invoke(function_definition)
394
+ end
395
+ end
396
+
397
+ def notify_parameter_defined(parameter_definition, variable)
398
+ unless @suppress_notification
399
+ on_parameter_defined.invoke(parameter_definition, variable)
400
+ end
401
+ end
402
+
403
+ def notify_variable_referred(object_specifier, variable)
404
+ unless @suppress_notification
405
+ on_variable_referred.invoke(object_specifier, variable)
406
+ end
407
+ end
408
+
409
+ def notify_constant_referred(constant_specifier, variable)
410
+ unless @suppress_notification
411
+ on_constant_referred.invoke(constant_specifier, variable)
412
+ end
413
+ end
414
+
415
+ def notify_variable_value_referred(expression, variable)
416
+ unless @suppress_notification
417
+ on_variable_value_referred.invoke(expression, variable)
418
+ end
419
+ end
420
+
421
+ def notify_variable_value_updated(expression, variable)
422
+ unless @suppress_notification
423
+ on_variable_value_updated.invoke(expression, variable)
424
+ end
425
+ end
426
+
427
+ def notify_function_referred(expression, function)
428
+ unless @suppress_notification
429
+ on_function_referred.invoke(expression, function)
430
+ end
431
+ end
432
+
433
+ def notify_sizeof_expr_evaled(expression,
434
+ operand_variable, result_variable)
435
+ unless @suppress_notification
436
+ on_sizeof_expr_evaled.invoke(expression,
437
+ operand_variable, result_variable)
438
+ end
439
+ end
440
+
441
+ def notify_sizeof_type_expr_evaled(expression, type, result_variable)
442
+ unless @suppress_notification
443
+ on_sizeof_type_expr_evaled.invoke(expression, type, result_variable)
444
+ end
445
+ end
446
+
447
+ def notify_explicit_conv_performed(expression,
448
+ original_variable, result_variable)
449
+ unless @suppress_notification
450
+ on_explicit_conv_performed.invoke(expression,
451
+ original_variable, result_variable)
452
+ end
453
+ end
454
+
455
+ def notify_implicit_conv_performed(initializer_or_expression,
456
+ original_variable, result_variable)
457
+ unless @suppress_notification
458
+ on_implicit_conv_performed.invoke(initializer_or_expression,
459
+ original_variable, result_variable)
460
+ end
461
+ end
462
+
463
+ def notify_array_subscript_expr_evaled(array_subscript_expression,
464
+ array_or_pointer_variable,
465
+ subscript_variable,
466
+ array_variable, result_variable)
467
+ unless @suppress_notification
468
+ on_array_subscript_expr_evaled.invoke(array_subscript_expression,
469
+ array_or_pointer_variable,
470
+ subscript_variable,
471
+ array_variable, result_variable)
472
+ end
473
+ end
474
+
475
+ def notify_function_call_expr_evaled(function_call_expression, function,
476
+ arg_variables, result_variable)
477
+ unless @suppress_notification
478
+ on_function_call_expr_evaled.invoke(function_call_expression, function,
479
+ arg_variables, result_variable)
480
+ end
481
+ end
482
+
483
+ def notify_unary_arithmetic_expr_evaled(unary_arithmetic_expression,
484
+ operand_variable, result_variable)
485
+ unless @suppress_notification
486
+ on_unary_arithmetic_expr_evaled.invoke(unary_arithmetic_expression,
487
+ operand_variable,
488
+ result_variable)
489
+ end
490
+ end
491
+
492
+ def notify_multiplicative_expr_evaled(multiplicative_expression,
493
+ lhs_variable, rhs_variable,
494
+ result_variable)
495
+ unless @suppress_notification
496
+ on_multiplicative_expr_evaled.invoke(multiplicative_expression,
497
+ lhs_variable, rhs_variable,
498
+ result_variable)
499
+ end
500
+ end
501
+
502
+ def notify_additive_expr_evaled(additive_expression,
503
+ lhs_variable, rhs_variable,
504
+ result_variable)
505
+ unless @suppress_notification
506
+ on_additive_expr_evaled.invoke(additive_expression,
507
+ lhs_variable, rhs_variable,
508
+ result_variable)
509
+ end
510
+ end
511
+
512
+ def notify_shift_expr_evaled(shift_expression,
513
+ lhs_variable, rhs_variable, result_variable)
514
+ unless @suppress_notification
515
+ on_shift_expr_evaled.invoke(shift_expression,
516
+ lhs_variable, rhs_variable,
517
+ result_variable)
518
+ end
519
+ end
520
+
521
+ def notify_relational_expr_evaled(relational_expression,
522
+ lhs_variable, rhs_variable,
523
+ result_variable)
524
+ unless @suppress_notification
525
+ on_relational_expr_evaled.invoke(relational_expression,
526
+ lhs_variable, rhs_variable,
527
+ result_variable)
528
+ end
529
+ end
530
+
531
+ def notify_equality_expr_evaled(equality_expression,
532
+ lhs_variable, rhs_variable,
533
+ result_variable)
534
+ unless @suppress_notification
535
+ on_equality_expr_evaled.invoke(equality_expression,
536
+ lhs_variable, rhs_variable,
537
+ result_variable)
538
+ end
539
+ end
540
+
541
+ def notify_and_expr_evaled(and_expression,
542
+ lhs_variable, rhs_variable, result_variable)
543
+ unless @suppress_notification
544
+ on_and_expr_evaled.invoke(and_expression,
545
+ lhs_variable, rhs_variable, result_variable)
546
+ end
547
+ end
548
+
549
+ def notify_exclusive_or_expr_evaled(exclusive_or_expression,
550
+ lhs_variable, rhs_variable,
551
+ result_variable)
552
+ unless @suppress_notification
553
+ on_exclusive_or_expr_evaled.invoke(exclusive_or_expression,
554
+ lhs_variable, rhs_variable,
555
+ result_variable)
556
+ end
557
+ end
558
+
559
+ def notify_inclusive_or_expr_evaled(inclusive_or_expression,
560
+ lhs_variable, rhs_variable,
561
+ result_variable)
562
+ unless @suppress_notification
563
+ on_inclusive_or_expr_evaled.invoke(inclusive_or_expression,
564
+ lhs_variable, rhs_variable,
565
+ result_variable)
566
+ end
567
+ end
568
+
569
+ def notify_logical_and_expr_evaled(logical_and_expression,
570
+ lhs_variable, rhs_variable,
571
+ result_variable)
572
+ unless @suppress_notification
573
+ on_logical_and_expr_evaled.invoke(logical_and_expression,
574
+ lhs_variable, rhs_variable,
575
+ result_variable)
576
+ end
577
+ end
578
+
579
+ def notify_logical_or_expr_evaled(logical_or_expression,
580
+ lhs_variable, rhs_variable,
581
+ result_variable)
582
+ unless @suppress_notification
583
+ on_logical_or_expr_evaled.invoke(logical_or_expression,
584
+ lhs_variable, rhs_variable,
585
+ result_variable)
586
+ end
587
+ end
588
+
589
+ def notify_conditional_expr_evaled(conditional_expression,
590
+ condition_variable, result_variable)
591
+ unless @suppress_notification
592
+ on_conditional_expr_evaled.invoke(conditional_expression,
593
+ condition_variable, result_variable)
594
+ end
595
+ end
596
+
597
+ def notify_indirection_expr_evaled(indirection_expression,
598
+ pointer_variable, dereferenced_variable)
599
+ unless @suppress_notification
600
+ on_indirection_expr_evaled.invoke(indirection_expression,
601
+ pointer_variable,
602
+ dereferenced_variable)
603
+ end
604
+ end
605
+
606
+ def notify_member_access_expr_evaled(member_access_expression,
607
+ outer_variable, member_variable)
608
+ unless @suppress_notification
609
+ on_member_access_expr_evaled.invoke(member_access_expression,
610
+ outer_variable, member_variable)
611
+ end
612
+ end
613
+
614
+ def notify_prefix_increment_expr_evaled(prefix_increment_expression,
615
+ operand_variable, original_value)
616
+ unless @suppress_notification
617
+ on_prefix_increment_expr_evaled.invoke(prefix_increment_expression,
618
+ operand_variable,
619
+ original_value)
620
+ end
621
+ end
622
+
623
+ def notify_postfix_increment_expr_evaled(postfix_increment_expression,
624
+ operand_variable, result_variable)
625
+ unless @suppress_notification
626
+ on_postfix_increment_expr_evaled.invoke(postfix_increment_expression,
627
+ operand_variable,
628
+ result_variable)
629
+ end
630
+ end
631
+
632
+ def notify_prefix_decrement_expr_evaled(prefix_decrement_expression,
633
+ operand_variable, original_value)
634
+ unless @suppress_notification
635
+ on_prefix_decrement_expr_evaled.invoke(prefix_decrement_expression,
636
+ operand_variable,
637
+ original_value)
638
+ end
639
+ end
640
+
641
+ def notify_postfix_decrement_expr_evaled(postfix_decrement_expression,
642
+ operand_variable, result_variable)
643
+ unless @suppress_notification
644
+ on_postfix_decrement_expr_evaled.invoke(postfix_decrement_expression,
645
+ operand_variable,
646
+ result_variable)
647
+ end
648
+ end
649
+
650
+ def notify_assignment_expr_evaled(assignment_expression,
651
+ lhs_variable, rhs_variable)
652
+ unless @suppress_notification
653
+ on_assignment_expr_evaled.invoke(assignment_expression,
654
+ lhs_variable, rhs_variable)
655
+ end
656
+ end
657
+
658
+ def notify_while_stmt_started(while_statement)
659
+ unless @suppress_notification
660
+ on_while_stmt_started.invoke(while_statement)
661
+ end
662
+ end
663
+
664
+ def notify_while_stmt_ended(while_statement)
665
+ unless @suppress_notification
666
+ on_while_stmt_ended.invoke(while_statement)
667
+ end
668
+ end
669
+
670
+ def notify_do_stmt_started(do_statement)
671
+ unless @suppress_notification
672
+ on_do_stmt_started.invoke(do_statement)
673
+ end
674
+ end
675
+
676
+ def notify_do_stmt_ended(do_statement)
677
+ unless @suppress_notification
678
+ on_do_stmt_ended.invoke(do_statement)
679
+ end
680
+ end
681
+
682
+ def notify_for_stmt_started(for_statement)
683
+ unless @suppress_notification
684
+ on_for_stmt_started.invoke(for_statement)
685
+ end
686
+ end
687
+
688
+ def notify_for_stmt_ended(for_statement)
689
+ unless @suppress_notification
690
+ on_for_stmt_ended.invoke(for_statement)
691
+ end
692
+ end
693
+
694
+ def notify_c99_for_stmt_started(c99_for_statement)
695
+ unless @suppress_notification
696
+ on_c99_for_stmt_started.invoke(c99_for_statement)
697
+ end
698
+ end
699
+
700
+ def notify_c99_for_stmt_ended(c99_for_statement)
701
+ unless @suppress_notification
702
+ on_c99_for_stmt_ended.invoke(c99_for_statement)
703
+ end
704
+ end
705
+
706
+ def notify_goto_stmt_evaled(goto_statement, label_name)
707
+ unless @suppress_notification
708
+ on_goto_stmt_evaled.invoke(goto_statement, label_name)
709
+ end
710
+ end
711
+
712
+ def notify_return_stmt_evaled(return_statement, result_variable)
713
+ unless @suppress_notification
714
+ on_return_stmt_evaled.invoke(return_statement, result_variable)
715
+ end
716
+ end
717
+
718
+ def notify_if_ctrlexpr_evaled(if_statement, ctrlexpr_value)
719
+ unless @suppress_notification
720
+ on_if_ctrlexpr_evaled.invoke(if_statement, ctrlexpr_value)
721
+ end
722
+ end
723
+
724
+ def notify_if_else_ctrlexpr_evaled(if_else_statement, ctrlexpr_value)
725
+ unless @suppress_notification
726
+ on_if_else_ctrlexpr_evaled.invoke(if_else_statement, ctrlexpr_value)
727
+ end
728
+ end
729
+
730
+ def notify_while_ctrlexpr_evaled(while_statement, ctrlexpr_value)
731
+ unless @suppress_notification
732
+ on_while_ctrlexpr_evaled.invoke(while_statement, ctrlexpr_value)
733
+ end
734
+ end
735
+
736
+ def notify_do_ctrlexpr_evaled(do_statement, ctrlexpr_value)
737
+ unless @suppress_notification
738
+ on_do_ctrlexpr_evaled.invoke(do_statement, ctrlexpr_value)
739
+ end
740
+ end
741
+
742
+ def notify_for_ctrlexpr_evaled(for_statement, ctrlexpr_value)
743
+ unless @suppress_notification
744
+ on_for_ctrlexpr_evaled.invoke(for_statement, ctrlexpr_value)
745
+ end
746
+ end
747
+
748
+ def notify_c99_for_ctrlexpr_evaled(c99_for_statement, ctrlexpr_value)
749
+ unless @suppress_notification
750
+ on_c99_for_ctrlexpr_evaled.invoke(c99_for_statement, ctrlexpr_value)
751
+ end
752
+ end
753
+
754
+ def notify_label_defined(generic_labeled_statement)
755
+ unless @suppress_notification
756
+ on_label_defined.invoke(generic_labeled_statement)
757
+ end
758
+ end
759
+
760
+ def notify_block_started(compound_statement)
761
+ unless @suppress_notification
762
+ on_block_started.invoke(compound_statement)
763
+ end
764
+ end
765
+
766
+ def notify_block_ended(compound_statement)
767
+ unless @suppress_notification
768
+ on_block_ended.invoke(compound_statement)
769
+ end
770
+ end
771
+
772
+ def notify_branch_started(branch)
773
+ unless @suppress_notification
774
+ on_branch_started.invoke(branch)
775
+ end
776
+ end
777
+
778
+ def notify_branch_ended(branch)
779
+ unless @suppress_notification
780
+ on_branch_ended.invoke(branch)
781
+ end
782
+ end
783
+
784
+ def notify_translation_unit_started(translation_unit)
785
+ unless @suppress_notification
786
+ on_translation_unit_started.invoke(translation_unit)
787
+ end
788
+ end
789
+
790
+ def notify_translation_unit_ended(translation_unit)
791
+ unless @suppress_notification
792
+ on_translation_unit_ended.invoke(translation_unit)
793
+ end
794
+ end
795
+
796
+ def _suppress_notification=(suppress_notification)
797
+ # NOTE: This method is called only from ControllingExpression.
798
+ @suppress_notification = suppress_notification
799
+ end
800
+
801
+ private
802
+ def interpreter_for(node)
803
+ @sub_interpreters.find do |interp|
804
+ node.kind_of?(interp.target_node_class)
805
+ end
806
+ end
807
+
808
+ def interpreter
809
+ # NOTE: This method is of the requirement for including
810
+ # InterpreterMediator.
811
+ self
812
+ end
813
+ end
814
+
815
+ class SubInterpreter < SyntaxTreeVisitor
816
+ include InterpreterMediator
817
+ include NotifierMediator
818
+ include Conversion
819
+ include MonitorUtil
820
+
821
+ def initialize(owner, target_node_class)
822
+ @owner = owner
823
+ @target_node_class = target_node_class
824
+ end
825
+
826
+ attr_reader :target_node_class
827
+
828
+ private
829
+ def interpreter
830
+ @owner
831
+ end
832
+ end
833
+
834
+ class TranslationUnitInterpreter < SubInterpreter
835
+ def initialize(owner)
836
+ super(owner, TranslationUnit)
837
+ end
838
+
839
+ def visit_declaration(node)
840
+ checkpoint(node.location)
841
+
842
+ interpret(node)
843
+ end
844
+
845
+ def visit_translation_unit(node)
846
+ checkpoint(node.location)
847
+
848
+ notify_translation_unit_started(node)
849
+ super
850
+ notify_translation_unit_ended(node)
851
+ end
852
+
853
+ def visit_ansi_function_definition(node)
854
+ checkpoint(node.location)
855
+
856
+ interpret(node)
857
+ end
858
+
859
+ def visit_kandr_function_definition(node)
860
+ checkpoint(node.location)
861
+
862
+ interpret(node)
863
+ end
864
+ end
865
+
866
+ class DeclarationInterpreter < SubInterpreter
867
+ def initialize(owner)
868
+ super(owner, Declaration)
869
+ end
870
+
871
+ def visit_function_declaration(node)
872
+ checkpoint(node.location)
873
+
874
+ resolve_unresolved_type(node)
875
+
876
+ node.type.declarations.each do |decl|
877
+ decl.mark_as_referred_by(node.identifier)
878
+ end
879
+
880
+ function = define_explicit_function(node)
881
+ notify_function_declared(node, function)
882
+ end
883
+
884
+ def visit_variable_declaration(node)
885
+ checkpoint(node.location)
886
+
887
+ resolve_unresolved_type(node)
888
+
889
+ node.type.declarations.each do |decl|
890
+ decl.mark_as_referred_by(node.identifier)
891
+ end
892
+
893
+ variable = declare_variable(node)
894
+ notify_variable_declared(node, variable)
895
+ end
896
+
897
+ def visit_variable_definition(node)
898
+ checkpoint(node.location)
899
+
900
+ resolve_unresolved_type(node)
901
+
902
+ node.type.declarations.each do |decl|
903
+ decl.mark_as_referred_by(node.identifier)
904
+ end
905
+
906
+ if initializer = node.initializer
907
+ init_variable = evaluate_initializer(initializer, node.type)
908
+
909
+ if node.type.same_as?(init_variable.type)
910
+ converted = init_variable
911
+ else
912
+ converted =
913
+ do_conversion(init_variable, node.type) ||
914
+ temporary_variable(node.type)
915
+ notify_implicit_conv_performed(initializer, init_variable, converted)
916
+ end
917
+
918
+ variable = define_variable(node, converted.value.to_defined_value)
919
+ notify_variable_defined(node, variable)
920
+ notify_variable_initialized(node, variable, init_variable)
921
+ else
922
+ variable = define_variable(node)
923
+ notify_variable_defined(node, variable)
924
+ end
925
+ end
926
+
927
+ def visit_struct_type_declaration(node)
928
+ checkpoint(node.location)
929
+
930
+ resolve_unresolved_type(node)
931
+
932
+ notify_struct_declared(node)
933
+ end
934
+
935
+ def visit_union_type_declaration(node)
936
+ checkpoint(node.location)
937
+
938
+ resolve_unresolved_type(node)
939
+
940
+ notify_union_declared(node)
941
+ end
942
+
943
+ def visit_enum_type_declaration(node)
944
+ checkpoint(node)
945
+
946
+ if enumerators = node.enum_specifier.enumerators
947
+ sequence = 0
948
+ enumerators.each do |enumerator|
949
+ if expression = enumerator.expression
950
+ object = interpret(expression)
951
+ if object.variable? && object.value.scalar?
952
+ enumerator.value = object.value.unique_sample
953
+ end
954
+ end
955
+ enumerator.value ||= sequence
956
+ define_enumerator(enumerator)
957
+ sequence = enumerator.value + 1
958
+ end
959
+ end
960
+
961
+ notify_enum_declared(node)
962
+ end
963
+
964
+ def visit_typedef_declaration(node)
965
+ checkpoint(node.location)
966
+
967
+ resolve_unresolved_type(node)
968
+
969
+ node.type.real_type.declarations.each do |decl|
970
+ decl.mark_as_referred_by(node.identifier)
971
+ end
972
+
973
+ notify_typedef_declared(node)
974
+
975
+ Analyzer.current.info("user type `#{node.identifier.value}' " +
976
+ "defined at #{node.location.to_s}.")
977
+ end
978
+
979
+ private
980
+ def evaluate_initializer(initializer, variable_type)
981
+ init_interp = InitializerInterpreter.new(interpreter)
982
+ object = init_interp.execute(initializer, variable_type)
983
+
984
+ case
985
+ when variable_type.pointer? && object.type.array?
986
+ init_variable = temporary_variable(variable_type,
987
+ pointer_value_of(object))
988
+ notify_implicit_conv_performed(initializer, object, init_variable)
989
+ when variable_type.pointer? && object.type.function?
990
+ init_variable = temporary_variable(variable_type,
991
+ pointer_value_of(object))
992
+ notify_implicit_conv_performed(initializer, object, init_variable)
993
+ when variable_type.array? && object.type.pointer?
994
+ unless init_variable = pointee_of(object) and init_variable.type.array?
995
+ init_variable = temporary_variable(variable_type)
996
+ end
997
+ deduct_array_length_from_array_variable(variable_type, init_variable)
998
+ when object.function?
999
+ init_variable = temporary_variable(variable_type)
1000
+ else
1001
+ init_variable = object
1002
+ end
1003
+
1004
+ init_variable
1005
+ end
1006
+
1007
+ def deduct_array_length_from_array_variable(variable_type, array_variable)
1008
+ variable_type.length ||= array_variable.type.length
1009
+ end
1010
+ end
1011
+
1012
+ class InitializerInterpreter
1013
+ include InterpreterMediator
1014
+ include MonitorUtil
1015
+
1016
+ def initialize(interpreter)
1017
+ @interpreter = interpreter
1018
+ end
1019
+
1020
+ def execute(initializer, variable_type)
1021
+ checkpoint(initializer.location)
1022
+
1023
+ case
1024
+ when expression = initializer.expression
1025
+ evaluate_expression(expression)
1026
+ when initializers = initializer.initializers
1027
+ evaluate_initializers(initializers, variable_type)
1028
+ else
1029
+ temporary_variable(variable_type)
1030
+ end
1031
+ end
1032
+
1033
+ private
1034
+ def evaluate_expression(expression)
1035
+ checkpoint(expression.location)
1036
+
1037
+ object_to_variable(interpret(expression))
1038
+ end
1039
+
1040
+ def evaluate_initializers(initializers, variable_type)
1041
+ case
1042
+ when variable_type.array?
1043
+ deduct_array_length_from_initializers(variable_type, initializers)
1044
+ member_types = [variable_type.base_type] * variable_type.impl_length
1045
+ when variable_type.composite?
1046
+ member_types = variable_type.members.map { |member| member.type }
1047
+ else
1048
+ member_types = [variable_type]
1049
+ end
1050
+
1051
+ values = member_types.zip(initializers).map { |type, initializer|
1052
+ if initializer
1053
+ checkpoint(initializer.location)
1054
+ case
1055
+ when expression = initializer.expression
1056
+ value_of(evaluate_expression(expression))
1057
+ when initializers = initializer.initializers
1058
+ value_of(evaluate_initializers(initializers, type))
1059
+ else
1060
+ type.undefined_value
1061
+ end
1062
+ else
1063
+ type.undefined_value
1064
+ end
1065
+ }
1066
+
1067
+ case
1068
+ when variable_type.array?
1069
+ temporary_variable(variable_type, ArrayValue.new(values))
1070
+ when variable_type.composite?
1071
+ temporary_variable(variable_type, CompositeValue.new(values))
1072
+ else
1073
+ temporary_variable(variable_type, values.first)
1074
+ end
1075
+ end
1076
+
1077
+ def deduct_array_length_from_initializers(variable_type, initializers)
1078
+ variable_type.length ||= initializers.size
1079
+ end
1080
+
1081
+ def interpreter
1082
+ # NOTE: This is private attr_reader for InterpreterMediator.
1083
+ # This attribute is read via a normal method to suppress
1084
+ # `private attribute?' warning.
1085
+ @interpreter
1086
+ end
1087
+ end
1088
+
1089
+ class ParameterDefinitionInterpreter < SubInterpreter
1090
+ def initialize(owner)
1091
+ super(owner, ParameterDefinition)
1092
+ end
1093
+
1094
+ def visit_parameter_definition(node)
1095
+ checkpoint(node.location)
1096
+
1097
+ resolve_unresolved_type(node)
1098
+
1099
+ node.type.declarations.each do |decl|
1100
+ if identifier = node.identifier
1101
+ decl.mark_as_referred_by(identifier)
1102
+ else
1103
+ decl.mark_as_referred_by(node.head_token)
1104
+ end
1105
+ end
1106
+
1107
+ if node.identifier
1108
+ variable = define_variable(node.to_variable_definition,
1109
+ node.type.parameter_value)
1110
+ notify_parameter_defined(node, variable)
1111
+ end
1112
+ end
1113
+ end
1114
+
1115
+ class FunctionInterpreter < SubInterpreter
1116
+ def initialize(owner)
1117
+ super(owner, FunctionDefinition)
1118
+ end
1119
+
1120
+ def visit_ansi_function_definition(node)
1121
+ interpret_function(node)
1122
+ end
1123
+
1124
+ def visit_kandr_function_definition(node)
1125
+ interpret_function(node)
1126
+ end
1127
+
1128
+ private
1129
+ def interpret_function(node)
1130
+ checkpoint(node.location)
1131
+
1132
+ reset_environment
1133
+ resolve_unresolved_type(node)
1134
+
1135
+ if function = function_named(node.identifier.value)
1136
+ function.declarations_and_definitions.each do |decl_or_def|
1137
+ decl_or_def.mark_as_referred_by(node.identifier)
1138
+ end
1139
+ function.declarations_and_definitions.push(node)
1140
+ else
1141
+ function = define_explicit_function(node)
1142
+ end
1143
+
1144
+ scoped_eval do
1145
+ notify_function_started(node)
1146
+ notify_block_started(node.function_body)
1147
+
1148
+ node.parameter_definitions.each { |pdef| interpret(pdef) }
1149
+
1150
+ BreakEvent.catch do
1151
+ node.function_body.block_items.each { |item| interpret(item) }
1152
+ end
1153
+
1154
+ notify_block_ended(node.function_body)
1155
+ notify_function_ended(node)
1156
+ end
1157
+ end
1158
+ end
1159
+
1160
+ class StatementInterpreter < SubInterpreter
1161
+ include BranchGroup::Option
1162
+ include Branch::Option
1163
+ include SyntaxNodeCollector
1164
+
1165
+ def initialize(owner)
1166
+ super(owner, Statement)
1167
+ end
1168
+
1169
+ def visit_generic_labeled_statement(node)
1170
+ checkpoint(node.location)
1171
+
1172
+ node.executed = true
1173
+ notify_label_defined(node)
1174
+
1175
+ uninitialize_block_local_variables(node)
1176
+ interpret(node.statement)
1177
+ end
1178
+
1179
+ def visit_case_labeled_statement(node)
1180
+ checkpoint(node.location)
1181
+
1182
+ node.executed = true
1183
+ interpret(node.statement)
1184
+ end
1185
+
1186
+ def visit_default_labeled_statement(node)
1187
+ checkpoint(node.location)
1188
+
1189
+ node.executed = true
1190
+ interpret(node.statement)
1191
+ end
1192
+
1193
+ def visit_compound_statement(node)
1194
+ checkpoint(node.location)
1195
+
1196
+ node.executed = true
1197
+ scoped_eval do
1198
+ begin
1199
+ notify_block_started(node)
1200
+ node.block_items.each { |block_item| interpret(block_item) }
1201
+ ensure
1202
+ notify_block_ended(node)
1203
+ end
1204
+ end
1205
+ end
1206
+
1207
+ def visit_expression_statement(node)
1208
+ checkpoint(node.location)
1209
+
1210
+ node.executed = true
1211
+ interpret(node.expression) if node.expression
1212
+ end
1213
+
1214
+ def visit_if_statement(node)
1215
+ checkpoint(node.location)
1216
+
1217
+ node.executed = true
1218
+ ctrlexpr = node.expression
1219
+ ctrlexpr_value = value_of(interpret(ctrlexpr, :suppress_notification))
1220
+ notify_if_ctrlexpr_evaled(node, ctrlexpr_value)
1221
+
1222
+ case
1223
+ when ctrlexpr_value.must_be_true?
1224
+ branched_eval(ctrlexpr, NARROWING, FINAL, COMPLETE) do
1225
+ interpret(node.statement)
1226
+ end
1227
+ when ctrlexpr_value.may_be_true?
1228
+ branched_eval(ctrlexpr, NARROWING, FINAL) do
1229
+ interpret(node.statement)
1230
+ end
1231
+ else
1232
+ # NOTE: To warn about the controlling expression and to end the current
1233
+ # branch group of else-if sequence.
1234
+ branched_eval(nil, NARROWING, FINAL) do
1235
+ interpret(ctrlexpr)
1236
+ end
1237
+ end
1238
+ end
1239
+
1240
+ def visit_if_else_statement(node)
1241
+ checkpoint(node.location)
1242
+
1243
+ node.executed = true
1244
+ ctrlexpr = node.expression
1245
+ ctrlexpr_value = value_of(interpret(ctrlexpr, :suppress_notification))
1246
+ notify_if_else_ctrlexpr_evaled(node, ctrlexpr_value)
1247
+
1248
+ case
1249
+ when ctrlexpr_value.must_be_true?
1250
+ branched_eval(ctrlexpr, NARROWING, FINAL, COMPLETE) do
1251
+ interpret(node.then_statement)
1252
+ end
1253
+ return
1254
+ when ctrlexpr_value.may_be_true?
1255
+ branched_eval(ctrlexpr, NARROWING) do
1256
+ interpret(node.then_statement)
1257
+ end
1258
+ else
1259
+ # NOTE: To warn about the controlling expression.
1260
+ interpret(ctrlexpr)
1261
+ end
1262
+
1263
+ case node.else_statement
1264
+ when IfStatement, IfElseStatement
1265
+ interpret(node.else_statement)
1266
+ else
1267
+ branched_eval(nil, NARROWING, FINAL, COMPLETE) do
1268
+ interpret(node.else_statement)
1269
+ end
1270
+ end
1271
+ end
1272
+
1273
+ def visit_while_statement(node)
1274
+ checkpoint(node.location)
1275
+
1276
+ node.executed = true
1277
+ notify_while_stmt_started(node)
1278
+
1279
+ widen_varying_variable_value_domain(node)
1280
+ effective_ctrlexpr = deduct_effective_controlling_expression(node)
1281
+
1282
+ ctrlexpr = node.expression
1283
+ ctrlexpr_value = value_of(interpret(ctrlexpr))
1284
+ notify_while_ctrlexpr_evaled(node, ctrlexpr_value)
1285
+
1286
+ case
1287
+ when ctrlexpr_value.must_be_true?
1288
+ branched_eval(effective_ctrlexpr,
1289
+ NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
1290
+ interpret(node.statement)
1291
+ end
1292
+ when ctrlexpr_value.may_be_true?
1293
+ branched_eval(effective_ctrlexpr,
1294
+ NARROWING, FINAL, IMPLICIT_CONDITION) do
1295
+ interpret(node.statement)
1296
+ end
1297
+ end
1298
+ ensure
1299
+ notify_while_stmt_ended(node)
1300
+ end
1301
+
1302
+ def visit_do_statement(node)
1303
+ checkpoint(node.location)
1304
+
1305
+ node.executed = true
1306
+ notify_do_stmt_started(node)
1307
+
1308
+ widen_varying_variable_value_domain(node)
1309
+ effective_ctrlexpr = deduct_effective_controlling_expression(node)
1310
+
1311
+ branched_eval(effective_ctrlexpr,
1312
+ NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
1313
+ interpret(node.statement)
1314
+ end
1315
+
1316
+ ctrlexpr_value = value_of(interpret(node.expression))
1317
+ notify_do_ctrlexpr_evaled(node, ctrlexpr_value)
1318
+ ensure
1319
+ notify_do_stmt_ended(node)
1320
+ end
1321
+
1322
+ def visit_for_statement(node)
1323
+ checkpoint(node.location)
1324
+
1325
+ node.executed = true
1326
+ notify_for_stmt_started(node)
1327
+
1328
+ node.initial_statement.accept(self)
1329
+
1330
+ widen_varying_variable_value_domain(node)
1331
+ effective_ctrlexpr = deduct_effective_controlling_expression(node)
1332
+
1333
+ node.condition_statement.executed = true
1334
+ if ctrlexpr = node.condition_statement.expression
1335
+ ctrlexpr_value = value_of(interpret(ctrlexpr))
1336
+ notify_for_ctrlexpr_evaled(node, ctrlexpr_value)
1337
+
1338
+ case
1339
+ when ctrlexpr_value.must_be_true?
1340
+ branched_eval(effective_ctrlexpr,
1341
+ NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
1342
+ interpret(node.body_statement)
1343
+ interpret(node.expression) if node.expression
1344
+ end
1345
+ when ctrlexpr_value.may_be_true?
1346
+ branched_eval(effective_ctrlexpr,
1347
+ NARROWING, FINAL, IMPLICIT_CONDITION) do
1348
+ interpret(node.body_statement)
1349
+ interpret(node.expression) if node.expression
1350
+ end
1351
+ end
1352
+ else
1353
+ branched_eval(effective_ctrlexpr,
1354
+ NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
1355
+ interpret(node.body_statement)
1356
+ interpret(node.expression) if node.expression
1357
+ end
1358
+ end
1359
+ ensure
1360
+ notify_for_stmt_ended(node)
1361
+ end
1362
+
1363
+ def visit_c99_for_statement(node)
1364
+ checkpoint(node.location)
1365
+
1366
+ scoped_eval do
1367
+ interpret(node.declaration)
1368
+
1369
+ node.executed = true
1370
+ notify_c99_for_stmt_started(node)
1371
+
1372
+ widen_varying_variable_value_domain(node)
1373
+ effective_ctrlexpr = deduct_effective_controlling_expression(node)
1374
+
1375
+ node.condition_statement.executed = true
1376
+ if ctrlexpr = node.condition_statement.expression
1377
+ ctrlexpr_value = value_of(interpret(ctrlexpr))
1378
+ notify_c99_for_ctrlexpr_evaled(node, ctrlexpr_value)
1379
+
1380
+ case
1381
+ when ctrlexpr_value.must_be_true?
1382
+ branched_eval(effective_ctrlexpr,
1383
+ NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
1384
+ interpret(node.body_statement)
1385
+ interpret(node.expression) if node.expression
1386
+ end
1387
+ when ctrlexpr_value.may_be_true?
1388
+ branched_eval(effective_ctrlexpr,
1389
+ NARROWING, FINAL, IMPLICIT_CONDITION) do
1390
+ interpret(node.body_statement)
1391
+ interpret(node.expression) if node.expression
1392
+ end
1393
+ end
1394
+ else
1395
+ branched_eval(effective_ctrlexpr,
1396
+ NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
1397
+ interpret(node.body_statement)
1398
+ interpret(node.expression) if node.expression
1399
+ end
1400
+ end
1401
+ end
1402
+ ensure
1403
+ notify_c99_for_stmt_ended(node)
1404
+ end
1405
+
1406
+ def visit_goto_statement(node)
1407
+ checkpoint(node.location)
1408
+
1409
+ # TODO: Must implement goto semantics.
1410
+ node.executed = true
1411
+ notify_goto_stmt_evaled(node, node.identifier.value)
1412
+ end
1413
+
1414
+ def visit_continue_statement(node)
1415
+ checkpoint(node.location)
1416
+
1417
+ node.executed = true
1418
+ BreakEvent.of_continue.throw
1419
+ end
1420
+
1421
+ def visit_break_statement(node)
1422
+ checkpoint(node.location)
1423
+
1424
+ node.executed = true
1425
+ BreakEvent.of_break.throw
1426
+ end
1427
+
1428
+ def visit_return_statement(node)
1429
+ checkpoint(node.location)
1430
+
1431
+ node.executed = true
1432
+ return_object = node.expression ? interpret(node.expression) : nil
1433
+ notify_return_stmt_evaled(node, return_object)
1434
+ BreakEvent.of_return.throw
1435
+ end
1436
+
1437
+ private
1438
+ def uninitialize_block_local_variables(generic_labeled_statement)
1439
+ related_goto_statements = generic_labeled_statement.referrers
1440
+ return if related_goto_statements.empty?
1441
+
1442
+ local_variables.each do |variable|
1443
+ variable_definition = variable.declarations_and_definitions.first
1444
+
1445
+ anterior_gotos = related_goto_statements.select { |goto|
1446
+ goto.location.line_no < variable_definition.location.line_no
1447
+ }
1448
+
1449
+ unless anterior_gotos.empty?
1450
+ variable.value.begin_versioning_group
1451
+ variable.value.begin_versioning
1452
+ variable.uninitialize!
1453
+ variable.value.end_versioning
1454
+ variable.value.end_versioning_group(true)
1455
+ end
1456
+ end
1457
+ end
1458
+
1459
+ def widen_varying_variable_value_domain(iteration_statement)
1460
+ varying_vars = {}
1461
+ iteration_statement.varying_variable_names.each do |name|
1462
+ if variable = variable_named(name)
1463
+ varying_vars[variable] = variable.value.dup
1464
+ variable.widen_value_domain!(:==, variable.type.arbitrary_value)
1465
+ end
1466
+ end
1467
+
1468
+ varying_vars.each do |variable, orig_value|
1469
+ case deduct_variable_varying_path(variable, iteration_statement)
1470
+ when :increase
1471
+ variable.narrow_value_domain!(:>=, orig_value)
1472
+ when :decrease
1473
+ variable.narrow_value_domain!(:<=, orig_value)
1474
+ end
1475
+ end
1476
+ end
1477
+
1478
+ def deduct_variable_varying_path(variable, iteration_statement)
1479
+ histogram = iteration_statement.varying_expressions.map { |expr|
1480
+ case expr
1481
+ when SimpleAssignmentExpression
1482
+ deduct_ctrl_var_path_by_simple_assignment_expr(variable, expr)
1483
+ when CompoundAssignmentExpression
1484
+ deduct_ctrl_var_path_by_compound_assignment_expr(variable, expr)
1485
+ when PrefixIncrementExpression, PostfixIncrementExpression
1486
+ expr.operand.identifier.value == variable.name ? :increase : nil
1487
+ when PrefixDecrementExpression, PostfixDecrementExpression
1488
+ expr.operand.identifier.value == variable.name ? :decrease : nil
1489
+ else
1490
+ nil
1491
+ end
1492
+ }.compact.each_with_object(Hash.new(0)) { |dir, hash| hash[dir] += 1 }
1493
+
1494
+ if histogram.empty?
1495
+ nil
1496
+ else
1497
+ histogram[:decrease] <= histogram[:increase] ? :increase : :decrease
1498
+ end
1499
+ end
1500
+
1501
+ def deduct_ctrl_var_path_by_simple_assignment_expr(variable, expr)
1502
+ return nil unless expr.lhs_operand.identifier.value == variable.name
1503
+
1504
+ additive_exprs = collect_additive_expressions(expr.rhs_operand)
1505
+ histogram = additive_exprs.map { |additive_expr|
1506
+ if additive_expr.lhs_operand.kind_of?(ObjectSpecifier)
1507
+ lhs_name = additive_expr.lhs_operand.identifier.value
1508
+ end
1509
+
1510
+ if additive_expr.rhs_operand.kind_of?(ObjectSpecifier)
1511
+ rhs_name = additive_expr.rhs_operand.identifier.value
1512
+ end
1513
+
1514
+ unless lhs_name == variable.name || rhs_name == variable.name
1515
+ next nil
1516
+ end
1517
+
1518
+ case additive_expr.operator.type
1519
+ when "+"
1520
+ :increase
1521
+ when "-"
1522
+ :decrease
1523
+ else
1524
+ nil
1525
+ end
1526
+ }.compact.each_with_object(Hash.new(0)) { |dir, hash| hash[dir] += 1 }
1527
+
1528
+ if histogram.empty?
1529
+ nil
1530
+ else
1531
+ histogram[:decrease] <= histogram[:increase] ? :increase : :decrease
1532
+ end
1533
+ end
1534
+
1535
+ def deduct_ctrl_var_path_by_compound_assignment_expr(variable, expr)
1536
+ return nil unless expr.lhs_operand.identifier.value == variable.name
1537
+
1538
+ case expr.operator.type
1539
+ when "+="
1540
+ :increase
1541
+ when "-="
1542
+ :decrease
1543
+ else
1544
+ nil
1545
+ end
1546
+ end
1547
+
1548
+ def deduct_effective_controlling_expression(iteration_statement)
1549
+ if effective_ctrlexpr = iteration_statement.deduct_controlling_expression
1550
+ # TODO: If the controlling expression is `i == 2 || i == 5', this
1551
+ # expression should not be used.
1552
+ if effective_ctrlexpr.kind_of?(EqualityExpression) &&
1553
+ effective_ctrlexpr.operator.type == "=="
1554
+ effective_ctrlexpr = nil
1555
+ end
1556
+ end
1557
+ effective_ctrlexpr
1558
+ end
1559
+ end
1560
+
1561
+ class SwitchStatementInterpreter < SubInterpreter
1562
+ include BranchGroup::Option
1563
+ include Branch::Option
1564
+
1565
+ def initialize(owner)
1566
+ super(owner, SwitchStatement)
1567
+ end
1568
+
1569
+ def visit_switch_statement(node)
1570
+ checkpoint(node.location)
1571
+
1572
+ node.executed = true
1573
+ object = interpret(node.expression)
1574
+ execute_switch_body(object, node.statement) if object.variable?
1575
+ end
1576
+
1577
+ private
1578
+ def execute_switch_body(variable, node)
1579
+ checkpoint(node.location)
1580
+
1581
+ node.executed = true
1582
+ scoped_eval do
1583
+ begin
1584
+ notify_block_started(node)
1585
+ execute_switch_branches(variable, node.block_items)
1586
+ ensure
1587
+ notify_block_ended(node)
1588
+ end
1589
+ end
1590
+ end
1591
+
1592
+ def execute_switch_branches(variable, block_items)
1593
+ base_options = [SMOTHER_BREAK, IMPLICIT_CONDITION, NARROWING]
1594
+ base_options.push(COMPLETE) if complete?(block_items)
1595
+
1596
+ index = 0
1597
+ while block_item = block_items[index]
1598
+ while block_item.kind_of?(GenericLabeledStatement)
1599
+ block_item.executed = true
1600
+ notify_label_defined(block_item)
1601
+ block_item = block_item.statement
1602
+ end
1603
+
1604
+ case block_item
1605
+ when CaseLabeledStatement, DefaultLabeledStatement
1606
+ options = base_options.dup
1607
+ options.push(FINAL) if final_branch?(block_items, index)
1608
+ index = execute_branch(block_item, block_items, index + 1, options)
1609
+ break unless index
1610
+ else
1611
+ interpret(block_item)
1612
+ index += 1
1613
+ end
1614
+ end
1615
+ end
1616
+
1617
+ def execute_branch(labeled_statement, block_items, index, branch_options)
1618
+ ctrlexpr = labeled_statement.normalized_expression
1619
+ ctrlexpr_value = value_of(interpret(ctrlexpr, :suppress_notification))
1620
+
1621
+ case
1622
+ when ctrlexpr_value.must_be_true?
1623
+ branch_options.push(FINAL, COMPLETE)
1624
+ when ctrlexpr_value.must_be_false?
1625
+ # NOTE: To end the current branch group of switch-statement if this
1626
+ # case-clause is the final one.
1627
+ branched_eval(ctrlexpr, *branch_options) {}
1628
+ return seek_next_branch(block_items, index)
1629
+ end
1630
+
1631
+ branched_eval(ctrlexpr, *branch_options) do |branch|
1632
+ interpret(labeled_statement)
1633
+ while block_item = block_items[index]
1634
+ while block_item.kind_of?(GenericLabeledStatement)
1635
+ block_item.executed = true
1636
+ notify_label_defined(block_item)
1637
+ block_item = block_item.statement
1638
+ end
1639
+
1640
+ case block_item
1641
+ when CaseLabeledStatement, DefaultLabeledStatement
1642
+ # NOTE: Fall through!
1643
+ prepare_fall_through(branch, branch_options, block_item)
1644
+ branch_options.push(FINAL) if final_branch?(block_items, index)
1645
+ branch.add_options(*branch_options)
1646
+ end
1647
+ interpret(block_item)
1648
+ index += 1
1649
+ end
1650
+ # NOTE: To simulate implicit breaking of the last case-clause.
1651
+ BreakEvent.of_break.throw
1652
+ end
1653
+
1654
+ branch_options.include?(FINAL) ?
1655
+ nil : seek_next_branch(block_items, index)
1656
+ end
1657
+
1658
+ def prepare_fall_through(branch, branch_options, labeled_statement)
1659
+ value_domain_manip = nil
1660
+
1661
+ branch.restart_versioning do
1662
+ ctrlexpr = labeled_statement.normalized_expression
1663
+ ctrlexpr_value = value_of(interpret(ctrlexpr, :suppress_notification))
1664
+
1665
+ case
1666
+ when ctrlexpr_value.must_be_true?
1667
+ branch_options.push(FINAL, COMPLETE)
1668
+ when ctrlexpr_value.must_be_false?
1669
+ return
1670
+ end
1671
+
1672
+ value_domain_manip =
1673
+ branch.controlling_expression.ensure_true_by_widening(ctrlexpr)
1674
+ end
1675
+
1676
+ value_domain_manip.commit!
1677
+ end
1678
+
1679
+ def final_branch?(block_items, index)
1680
+ index += 1
1681
+ while block_item = block_items[index]
1682
+ while block_item.kind_of?(GenericLabeledStatement)
1683
+ block_item = block_item.statement
1684
+ end
1685
+
1686
+ case block_item
1687
+ when CaseLabeledStatement, DefaultLabeledStatement
1688
+ return false
1689
+ else
1690
+ index += 1
1691
+ end
1692
+ end
1693
+ true
1694
+ end
1695
+
1696
+ def complete?(block_items)
1697
+ index = 0
1698
+ while block_item = block_items[index]
1699
+ while block_item.kind_of?(GenericLabeledStatement)
1700
+ block_item = block_item.statement
1701
+ end
1702
+
1703
+ case block_item
1704
+ when DefaultLabeledStatement
1705
+ return true
1706
+ else
1707
+ index += 1
1708
+ end
1709
+ end
1710
+ false
1711
+ end
1712
+
1713
+ def seek_next_branch(block_items, index)
1714
+ while block_item = block_items[index]
1715
+ while block_item.kind_of?(GenericLabeledStatement)
1716
+ notify_label_defined(block_item)
1717
+ block_item = block_item.statement
1718
+ end
1719
+
1720
+ case block_item
1721
+ when CaseLabeledStatement, DefaultLabeledStatement
1722
+ break
1723
+ else
1724
+ index += 1
1725
+ end
1726
+ end
1727
+ index
1728
+ end
1729
+ end
1730
+
1731
+ class ExpressionInterpreter < SubInterpreter
1732
+ include ExpressionEvaluator
1733
+
1734
+ def initialize(owner)
1735
+ super(owner, Expression)
1736
+ end
1737
+ end
1738
+
1739
+ end
1740
+ end