adlint 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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