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.
- data/AUTHORS +27 -0
- data/COPYING +674 -0
- data/ChangeLog +820 -0
- data/INSTALL +78 -0
- data/MANIFEST +464 -0
- data/NEWS +38 -0
- data/README +74 -0
- data/Rakefile +167 -0
- data/TODO +29 -0
- data/bin/adlint +141 -0
- data/bin/adlint_chk +129 -0
- data/bin/adlint_cma +122 -0
- data/bin/adlint_sma +129 -0
- data/bin/adlintize +286 -0
- data/etc/conf.d/fallback/cinit.erb +11 -0
- data/etc/conf.d/fallback/traits.erb +216 -0
- data/etc/conf.d/i686-cygwin/cinit-gcc_4.3.4.erb +149 -0
- data/etc/conf.d/i686-cygwin/traits-gcc_4.3.4.erb +227 -0
- data/etc/conf.d/i686-devkit/cinit-gcc_4.5.2.erb +224 -0
- data/etc/conf.d/i686-devkit/traits-gcc_4.5.2.erb +226 -0
- data/etc/conf.d/i686-linux/cinit-gcc_4.5.1.erb +219 -0
- data/etc/conf.d/i686-linux/traits-gcc_4.5.1.erb +224 -0
- data/etc/conf.d/i686-mingw/cinit-gcc_4.6.1.erb +234 -0
- data/etc/conf.d/i686-mingw/traits-gcc_4.6.1.erb +226 -0
- data/etc/conf.d/noarch/GNUmakefile.erb +119 -0
- data/etc/conf.d/noarch/adlint_all_bat.erb +9 -0
- data/etc/conf.d/noarch/adlint_all_sh.erb +10 -0
- data/etc/conf.d/noarch/pinit.erb +11 -0
- data/etc/mesg.d/en_US/messages.yml +784 -0
- data/etc/mesg.d/ja_JP/messages.yml +784 -0
- data/lib/adlint/analyzer.rb +294 -0
- data/lib/adlint/c/branch.rb +251 -0
- data/lib/adlint/c/builtin.rb +92 -0
- data/lib/adlint/c/code.rb +490 -0
- data/lib/adlint/c/const.rb +465 -0
- data/lib/adlint/c/conv.rb +212 -0
- data/lib/adlint/c/ctrlexpr.rb +949 -0
- data/lib/adlint/c/domain.rb +7499 -0
- data/lib/adlint/c/environ.rb +133 -0
- data/lib/adlint/c/expr.rb +1725 -0
- data/lib/adlint/c/format.rb +3209 -0
- data/lib/adlint/c/interp.rb +1740 -0
- data/lib/adlint/c/lexer.rb +241 -0
- data/lib/adlint/c/mediator.rb +313 -0
- data/lib/adlint/c/message.rb +13597 -0
- data/lib/adlint/c/metric.rb +765 -0
- data/lib/adlint/c/object.rb +1018 -0
- data/lib/adlint/c/parser.rb +3800 -0
- data/lib/adlint/c/parser.y +2054 -0
- data/lib/adlint/c/phase.rb +712 -0
- data/lib/adlint/c/resolver.rb +270 -0
- data/lib/adlint/c/scanner.rb +248 -0
- data/lib/adlint/c/scope.rb +74 -0
- data/lib/adlint/c/syntax.rb +4279 -0
- data/lib/adlint/c/type.rb +7506 -0
- data/lib/adlint/c/util.rb +91 -0
- data/lib/adlint/c/value.rb +2310 -0
- data/lib/adlint/c.rb +56 -0
- data/lib/adlint/code.rb +500 -0
- data/lib/adlint/cpp/code.rb +189 -0
- data/lib/adlint/cpp/constexpr.rb +721 -0
- data/lib/adlint/cpp/constexpr.y +389 -0
- data/lib/adlint/cpp/eval.rb +1012 -0
- data/lib/adlint/cpp/lexer.rb +860 -0
- data/lib/adlint/cpp/macro.rb +637 -0
- data/lib/adlint/cpp/message.rb +992 -0
- data/lib/adlint/cpp/phase.rb +176 -0
- data/lib/adlint/cpp/scanner.rb +93 -0
- data/lib/adlint/cpp/source.rb +169 -0
- data/lib/adlint/cpp/subst.rb +300 -0
- data/lib/adlint/cpp/syntax.rb +1412 -0
- data/lib/adlint/cpp/util.rb +97 -0
- data/lib/adlint/cpp.rb +43 -0
- data/lib/adlint/driver.rb +147 -0
- data/lib/adlint/error.rb +179 -0
- data/lib/adlint/lang.rb +97 -0
- data/lib/adlint/ld/message.rb +259 -0
- data/lib/adlint/ld/metric.rb +57 -0
- data/lib/adlint/ld/object.rb +542 -0
- data/lib/adlint/ld/phase.rb +193 -0
- data/lib/adlint/ld/typedef.rb +109 -0
- data/lib/adlint/ld/util.rb +88 -0
- data/lib/adlint/ld.rb +37 -0
- data/lib/adlint/lexer.rb +293 -0
- data/lib/adlint/message.rb +368 -0
- data/lib/adlint/metric.rb +805 -0
- data/lib/adlint/monitor.rb +144 -0
- data/lib/adlint/phase.rb +90 -0
- data/lib/adlint/prelude.rb +314 -0
- data/lib/adlint/report.rb +617 -0
- data/lib/adlint/source.rb +155 -0
- data/lib/adlint/symbol.rb +127 -0
- data/lib/adlint/token.rb +215 -0
- data/lib/adlint/traits.rb +643 -0
- data/lib/adlint/util.rb +524 -0
- data/lib/adlint/version.rb +71 -0
- data/lib/adlint.rb +66 -0
- data/share/HEADER +45 -0
- data/share/demo/Makefile +110 -0
- data/share/demo/ambig_operator/ambig_operator.c +289 -0
- data/share/demo/arg_points_unset/arg_points_unset.c +37 -0
- data/share/demo/array_range/array_range.c +62 -0
- data/share/demo/bad_bitfields/bad_bitfields.c +74 -0
- data/share/demo/bad_brace/bad_brace.c +19 -0
- data/share/demo/bad_charset/abcde$.h +0 -0
- data/share/demo/bad_charset/bad_charset.c +22 -0
- data/share/demo/bad_comment/bad_comment.c +3 -0
- data/share/demo/bad_const/bad_const.c +19 -0
- data/share/demo/bad_conv/bad_conv.c +48 -0
- data/share/demo/bad_indent/bad_indent.c +50 -0
- data/share/demo/bad_init/bad_init.c +49 -0
- data/share/demo/bad_macro/bad_macro.c +97 -0
- data/share/demo/bitwise_expr/bitwise_expr.c +19 -0
- data/share/demo/call_by_value/call_by_value.c +26 -0
- data/share/demo/cross_ref/cross_ref.c +21 -0
- data/share/demo/dangling_else/dangling_else.c +20 -0
- data/share/demo/dead_code/dead_code.c +237 -0
- data/share/demo/deep_nest/deep_nest.c +57 -0
- data/share/demo/dense_switch/dense_switch.c +62 -0
- data/share/demo/direct_recur/direct_recur.c +15 -0
- data/share/demo/div_by_zero/div_by_zero.c +35 -0
- data/share/demo/dos_source/dos_source.c +7 -0
- data/share/demo/funptr_cast/funptr_cast.c +26 -0
- data/share/demo/goto_stmt/goto_stmt.c +19 -0
- data/share/demo/id_hiding/id_hiding.c +19 -0
- data/share/demo/ill_defined/ill_defined.c +13 -0
- data/share/demo/implicit_conv/implicit_conv.c +60 -0
- data/share/demo/implicit_int/implicit_int.c +14 -0
- data/share/demo/incomplete_type/incomplete_type.c +49 -0
- data/share/demo/indirect_recur/indirect_recur_1.c +14 -0
- data/share/demo/indirect_recur/indirect_recur_1.h +7 -0
- data/share/demo/indirect_recur/indirect_recur_2.c +12 -0
- data/share/demo/indirect_recur/indirect_recur_2.h +6 -0
- data/share/demo/indirect_recur/indirect_recur_3.c +6 -0
- data/share/demo/indirect_recur/indirect_recur_3.h +6 -0
- data/share/demo/indirect_recur/indirect_recur_4.c +25 -0
- data/share/demo/intro_demo/intro_demo.c +76 -0
- data/share/demo/intro_demo/intro_demo.h +12 -0
- data/share/demo/intro_demo/useless_header.h +5 -0
- data/share/demo/invalid_call/invalid_call.c +32 -0
- data/share/demo/kandr_fundef/kandr_fundef.c +10 -0
- data/share/demo/line_comment/line_comment.c +12 -0
- data/share/demo/local_decl/local_decl.c +9 -0
- data/share/demo/logical_trick/logical_trick.c +36 -0
- data/share/demo/long_sym/long_sym.c +5 -0
- data/share/demo/loop_var/loop_var.c +92 -0
- data/share/demo/malloc_or_die/malloc_or_die.c +43 -0
- data/share/demo/may_be_null/may_be_null.c +52 -0
- data/share/demo/may_be_null_arith/may_be_null_arith.c +15 -0
- data/share/demo/may_be_unset/may_be_unset.c +34 -0
- data/share/demo/mmapped_io/mmapped_io.c +23 -0
- data/share/demo/multi_break/multi_break.c +33 -0
- data/share/demo/multi_decl/multi_decl_1.c +17 -0
- data/share/demo/multi_decl/multi_decl_1.h +6 -0
- data/share/demo/multi_decl/multi_decl_2.c +13 -0
- data/share/demo/multi_decl/multi_decl_2.h +6 -0
- data/share/demo/multi_decl/multi_decl_3.c +22 -0
- data/share/demo/multi_def/multi_def_1.c +36 -0
- data/share/demo/multi_def/multi_def_1.h +6 -0
- data/share/demo/multi_def/multi_def_2.c +22 -0
- data/share/demo/multi_def/multi_def_2.h +6 -0
- data/share/demo/multi_def/multi_def_3.c +6 -0
- data/share/demo/multi_typedef/multi_typedef.c +11 -0
- data/share/demo/multi_typedef/multi_typedef_1.h +1 -0
- data/share/demo/multi_typedef/multi_typedef_2.h +1 -0
- data/share/demo/must_be_false/must_be_false.c +53 -0
- data/share/demo/must_be_null/must_be_null.c +13 -0
- data/share/demo/must_be_null_arith/must_be_null_arith.c +14 -0
- data/share/demo/must_be_true/must_be_true.c +21 -0
- data/share/demo/no_eof_nl/no_eof_nl.c +4 -0
- data/share/demo/no_void_arg/no_void_arg.c +14 -0
- data/share/demo/null_stmt/null_stmt.c +19 -0
- data/share/demo/octal_const/octal_const.c +20 -0
- data/share/demo/output_by_param/output_by_param.c +17 -0
- data/share/demo/overflow/overflow.c +74 -0
- data/share/demo/press_release/press_release.c +40 -0
- data/share/demo/retn_lvar_addr/retn_lvar_addr.c +47 -0
- data/share/demo/shift_expr/shift_expr.c +14 -0
- data/share/demo/should_be_typedef/should_be_typedef.c +51 -0
- data/share/demo/static_paths/static_paths.c +153 -0
- data/share/demo/static_vars/static_vars.c +39 -0
- data/share/demo/tag_hiding/tag_hiding.c +18 -0
- data/share/demo/tricky_incdec/tricky_incdec.c +12 -0
- data/share/demo/undefined_macro/undefined_macro.c +17 -0
- data/share/demo/uninit_vars/uninit_vars.c +28 -0
- data/share/demo/union_type/union_type.c +23 -0
- data/share/demo/unmatch_decl/unmatch_decl_1.c +12 -0
- data/share/demo/unmatch_decl/unmatch_decl_1.h +8 -0
- data/share/demo/unmatch_decl/unmatch_decl_2.c +10 -0
- data/share/demo/unmatch_decl/unmatch_decl_2.h +8 -0
- data/share/demo/unmatch_decl/unmatch_decl_3.c +7 -0
- data/share/demo/unmatch_paren_macro/unmatch_paren_macro.c +15 -0
- data/share/demo/unreachable/unreachable.c +34 -0
- data/share/demo/useless_exp_funs/useless_exp_funs_1.c +14 -0
- data/share/demo/useless_exp_funs/useless_exp_funs_1.h +1 -0
- data/share/demo/useless_exp_funs/useless_exp_funs_2.c +6 -0
- data/share/demo/useless_exp_vars/useless_export_1.c +8 -0
- data/share/demo/useless_exp_vars/useless_export_1.h +1 -0
- data/share/demo/useless_exp_vars/useless_export_2.c +7 -0
- data/share/demo/useless_expr/useless_expr.c +17 -0
- data/share/demo/useless_funs/useless_funs_1.c +21 -0
- data/share/demo/useless_funs/useless_funs_1.h +8 -0
- data/share/demo/useless_funs/useless_funs_2.c +6 -0
- data/share/demo/useless_header/useless_header.c +9 -0
- data/share/demo/useless_header/useless_header_1.h +12 -0
- data/share/demo/useless_header/useless_header_2.h +6 -0
- data/share/demo/useless_header/useless_header_3.h +9 -0
- data/share/demo/useless_header/useless_header_4.h +3 -0
- data/share/demo/useless_vars/useless_vars.c +17 -0
- data/share/demo/va_funcall/va_funcall.c +25 -0
- data/share/demo/various_fundef/various_fundef.c +36 -0
- data/share/demo/wchar_wstring/wchar_wstring.c +7 -0
- data/share/demo/wrap_around/wrap_around.c +38 -0
- data/share/doc/Makefile +16 -0
- data/share/doc/adlint_on_adqua.png +0 -0
- data/share/doc/adlint_on_eclipse_en.png +0 -0
- data/share/doc/adlint_on_eclipse_ja.png +0 -0
- data/share/doc/adlint_on_vim_en.png +0 -0
- data/share/doc/adlint_on_vim_ja.png +0 -0
- data/share/doc/developers_guide_ja.html +171 -0
- data/share/doc/developers_guide_ja.texi +87 -0
- data/share/doc/gen_mesg_sections.rb +39 -0
- data/share/doc/samples/GNUmakefile +162 -0
- data/share/doc/samples/adlint_traits.yml +238 -0
- data/share/doc/texinfo.css +22 -0
- data/share/doc/users_guide_en.html +39975 -0
- data/share/doc/users_guide_en.texi +32640 -0
- data/share/doc/users_guide_ja.html +40505 -0
- data/share/doc/users_guide_ja.texi +33189 -0
- data/share/logo/adlint-110.png +0 -0
- data/share/logo/adlint-524.png +0 -0
- data/share/logo/adlint.svg +4637 -0
- data/share/sample/README +6 -0
- data/share/sample/bison-2.5/adlint/GNUmakefile +170 -0
- data/share/sample/bison-2.5/adlint/adlint_traits.yml +225 -0
- data/share/sample/bison-2.5/adlint/lib/GNUmakefile +198 -0
- data/share/sample/bison-2.5/adlint/lib/adlint_cinit.h +228 -0
- data/share/sample/bison-2.5/adlint/lib/adlint_pinit.h +21 -0
- data/share/sample/bison-2.5/adlint/lib/adlint_traits.yml +238 -0
- data/share/sample/bison-2.5/adlint/src/GNUmakefile +166 -0
- data/share/sample/bison-2.5/adlint/src/adlint_cinit.h +228 -0
- data/share/sample/bison-2.5/adlint/src/adlint_pinit.h +21 -0
- data/share/sample/bison-2.5/adlint/src/adlint_traits.yml +239 -0
- data/share/sample/ctags-5.8/adlint/GNUmakefile +169 -0
- data/share/sample/ctags-5.8/adlint/adlint_cinit.h +219 -0
- data/share/sample/ctags-5.8/adlint/adlint_pinit.h +13 -0
- data/share/sample/ctags-5.8/adlint/adlint_traits.yml +225 -0
- data/share/sample/flex-2.5.35/adlint/GNUmakefile +140 -0
- data/share/sample/flex-2.5.35/adlint/adlint_cinit.h +219 -0
- data/share/sample/flex-2.5.35/adlint/adlint_pinit.h +14 -0
- data/share/sample/flex-2.5.35/adlint/adlint_traits.yml +225 -0
- data/share/sample/ruby-1.9.3-p0/adlint/GNUmakefile +314 -0
- data/share/sample/ruby-1.9.3-p0/adlint/adlint_traits.yml +225 -0
- data/share/sample/ruby-1.9.3-p0/adlint/core/GNUmakefile +204 -0
- data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_pinit.h +28 -0
- data/share/sample/ruby-1.9.3-p0/adlint/core/adlint_traits.yml +240 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc/GNUmakefile +163 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc/adlint_traits.yml +240 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/GNUmakefile +149 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/enc-trans/adlint_traits.yml +240 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-bigdecimal/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-continuation/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-coverage/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-curses/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-date/GNUmakefile +134 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-date/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dbm/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-bubblebabble/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/GNUmakefile +132 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-md5/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/GNUmakefile +132 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-rmd160/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/GNUmakefile +132 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha1/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/GNUmakefile +132 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-digest-sha2/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/GNUmakefile +134 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/GNUmakefile +140 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-dl-callback/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-etc/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fcntl/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiber/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/GNUmakefile +134 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-fiddle/adlint_traits.yml +242 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-gdbm/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-iconv/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-console/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-nonblock/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-io-wait/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-generator/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-json-parser/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-complex/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-mathn-rational/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-nkf/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/GNUmakefile +162 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-openssl/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pathname/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/GNUmakefile +135 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-psych/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-pty/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-racc-cparse/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-readline/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-ripper/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/GNUmakefile +132 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-sdbm/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/GNUmakefile +144 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-socket/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-stringio/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-strscan/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/GNUmakefile +140 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syck/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-syslog/adlint_traits.yml +241 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/GNUmakefile +131 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_cinit.h +228 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_pinit.h +24 -0
- data/share/sample/ruby-1.9.3-p0/adlint/ext-zlib/adlint_traits.yml +241 -0
- data/share/sample/screen-4.0.3/adlint/GNUmakefile +162 -0
- data/share/sample/screen-4.0.3/adlint/adlint_cinit.h +228 -0
- data/share/sample/screen-4.0.3/adlint/adlint_pinit.h +21 -0
- data/share/sample/screen-4.0.3/adlint/adlint_traits.yml +238 -0
- data/share/sample/vim-7.3/adlint/vim/GNUmakefile +185 -0
- data/share/sample/vim-7.3/adlint/vim/adlint_cinit.h +228 -0
- data/share/sample/vim-7.3/adlint/vim/adlint_pinit.h +25 -0
- data/share/sample/vim-7.3/adlint/vim/adlint_traits.yml +250 -0
- data/share/sample/vim-7.3/adlint/xxd/GNUmakefile +131 -0
- data/share/sample/vim-7.3/adlint/xxd/adlint_cinit.h +228 -0
- data/share/sample/vim-7.3/adlint/xxd/adlint_pinit.h +24 -0
- data/share/sample/vim-7.3/adlint/xxd/adlint_traits.yml +237 -0
- data/share/sample/zsh-4.3.15/adlint/GNUmakefile +146 -0
- data/share/sample/zsh-4.3.15/adlint/adlint_traits.yml +225 -0
- data/share/sample/zsh-4.3.15/adlint/builtins/GNUmakefile +132 -0
- data/share/sample/zsh-4.3.15/adlint/builtins/adlint_cinit.h +228 -0
- data/share/sample/zsh-4.3.15/adlint/builtins/adlint_pinit.h +24 -0
- data/share/sample/zsh-4.3.15/adlint/builtins/adlint_traits.yml +240 -0
- data/share/sample/zsh-4.3.15/adlint/core/GNUmakefile +153 -0
- data/share/sample/zsh-4.3.15/adlint/core/adlint_cinit.h +228 -0
- data/share/sample/zsh-4.3.15/adlint/core/adlint_pinit.h +23 -0
- data/share/sample/zsh-4.3.15/adlint/core/adlint_traits.yml +239 -0
- data/share/sample/zsh-4.3.15/adlint/modules/GNUmakefile +147 -0
- data/share/sample/zsh-4.3.15/adlint/modules/adlint_cinit.h +228 -0
- data/share/sample/zsh-4.3.15/adlint/modules/adlint_pinit.h +24 -0
- data/share/sample/zsh-4.3.15/adlint/modules/adlint_traits.yml +240 -0
- data/share/sample/zsh-4.3.15/adlint/zle/GNUmakefile +144 -0
- data/share/sample/zsh-4.3.15/adlint/zle/adlint_cinit.h +228 -0
- data/share/sample/zsh-4.3.15/adlint/zle/adlint_pinit.h +24 -0
- data/share/sample/zsh-4.3.15/adlint/zle/adlint_traits.yml +239 -0
- data/spec/MUST_WRITE_SPECS_WITH_RSPEC +0 -0
- metadata +532 -0
|
@@ -0,0 +1,1725 @@
|
|
|
1
|
+
# C expression evaluator.
|
|
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/c/mediator"
|
|
33
|
+
require "adlint/c/const"
|
|
34
|
+
require "adlint/c/conv"
|
|
35
|
+
|
|
36
|
+
module AdLint #:nodoc:
|
|
37
|
+
module C #:nodoc:
|
|
38
|
+
|
|
39
|
+
module ExpressionUtil
|
|
40
|
+
# NOTE: Host class of this module must include InterpreterMediator,
|
|
41
|
+
# NotifierMediator and Conversion.
|
|
42
|
+
|
|
43
|
+
def execute_array_subscript_expression(node, object, subscript)
|
|
44
|
+
unless object.variable? && (object.type.array? || object.type.pointer?)
|
|
45
|
+
return temporary_variable
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
array_or_pointer = object
|
|
49
|
+
|
|
50
|
+
result_type = array_or_pointer.type.unqualify.base_type
|
|
51
|
+
result_type = pointer_type(result_type) if result_type.array?
|
|
52
|
+
|
|
53
|
+
unless subscript.variable? && subscript.value.scalar? &&
|
|
54
|
+
subscript.value.exist?
|
|
55
|
+
return temporary_variable(result_type)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
case
|
|
59
|
+
when array_or_pointer.type.array?
|
|
60
|
+
array = array_or_pointer
|
|
61
|
+
when array_or_pointer.type.pointer?
|
|
62
|
+
if pointee = pointee_of(array_or_pointer)
|
|
63
|
+
if pointee.type.array?
|
|
64
|
+
array = pointee
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# NOTE: An array subscript converted to `int' implicitly.
|
|
70
|
+
if subscript.type.same_as?(int_type)
|
|
71
|
+
int_subscript = subscript
|
|
72
|
+
else
|
|
73
|
+
if int_subscript = do_conversion(subscript, int_type)
|
|
74
|
+
notify_implicit_conv_performed(node.array_subscript,
|
|
75
|
+
subscript, int_subscript)
|
|
76
|
+
else
|
|
77
|
+
return temporary_variable(result_type)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# FIXME: Domain of the subscript may have multiple values.
|
|
82
|
+
subscript_value = int_subscript.value.unique_sample
|
|
83
|
+
if array and inner_variable = array.inner_variable_at(subscript_value)
|
|
84
|
+
notify_variable_referred(node, inner_variable)
|
|
85
|
+
unless variable_reassigning?
|
|
86
|
+
notify_variable_value_referred(node, inner_variable)
|
|
87
|
+
end
|
|
88
|
+
if inner_variable.type.array?
|
|
89
|
+
result = temporary_variable(result_type,
|
|
90
|
+
pointer_value_of(inner_variable))
|
|
91
|
+
else
|
|
92
|
+
result = inner_variable
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
result = temporary_variable(result_type)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
notify_array_subscript_expr_evaled(node, array_or_pointer,
|
|
99
|
+
int_subscript, array, result)
|
|
100
|
+
result
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def execute_function_call_expression(node, object, args)
|
|
104
|
+
if object.function?
|
|
105
|
+
function = object
|
|
106
|
+
else
|
|
107
|
+
if object.type.pointer? && object.type.unqualify.base_type.function?
|
|
108
|
+
if pointee = pointee_of(object) and pointee.function?
|
|
109
|
+
function = pointee
|
|
110
|
+
else
|
|
111
|
+
function_type = object.type.unqualify.base_type
|
|
112
|
+
function = define_anonymous_function(function_type)
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
return temporary_variable
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
result = function.call(interpreter, args)
|
|
120
|
+
unless function.builtin?
|
|
121
|
+
notify_function_call_expr_evaled(node, function,
|
|
122
|
+
args.map { |arg, expr| arg }, result)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
result
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def execute_member_access_by_value_expression(node, object)
|
|
129
|
+
unless object.variable? && object.type.composite?
|
|
130
|
+
return temporary_variable
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
variable = object
|
|
134
|
+
member_variable = variable.inner_variable_named(node.identifier.value)
|
|
135
|
+
|
|
136
|
+
# NOTE: `member_variable' is nil when this expression represents the
|
|
137
|
+
# direct member access extension.
|
|
138
|
+
notify_member_access_expr_evaled(node, variable, member_variable)
|
|
139
|
+
|
|
140
|
+
if member_variable
|
|
141
|
+
notify_variable_referred(node, member_variable)
|
|
142
|
+
unless variable_reassigning?
|
|
143
|
+
notify_variable_value_referred(node, member_variable)
|
|
144
|
+
end
|
|
145
|
+
if member_variable.type.array?
|
|
146
|
+
type = pointer_type(member_variable.type.base_type)
|
|
147
|
+
return temporary_variable(type, pointer_value_of(member_variable))
|
|
148
|
+
end
|
|
149
|
+
member_variable
|
|
150
|
+
else
|
|
151
|
+
temporary_variable
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def execute_member_access_by_pointer_expression(node, object)
|
|
156
|
+
unqualified_type = object.type.unqualify
|
|
157
|
+
|
|
158
|
+
unless object.variable? && unqualified_type.pointer? &&
|
|
159
|
+
unqualified_type.base_type.composite?
|
|
160
|
+
return temporary_variable
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
pointer = object
|
|
164
|
+
if pointee = pointee_of(pointer)
|
|
165
|
+
if pointee.type.array?
|
|
166
|
+
if first_element = pointee.inner_variable_at(0)
|
|
167
|
+
pointee = first_element
|
|
168
|
+
else
|
|
169
|
+
pointee = temporary_variable(object.type.unqualify.base_type)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
if variable_reassigning?
|
|
175
|
+
notify_variable_value_referred(node, pointer)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
if pointee && pointee.type.composite?
|
|
179
|
+
member_variable = pointee.inner_variable_named(node.identifier.value)
|
|
180
|
+
else
|
|
181
|
+
member = unqualified_type.base_type.member_named(node.identifier.value)
|
|
182
|
+
member_variable = temporary_variable(member.type) if member
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# NOTE: `member_variable' is nil when this expression represents the
|
|
186
|
+
# direct member access extension.
|
|
187
|
+
notify_member_access_expr_evaled(node, pointer, member_variable)
|
|
188
|
+
|
|
189
|
+
if member_variable
|
|
190
|
+
notify_variable_referred(node, member_variable)
|
|
191
|
+
unless variable_reassigning?
|
|
192
|
+
notify_variable_value_referred(node, member_variable)
|
|
193
|
+
end
|
|
194
|
+
if member_variable.type.array?
|
|
195
|
+
type = pointer_type(member_variable.type.base_type)
|
|
196
|
+
return temporary_variable(type, pointer_value_of(member_variable))
|
|
197
|
+
end
|
|
198
|
+
member_variable
|
|
199
|
+
else
|
|
200
|
+
temporary_variable
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def execute_postfix_increment_expression(node, object)
|
|
205
|
+
if object.variable?
|
|
206
|
+
variable = object
|
|
207
|
+
|
|
208
|
+
if variable.type.scalar?
|
|
209
|
+
result = temporary_variable(variable.type, variable.value.dup)
|
|
210
|
+
if variable.value.scalar?
|
|
211
|
+
variable.assign!(variable.value + ScalarValue.of(1))
|
|
212
|
+
end
|
|
213
|
+
else
|
|
214
|
+
result = temporary_variable
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
notify_postfix_increment_expr_evaled(node, variable, result)
|
|
218
|
+
notify_variable_value_updated(node, variable)
|
|
219
|
+
|
|
220
|
+
result
|
|
221
|
+
else
|
|
222
|
+
temporary_variable
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def execute_postfix_decrement_expression(node, object)
|
|
227
|
+
if object.variable?
|
|
228
|
+
variable = object
|
|
229
|
+
|
|
230
|
+
if variable.type.scalar?
|
|
231
|
+
result = temporary_variable(variable.type, variable.value.dup)
|
|
232
|
+
if variable.value.scalar?
|
|
233
|
+
variable.assign!(variable.value - ScalarValue.of(1))
|
|
234
|
+
end
|
|
235
|
+
else
|
|
236
|
+
result = temporary_variable
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
notify_postfix_decrement_expr_evaled(node, variable, result)
|
|
240
|
+
notify_variable_value_updated(node, variable)
|
|
241
|
+
|
|
242
|
+
result
|
|
243
|
+
else
|
|
244
|
+
temporary_variable
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def execute_prefix_increment_expression(node, object)
|
|
249
|
+
if object.variable?
|
|
250
|
+
variable = object
|
|
251
|
+
|
|
252
|
+
if variable.type.scalar?
|
|
253
|
+
original_value = variable.value.dup
|
|
254
|
+
if variable.value.scalar?
|
|
255
|
+
variable.assign!(variable.value + ScalarValue.of(1))
|
|
256
|
+
end
|
|
257
|
+
else
|
|
258
|
+
original_value = variable.value.dup
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
notify_prefix_increment_expr_evaled(node, variable, original_value)
|
|
262
|
+
notify_variable_value_updated(node, variable)
|
|
263
|
+
|
|
264
|
+
variable
|
|
265
|
+
else
|
|
266
|
+
temporary_variable
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def execute_prefix_decrement_expression(node, object)
|
|
271
|
+
if object.variable?
|
|
272
|
+
variable = object
|
|
273
|
+
|
|
274
|
+
if variable.type.scalar?
|
|
275
|
+
original_value = variable.value.dup
|
|
276
|
+
if variable.value.scalar?
|
|
277
|
+
variable.assign!(variable.value - ScalarValue.of(1))
|
|
278
|
+
end
|
|
279
|
+
else
|
|
280
|
+
original_value = variable.value.dup
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
notify_prefix_decrement_expr_evaled(node, variable, original_value)
|
|
284
|
+
notify_variable_value_updated(node, variable)
|
|
285
|
+
|
|
286
|
+
variable
|
|
287
|
+
else
|
|
288
|
+
temporary_variable
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def execute_indirection_expression(node, object)
|
|
293
|
+
if object.variable?
|
|
294
|
+
variable = object
|
|
295
|
+
|
|
296
|
+
return temporary_variable unless variable.type.pointer?
|
|
297
|
+
|
|
298
|
+
pointer = object
|
|
299
|
+
unqualified_type = pointer.type.unqualify
|
|
300
|
+
|
|
301
|
+
pointee = pointee_of(pointer)
|
|
302
|
+
if variable_reassigning?
|
|
303
|
+
notify_variable_value_referred(node, pointer)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
case
|
|
307
|
+
when pointee
|
|
308
|
+
if pointee.type.array?
|
|
309
|
+
if first_element = pointee.inner_variable_at(0)
|
|
310
|
+
pointee = first_element
|
|
311
|
+
else
|
|
312
|
+
pointee = temporary_variable(unqualified_type.base_type)
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
unless variable_reassigning?
|
|
317
|
+
notify_variable_value_referred(node, pointee) if pointee.variable?
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
unless unqualified_type.base_type.same_as?(pointee.type)
|
|
321
|
+
pointee =
|
|
322
|
+
do_conversion(pointee, unqualified_type.base_type) ||
|
|
323
|
+
temporary_variable(unqualified_type.base_type)
|
|
324
|
+
end
|
|
325
|
+
when unqualified_type.base_type.function?
|
|
326
|
+
pointee = define_anonymous_function(unqualified_type.base_type)
|
|
327
|
+
else
|
|
328
|
+
pointee = temporary_variable(unqualified_type.base_type)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
notify_indirection_expr_evaled(node, variable, pointee)
|
|
332
|
+
return pointee
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
temporary_variable
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def execute_unary_arithmetic_expression(node, object)
|
|
339
|
+
if object.variable? && object.type.scalar?
|
|
340
|
+
variable = object
|
|
341
|
+
|
|
342
|
+
if variable.value.scalar?
|
|
343
|
+
case node.operator.type
|
|
344
|
+
when "+"
|
|
345
|
+
result = temporary_variable(variable.type, +variable.value)
|
|
346
|
+
when "-"
|
|
347
|
+
result = temporary_variable(variable.type, -variable.value)
|
|
348
|
+
when "~"
|
|
349
|
+
result = temporary_variable(variable.type, ~variable.value)
|
|
350
|
+
when "!"
|
|
351
|
+
result = temporary_variable(int_type, !variable.value)
|
|
352
|
+
else
|
|
353
|
+
# NOTREACHED
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
notify_unary_arithmetic_expr_evaled(node, variable, result)
|
|
357
|
+
return result
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
temporary_variable
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def execute_cast_expression(node, object)
|
|
365
|
+
resolve_unresolved_type(node.type_name)
|
|
366
|
+
|
|
367
|
+
variable = object_to_variable(object)
|
|
368
|
+
converted =
|
|
369
|
+
do_conversion(variable, node.type_name.type) ||
|
|
370
|
+
temporary_variable(node.type_name.type)
|
|
371
|
+
|
|
372
|
+
notify_explicit_conv_performed(node, variable, converted)
|
|
373
|
+
converted
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def execute_multiplicative_expression(node, lhs_object, rhs_object)
|
|
377
|
+
if lhs_object.function? || rhs_object.function?
|
|
378
|
+
return temporary_variable
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
lhs_variable = lhs_object
|
|
382
|
+
rhs_variable = rhs_object
|
|
383
|
+
|
|
384
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
385
|
+
return temporary_variable
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
389
|
+
return temporary_variable
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
lhs_converted, rhs_converted =
|
|
393
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
394
|
+
|
|
395
|
+
unless lhs_variable == lhs_converted
|
|
396
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
397
|
+
lhs_variable, lhs_converted)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
unless rhs_variable == rhs_converted
|
|
401
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
402
|
+
rhs_variable, rhs_converted)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
case node.operator.type
|
|
406
|
+
when "*"
|
|
407
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
408
|
+
# min-max of the variable type.
|
|
409
|
+
result = temporary_variable(lhs_converted.type,
|
|
410
|
+
lhs_converted.value * rhs_converted.value)
|
|
411
|
+
when "/"
|
|
412
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
413
|
+
# min-max of the variable type.
|
|
414
|
+
# NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
|
|
415
|
+
result = temporary_variable(lhs_converted.type,
|
|
416
|
+
lhs_converted.value / rhs_converted.value)
|
|
417
|
+
when "%"
|
|
418
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
419
|
+
# min-max of the variable type.
|
|
420
|
+
# NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
|
|
421
|
+
result = temporary_variable(lhs_converted.type,
|
|
422
|
+
lhs_converted.value % rhs_converted.value)
|
|
423
|
+
else
|
|
424
|
+
# NOTREACHED
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
notify_multiplicative_expr_evaled(node,
|
|
428
|
+
lhs_variable, rhs_variable, result)
|
|
429
|
+
result
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
def execute_additive_expression(node, lhs_object, rhs_object)
|
|
433
|
+
if lhs_object.function? || rhs_object.function?
|
|
434
|
+
return temporary_variable
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
lhs_variable = lhs_object
|
|
438
|
+
rhs_variable = rhs_object
|
|
439
|
+
|
|
440
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
441
|
+
return temporary_variable
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
445
|
+
return temporary_variable
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
lhs_converted, rhs_converted =
|
|
449
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
450
|
+
|
|
451
|
+
unless lhs_variable == lhs_converted
|
|
452
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
453
|
+
lhs_variable, lhs_converted)
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
unless rhs_variable == rhs_converted
|
|
457
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
458
|
+
rhs_variable, rhs_converted)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
case node.operator.type
|
|
462
|
+
when "+"
|
|
463
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
464
|
+
# min-max of the variable type.
|
|
465
|
+
result = temporary_variable(lhs_converted.type,
|
|
466
|
+
lhs_converted.value + rhs_converted.value)
|
|
467
|
+
when "-"
|
|
468
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
469
|
+
# min-max of the variable type.
|
|
470
|
+
result = temporary_variable(lhs_converted.type,
|
|
471
|
+
lhs_converted.value - rhs_converted.value)
|
|
472
|
+
else
|
|
473
|
+
# NOTREACHED
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
notify_additive_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
477
|
+
result
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def execute_shift_expression(node, lhs_object, rhs_object)
|
|
481
|
+
if lhs_object.function? || rhs_object.function?
|
|
482
|
+
return temporary_variable
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
lhs_variable = lhs_object
|
|
486
|
+
rhs_variable = rhs_object
|
|
487
|
+
|
|
488
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
489
|
+
return temporary_variable
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
493
|
+
return temporary_variable
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
# NOTE: The ISO C99 standard saids;
|
|
497
|
+
#
|
|
498
|
+
# 6.5.7 Bitwise shift operators
|
|
499
|
+
#
|
|
500
|
+
# 3 The integer promotions are performed on each of the operands. The
|
|
501
|
+
# type of the result is that of the promoted left operand. If the
|
|
502
|
+
# value of the right operand is negative or is greater than or equal to
|
|
503
|
+
# the width of the promoted left operand, the behavior is undefined.
|
|
504
|
+
|
|
505
|
+
lhs_converted = do_integer_promotion(lhs_variable)
|
|
506
|
+
unless lhs_variable == lhs_converted
|
|
507
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
508
|
+
lhs_variable, lhs_converted)
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
rhs_converted = do_integer_promotion(rhs_variable)
|
|
512
|
+
unless rhs_variable == rhs_converted
|
|
513
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
514
|
+
rhs_variable, rhs_converted)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
case node.operator.type
|
|
518
|
+
when "<<"
|
|
519
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
520
|
+
# min-max of the variable type.
|
|
521
|
+
result = temporary_variable(lhs_converted.type,
|
|
522
|
+
lhs_converted.value << rhs_converted.value)
|
|
523
|
+
when ">>"
|
|
524
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
525
|
+
# min-max of the variable type.
|
|
526
|
+
result = temporary_variable(lhs_converted.type,
|
|
527
|
+
lhs_converted.value >> rhs_converted.value)
|
|
528
|
+
else
|
|
529
|
+
# NOTREACHED
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
notify_shift_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
533
|
+
result
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
def execute_and_expression(node, lhs_object, rhs_object)
|
|
537
|
+
if lhs_object.function? || rhs_object.function?
|
|
538
|
+
return temporary_variable
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
lhs_variable = lhs_object
|
|
542
|
+
rhs_variable = rhs_object
|
|
543
|
+
|
|
544
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
545
|
+
return temporary_variable
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
549
|
+
return temporary_variable
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
lhs_converted, rhs_converted =
|
|
553
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
554
|
+
|
|
555
|
+
unless lhs_variable == lhs_converted
|
|
556
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
557
|
+
lhs_variable, lhs_converted)
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
unless rhs_variable == rhs_converted
|
|
561
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
562
|
+
rhs_variable, rhs_converted)
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
566
|
+
# min-max of the variable type.
|
|
567
|
+
result = temporary_variable(lhs_converted.type,
|
|
568
|
+
lhs_converted.value & rhs_converted.value)
|
|
569
|
+
|
|
570
|
+
notify_and_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
571
|
+
result
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
def execute_exclusive_or_expression(node, lhs_object, rhs_object)
|
|
575
|
+
if lhs_object.function? || rhs_object.function?
|
|
576
|
+
return temporary_variable
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
lhs_variable = lhs_object
|
|
580
|
+
rhs_variable = rhs_object
|
|
581
|
+
|
|
582
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
583
|
+
return temporary_variable
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
587
|
+
return temporary_variable
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
lhs_converted, rhs_converted =
|
|
591
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
592
|
+
|
|
593
|
+
unless lhs_variable == lhs_converted
|
|
594
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
595
|
+
lhs_variable, lhs_converted)
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
unless rhs_variable == rhs_converted
|
|
599
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
600
|
+
rhs_variable, rhs_converted)
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
604
|
+
# min-max of the variable type.
|
|
605
|
+
result = temporary_variable(lhs_converted.type,
|
|
606
|
+
lhs_converted.value ^ rhs_converted.value)
|
|
607
|
+
|
|
608
|
+
notify_exclusive_or_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
609
|
+
result
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
def execute_inclusive_or_expression(node, lhs_object, rhs_object)
|
|
613
|
+
if lhs_object.function? || rhs_object.function?
|
|
614
|
+
return temporary_variable
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
lhs_variable = lhs_object
|
|
618
|
+
rhs_variable = rhs_object
|
|
619
|
+
|
|
620
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
621
|
+
return temporary_variable
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
unless lhs_variable.value.scalar? && rhs_variable.type.scalar?
|
|
625
|
+
return temporary_variable
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
lhs_converted, rhs_converted =
|
|
629
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
630
|
+
|
|
631
|
+
unless lhs_variable == lhs_converted
|
|
632
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
633
|
+
lhs_variable, lhs_converted)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
unless rhs_variable == rhs_converted
|
|
637
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
638
|
+
rhs_variable, rhs_converted)
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
642
|
+
# min-max of the variable type.
|
|
643
|
+
result = temporary_variable(lhs_converted.type,
|
|
644
|
+
lhs_converted.value | rhs_converted.value)
|
|
645
|
+
|
|
646
|
+
notify_inclusive_or_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
647
|
+
result
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
def execute_simple_assignment_expression(node, lhs_object, rhs_object)
|
|
651
|
+
if lhs_object.variable?
|
|
652
|
+
lhs_variable = lhs_object
|
|
653
|
+
else
|
|
654
|
+
return lhs_object
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
rhs_variable = object_to_variable(rhs_object)
|
|
658
|
+
unless rhs_variable == rhs_object
|
|
659
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
660
|
+
rhs_object, rhs_variable)
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
if lhs_variable.type.same_as?(rhs_object.type)
|
|
664
|
+
rhs_converted = rhs_object
|
|
665
|
+
else
|
|
666
|
+
rhs_converted =
|
|
667
|
+
do_conversion(rhs_object, lhs_variable.type) ||
|
|
668
|
+
temporary_variable(lhs_variable.type)
|
|
669
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
670
|
+
rhs_object, rhs_converted)
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
674
|
+
# min-max of the variable type.
|
|
675
|
+
# NOTE: Even if rhs_object is a NamedVariable, new value will be
|
|
676
|
+
# instantiated in value-coercing.
|
|
677
|
+
# So, value-aliasing never occurs.
|
|
678
|
+
lhs_variable.assign!(rhs_converted.value.to_defined_value)
|
|
679
|
+
notify_assignment_expr_evaled(node, lhs_variable, rhs_converted)
|
|
680
|
+
notify_variable_value_updated(node, lhs_variable)
|
|
681
|
+
|
|
682
|
+
lhs_variable
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
def execute_compound_assignment_expression(node, lhs_object, rhs_object)
|
|
686
|
+
if lhs_object.variable?
|
|
687
|
+
lhs_variable = lhs_object
|
|
688
|
+
else
|
|
689
|
+
return lhs_object
|
|
690
|
+
end
|
|
691
|
+
|
|
692
|
+
rhs_variable = object_to_variable(rhs_object)
|
|
693
|
+
unless rhs_variable == rhs_object
|
|
694
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
695
|
+
rhs_object, rhs_variable)
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
699
|
+
return lhs_variable
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
case node.operator.type
|
|
703
|
+
when "*="
|
|
704
|
+
execute_mul_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
705
|
+
when "/="
|
|
706
|
+
execute_div_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
707
|
+
when "%="
|
|
708
|
+
execute_mod_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
709
|
+
when "+="
|
|
710
|
+
execute_add_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
711
|
+
when "-="
|
|
712
|
+
execute_sub_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
713
|
+
when "<<="
|
|
714
|
+
execute_shl_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
715
|
+
when ">>="
|
|
716
|
+
execute_shr_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
717
|
+
when "&="
|
|
718
|
+
execute_and_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
719
|
+
when "^="
|
|
720
|
+
execute_xor_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
721
|
+
when "|="
|
|
722
|
+
execute_ior_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
notify_variable_value_updated(node, lhs_variable)
|
|
726
|
+
|
|
727
|
+
lhs_variable
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
def execute_mul_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
731
|
+
lhs_converted, rhs_converted =
|
|
732
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
733
|
+
|
|
734
|
+
unless lhs_variable == lhs_converted
|
|
735
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
736
|
+
lhs_variable, lhs_converted)
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
unless rhs_variable == rhs_converted
|
|
740
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
741
|
+
rhs_variable, rhs_converted)
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
745
|
+
result_value = lhs_converted.value * rhs_converted.value
|
|
746
|
+
else
|
|
747
|
+
result_value = lhs_converted.value
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
751
|
+
|
|
752
|
+
notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
|
|
753
|
+
result_variable)
|
|
754
|
+
|
|
755
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
756
|
+
result_converted = result_variable
|
|
757
|
+
else
|
|
758
|
+
result_converted =
|
|
759
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
760
|
+
temporary_variable(lhs_variable.type)
|
|
761
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
762
|
+
result_variable, result_converted)
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
766
|
+
# min-max of the variable type.
|
|
767
|
+
lhs_variable.assign!(result_converted.value)
|
|
768
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
def execute_div_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
772
|
+
lhs_converted, rhs_converted =
|
|
773
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
774
|
+
|
|
775
|
+
unless lhs_variable == lhs_converted
|
|
776
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
777
|
+
lhs_variable, lhs_converted)
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
unless rhs_variable == rhs_converted
|
|
781
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
782
|
+
rhs_variable, rhs_converted)
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
786
|
+
# NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
|
|
787
|
+
result_value = lhs_converted.value / rhs_converted.value
|
|
788
|
+
else
|
|
789
|
+
result_value = lhs_converted.value
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
793
|
+
|
|
794
|
+
notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
|
|
795
|
+
result_variable)
|
|
796
|
+
|
|
797
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
798
|
+
result_converted = result_variable
|
|
799
|
+
else
|
|
800
|
+
result_converted =
|
|
801
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
802
|
+
temporary_variable(lhs_variable.type)
|
|
803
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
804
|
+
result_variable, result_converted)
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
808
|
+
# min-max of the variable type.
|
|
809
|
+
lhs_variable.assign!(result_converted.value)
|
|
810
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def execute_mod_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
814
|
+
lhs_converted, rhs_converted =
|
|
815
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
816
|
+
|
|
817
|
+
unless lhs_variable == lhs_converted
|
|
818
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
819
|
+
lhs_variable, lhs_converted)
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
unless rhs_variable == rhs_converted
|
|
823
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
824
|
+
rhs_variable, rhs_converted)
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
828
|
+
# NOTE: "Div by 0" semantics is implemented in value-value arithmetic.
|
|
829
|
+
result_value = lhs_converted.value % rhs_converted.value
|
|
830
|
+
else
|
|
831
|
+
result_value = lhs_converted.value
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
835
|
+
|
|
836
|
+
notify_multiplicative_expr_evaled(node, lhs_variable, rhs_variable,
|
|
837
|
+
result_variable)
|
|
838
|
+
|
|
839
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
840
|
+
result_converted = result_variable
|
|
841
|
+
else
|
|
842
|
+
result_converted =
|
|
843
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
844
|
+
temporary_variable(lhs_variable.type)
|
|
845
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
846
|
+
result_variable, result_converted)
|
|
847
|
+
end
|
|
848
|
+
|
|
849
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
850
|
+
# min-max of the variable type.
|
|
851
|
+
lhs_variable.assign!(result_converted.value)
|
|
852
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
def execute_add_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
856
|
+
lhs_converted, rhs_converted =
|
|
857
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
858
|
+
|
|
859
|
+
unless lhs_variable == lhs_converted
|
|
860
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
861
|
+
lhs_variable, lhs_converted)
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
unless rhs_variable == rhs_converted
|
|
865
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
866
|
+
rhs_variable, rhs_converted)
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
870
|
+
result_value = lhs_converted.value + rhs_converted.value
|
|
871
|
+
else
|
|
872
|
+
result_value = lhs_converted.value
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
876
|
+
|
|
877
|
+
notify_additive_expr_evaled(node, lhs_variable, rhs_variable,
|
|
878
|
+
result_variable)
|
|
879
|
+
|
|
880
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
881
|
+
result_converted = result_variable
|
|
882
|
+
else
|
|
883
|
+
result_converted =
|
|
884
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
885
|
+
temporary_variable(lhs_variable.type)
|
|
886
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
887
|
+
result_variable, result_converted)
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
891
|
+
# min-max of the variable type.
|
|
892
|
+
lhs_variable.assign!(result_converted.value)
|
|
893
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
def execute_sub_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
897
|
+
lhs_converted, rhs_converted =
|
|
898
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
899
|
+
|
|
900
|
+
unless lhs_variable == lhs_converted
|
|
901
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
902
|
+
lhs_variable, lhs_converted)
|
|
903
|
+
end
|
|
904
|
+
|
|
905
|
+
unless rhs_variable == rhs_converted
|
|
906
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
907
|
+
rhs_variable, rhs_converted)
|
|
908
|
+
end
|
|
909
|
+
|
|
910
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
911
|
+
result_value = lhs_converted.value - rhs_converted.value
|
|
912
|
+
else
|
|
913
|
+
result_value = lhs_converted.value
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
917
|
+
|
|
918
|
+
notify_additive_expr_evaled(node, lhs_variable, rhs_variable,
|
|
919
|
+
result_variable)
|
|
920
|
+
|
|
921
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
922
|
+
result_converted = result_variable
|
|
923
|
+
else
|
|
924
|
+
result_converted =
|
|
925
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
926
|
+
temporary_variable(lhs_variable.type)
|
|
927
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
928
|
+
result_variable, result_converted)
|
|
929
|
+
end
|
|
930
|
+
|
|
931
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
932
|
+
# min-max of the variable type.
|
|
933
|
+
lhs_variable.assign!(result_converted.value)
|
|
934
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
935
|
+
end
|
|
936
|
+
|
|
937
|
+
def execute_shl_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
938
|
+
# NOTE: The ISO C99 standard saids;
|
|
939
|
+
#
|
|
940
|
+
# 6.5.7 Bitwise shift operators
|
|
941
|
+
#
|
|
942
|
+
# 3 The integer promotions are performed on each of the operands. The
|
|
943
|
+
# type of the result is that of the promoted left operand. If the
|
|
944
|
+
# value of the right operand is negative or is greater than or equal to
|
|
945
|
+
# the width of the promoted left operand, the behavior is undefined.
|
|
946
|
+
|
|
947
|
+
lhs_converted = do_integer_promotion(lhs_variable)
|
|
948
|
+
unless lhs_variable == lhs_converted
|
|
949
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
950
|
+
lhs_variable, lhs_converted)
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
rhs_converted = do_integer_promotion(rhs_variable)
|
|
954
|
+
unless rhs_variable == rhs_converted
|
|
955
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
956
|
+
rhs_variable, rhs_converted)
|
|
957
|
+
end
|
|
958
|
+
|
|
959
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
960
|
+
result_value = lhs_converted.value << rhs_converted.value
|
|
961
|
+
else
|
|
962
|
+
result_value = lhs_converted.value
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
966
|
+
|
|
967
|
+
notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
|
|
968
|
+
result_variable)
|
|
969
|
+
|
|
970
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
971
|
+
result_converted = result_variable
|
|
972
|
+
else
|
|
973
|
+
result_converted =
|
|
974
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
975
|
+
temporary_variable(lhs_variable.type)
|
|
976
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
977
|
+
result_variable, result_converted)
|
|
978
|
+
end
|
|
979
|
+
|
|
980
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
981
|
+
# min-max of the variable type.
|
|
982
|
+
lhs_variable.assign!(result_converted.value)
|
|
983
|
+
end
|
|
984
|
+
|
|
985
|
+
def execute_shr_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
986
|
+
# NOTE: The ISO C99 standard saids;
|
|
987
|
+
#
|
|
988
|
+
# 6.5.7 Bitwise shift operators
|
|
989
|
+
#
|
|
990
|
+
# 3 The integer promotions are performed on each of the operands. The
|
|
991
|
+
# type of the result is that of the promoted left operand. If the
|
|
992
|
+
# value of the right operand is negative or is greater than or equal to
|
|
993
|
+
# the width of the promoted left operand, the behavior is undefined.
|
|
994
|
+
|
|
995
|
+
lhs_converted = do_integer_promotion(lhs_variable)
|
|
996
|
+
unless lhs_variable == lhs_converted
|
|
997
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
998
|
+
lhs_variable, lhs_converted)
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
rhs_converted = do_integer_promotion(rhs_variable)
|
|
1002
|
+
unless rhs_variable == rhs_converted
|
|
1003
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
1004
|
+
rhs_variable, rhs_converted)
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
1008
|
+
result_value = lhs_converted.value >> rhs_converted.value
|
|
1009
|
+
else
|
|
1010
|
+
result_value = lhs_converted.value
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
1014
|
+
|
|
1015
|
+
notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
|
|
1016
|
+
result_variable)
|
|
1017
|
+
|
|
1018
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
1019
|
+
result_converted = result_variable
|
|
1020
|
+
else
|
|
1021
|
+
result_converted =
|
|
1022
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
1023
|
+
temporary_variable(lhs_variable.type)
|
|
1024
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1025
|
+
result_variable, result_converted)
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
1029
|
+
# min-max of the variable type.
|
|
1030
|
+
lhs_variable.assign!(result_converted.value)
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
def execute_and_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
1034
|
+
lhs_converted, rhs_converted =
|
|
1035
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
1036
|
+
|
|
1037
|
+
unless lhs_variable == lhs_converted
|
|
1038
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1039
|
+
lhs_variable, lhs_converted)
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
unless rhs_variable == rhs_converted
|
|
1043
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
1044
|
+
rhs_variable, rhs_converted)
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
1048
|
+
result_value = lhs_converted.value & rhs_converted.value
|
|
1049
|
+
else
|
|
1050
|
+
result_value = lhs_converted.value
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
1054
|
+
|
|
1055
|
+
notify_and_expr_evaled(node, lhs_variable, rhs_variable, result_variable)
|
|
1056
|
+
|
|
1057
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
1058
|
+
result_converted = result_variable
|
|
1059
|
+
else
|
|
1060
|
+
result_converted =
|
|
1061
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
1062
|
+
temporary_variable(lhs_variable.type)
|
|
1063
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1064
|
+
result_variable, result_converted)
|
|
1065
|
+
end
|
|
1066
|
+
|
|
1067
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
1068
|
+
# min-max of the variable type.
|
|
1069
|
+
lhs_variable.assign!(result_converted.value)
|
|
1070
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
1071
|
+
end
|
|
1072
|
+
|
|
1073
|
+
def execute_xor_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
1074
|
+
lhs_converted, rhs_converted =
|
|
1075
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
1076
|
+
|
|
1077
|
+
unless lhs_variable == lhs_converted
|
|
1078
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1079
|
+
lhs_variable, lhs_converted)
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
unless rhs_variable == rhs_converted
|
|
1083
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
1084
|
+
rhs_variable, rhs_converted)
|
|
1085
|
+
end
|
|
1086
|
+
|
|
1087
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
1088
|
+
result_value = lhs_converted.value ^ rhs_converted.value
|
|
1089
|
+
else
|
|
1090
|
+
result_value = lhs_converted.value
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1093
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
1094
|
+
|
|
1095
|
+
notify_exclusive_or_expr_evaled(node, lhs_variable, rhs_variable,
|
|
1096
|
+
result_variable)
|
|
1097
|
+
|
|
1098
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
1099
|
+
result_converted = result_variable
|
|
1100
|
+
else
|
|
1101
|
+
result_converted =
|
|
1102
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
1103
|
+
temporary_variable(lhs_variable.type)
|
|
1104
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1105
|
+
result_variable, result_converted)
|
|
1106
|
+
end
|
|
1107
|
+
|
|
1108
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
1109
|
+
# min-max of the variable type.
|
|
1110
|
+
lhs_variable.assign!(result_converted.value)
|
|
1111
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
1112
|
+
end
|
|
1113
|
+
|
|
1114
|
+
def execute_ior_then_assign_expression(node, lhs_variable, rhs_variable)
|
|
1115
|
+
lhs_converted, rhs_converted =
|
|
1116
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
1117
|
+
|
|
1118
|
+
unless lhs_variable == lhs_converted
|
|
1119
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1120
|
+
lhs_variable, lhs_converted)
|
|
1121
|
+
end
|
|
1122
|
+
|
|
1123
|
+
unless rhs_variable == rhs_converted
|
|
1124
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
1125
|
+
rhs_variable, rhs_converted)
|
|
1126
|
+
end
|
|
1127
|
+
|
|
1128
|
+
if lhs_converted.value.scalar? && rhs_converted.value.scalar?
|
|
1129
|
+
result_value = lhs_converted.value | rhs_converted.value
|
|
1130
|
+
else
|
|
1131
|
+
result_value = lhs_converted.value
|
|
1132
|
+
end
|
|
1133
|
+
|
|
1134
|
+
result_variable = temporary_variable(lhs_converted.type, result_value)
|
|
1135
|
+
|
|
1136
|
+
notify_inclusive_or_expr_evaled(node, lhs_variable, rhs_variable,
|
|
1137
|
+
result_variable)
|
|
1138
|
+
|
|
1139
|
+
if lhs_variable.type.same_as?(result_variable.type)
|
|
1140
|
+
result_converted = result_variable
|
|
1141
|
+
else
|
|
1142
|
+
result_converted =
|
|
1143
|
+
do_conversion(result_variable, lhs_variable.type) ||
|
|
1144
|
+
temporary_variable(lhs_variable.type)
|
|
1145
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1146
|
+
result_variable, result_converted)
|
|
1147
|
+
end
|
|
1148
|
+
|
|
1149
|
+
# NOTE: Domain of the arithmetic result value will be restricted by
|
|
1150
|
+
# min-max of the variable type.
|
|
1151
|
+
lhs_variable.assign!(result_converted.value)
|
|
1152
|
+
notify_assignment_expr_evaled(node, lhs_variable, result_converted)
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
def variable_reassigning_context(&block)
|
|
1156
|
+
expr_context_stack.push(:variable_reassigning)
|
|
1157
|
+
yield
|
|
1158
|
+
ensure
|
|
1159
|
+
expr_context_stack.pop
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
def variable_reassigning?
|
|
1163
|
+
expr_context_stack.last == :variable_reassigning
|
|
1164
|
+
end
|
|
1165
|
+
|
|
1166
|
+
def function_calling_context(&block)
|
|
1167
|
+
expr_context_stack.push(:function_calling)
|
|
1168
|
+
yield
|
|
1169
|
+
ensure
|
|
1170
|
+
expr_context_stack.pop
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
def function_calling?
|
|
1174
|
+
expr_context_stack.last == :function_calling
|
|
1175
|
+
end
|
|
1176
|
+
|
|
1177
|
+
def expr_context_stack
|
|
1178
|
+
@expr_context_stack ||= []
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
def char_array_value(string_literal)
|
|
1182
|
+
chars = string_literal.chars.map { |ch| ScalarValue.of(ch.ord) }
|
|
1183
|
+
ArrayValue.new(chars + [ScalarValue.of("\0".ord)])
|
|
1184
|
+
end
|
|
1185
|
+
|
|
1186
|
+
def wchar_array_value(string_literal)
|
|
1187
|
+
chars = string_literal.chars.map { |ch| ScalarValue.of(ch.ord) }
|
|
1188
|
+
ArrayValue.new(chars + [ScalarValue.of("\0".ord)])
|
|
1189
|
+
end
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
module ExpressionEvaluator
|
|
1193
|
+
# NOTE: Host class of this module must include InterpreterMediator and
|
|
1194
|
+
# MonitorUtil.
|
|
1195
|
+
|
|
1196
|
+
include NotifierMediator
|
|
1197
|
+
include ConstantEvaluator
|
|
1198
|
+
include Conversion
|
|
1199
|
+
include ExpressionUtil
|
|
1200
|
+
|
|
1201
|
+
def visit_error_expression(node)
|
|
1202
|
+
checkpoint(node.location)
|
|
1203
|
+
|
|
1204
|
+
temporary_variable
|
|
1205
|
+
end
|
|
1206
|
+
|
|
1207
|
+
def visit_object_specifier(node)
|
|
1208
|
+
checkpoint(node.location)
|
|
1209
|
+
|
|
1210
|
+
if variable = variable_named(node.identifier.value)
|
|
1211
|
+
notify_variable_referred(node, variable)
|
|
1212
|
+
unless variable_reassigning?
|
|
1213
|
+
notify_variable_value_referred(node, variable)
|
|
1214
|
+
end
|
|
1215
|
+
variable.declarations_and_definitions.each do |decl_or_def|
|
|
1216
|
+
decl_or_def.mark_as_referred_by(node.identifier)
|
|
1217
|
+
end
|
|
1218
|
+
if variable.type.array?
|
|
1219
|
+
variable = temporary_variable(pointer_type(variable.type.base_type),
|
|
1220
|
+
pointer_value_of(variable))
|
|
1221
|
+
end
|
|
1222
|
+
return variable
|
|
1223
|
+
end
|
|
1224
|
+
|
|
1225
|
+
if function = function_named(node.identifier.value)
|
|
1226
|
+
unless function_calling?
|
|
1227
|
+
notify_function_referred(node, function)
|
|
1228
|
+
end
|
|
1229
|
+
function.declarations_and_definitions.each do |decl_or_def|
|
|
1230
|
+
decl_or_def.mark_as_referred_by(node.identifier)
|
|
1231
|
+
end
|
|
1232
|
+
return function
|
|
1233
|
+
end
|
|
1234
|
+
|
|
1235
|
+
if enumerator = enumerator_named(node.identifier.value)
|
|
1236
|
+
enumerator.mark_as_referred_by(node.identifier)
|
|
1237
|
+
return temporary_variable(int_type, ScalarValue.of(enumerator.value))
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
define_implicit_function(node.identifier.value)
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
def visit_constant_specifier(node)
|
|
1244
|
+
checkpoint(node.location)
|
|
1245
|
+
|
|
1246
|
+
if variable = eval_constant(node)
|
|
1247
|
+
notify_constant_referred(node, variable)
|
|
1248
|
+
variable
|
|
1249
|
+
else
|
|
1250
|
+
temporary_variable
|
|
1251
|
+
end
|
|
1252
|
+
end
|
|
1253
|
+
|
|
1254
|
+
def visit_string_literal_specifier(node)
|
|
1255
|
+
checkpoint(node.location)
|
|
1256
|
+
|
|
1257
|
+
case node.literal.value
|
|
1258
|
+
when /\A"(.*)"\z/
|
|
1259
|
+
array = temporary_variable(array_type(char_type, $1.length + 1),
|
|
1260
|
+
char_array_value($1))
|
|
1261
|
+
when /\AL"(.*)"\z/i
|
|
1262
|
+
array = temporary_variable(array_type(wchar_type, $1.length + 1),
|
|
1263
|
+
wchar_array_value($1))
|
|
1264
|
+
else
|
|
1265
|
+
return temporary_variable(pointer_type(char_type))
|
|
1266
|
+
end
|
|
1267
|
+
|
|
1268
|
+
temporary_variable(pointer_type(array.type.base_type),
|
|
1269
|
+
pointer_value_of(array))
|
|
1270
|
+
end
|
|
1271
|
+
|
|
1272
|
+
def visit_null_constant_specifier(node)
|
|
1273
|
+
checkpoint(node.location)
|
|
1274
|
+
|
|
1275
|
+
# TODO: NULL may not be 0 on some environments.
|
|
1276
|
+
# Representation of NULL should be configurable?
|
|
1277
|
+
temporary_variable(pointer_type(void_type), ScalarValue.of(0))
|
|
1278
|
+
end
|
|
1279
|
+
|
|
1280
|
+
def visit_grouped_expression(node)
|
|
1281
|
+
checkpoint(node.location)
|
|
1282
|
+
|
|
1283
|
+
node.expression.accept(self)
|
|
1284
|
+
end
|
|
1285
|
+
|
|
1286
|
+
def visit_array_subscript_expression(node)
|
|
1287
|
+
checkpoint(node.location)
|
|
1288
|
+
|
|
1289
|
+
execute_array_subscript_expression(
|
|
1290
|
+
node, node.expression.accept(self), node.array_subscript.accept(self))
|
|
1291
|
+
end
|
|
1292
|
+
|
|
1293
|
+
def visit_function_call_expression(node)
|
|
1294
|
+
checkpoint(node.location)
|
|
1295
|
+
|
|
1296
|
+
object = function_calling_context { node.expression.accept(self) }
|
|
1297
|
+
args = node.argument_expressions.map { |expr| [expr.accept(self), expr] }
|
|
1298
|
+
|
|
1299
|
+
execute_function_call_expression(node, object, args)
|
|
1300
|
+
end
|
|
1301
|
+
|
|
1302
|
+
def visit_member_access_by_value_expression(node)
|
|
1303
|
+
checkpoint(node.location)
|
|
1304
|
+
|
|
1305
|
+
object = node.expression.accept(self)
|
|
1306
|
+
|
|
1307
|
+
execute_member_access_by_value_expression(node, object)
|
|
1308
|
+
end
|
|
1309
|
+
|
|
1310
|
+
def visit_member_access_by_pointer_expression(node)
|
|
1311
|
+
checkpoint(node.location)
|
|
1312
|
+
|
|
1313
|
+
object = node.expression.accept(self)
|
|
1314
|
+
|
|
1315
|
+
execute_member_access_by_pointer_expression(node, object)
|
|
1316
|
+
end
|
|
1317
|
+
|
|
1318
|
+
def visit_bit_access_by_value_expression(node)
|
|
1319
|
+
checkpoint(node.location)
|
|
1320
|
+
|
|
1321
|
+
# TODO: Should support the GCC extension.
|
|
1322
|
+
temporary_variable
|
|
1323
|
+
end
|
|
1324
|
+
|
|
1325
|
+
def visit_bit_access_by_pointer_expression(node)
|
|
1326
|
+
checkpoint(node.location)
|
|
1327
|
+
|
|
1328
|
+
# TODO: Should support the GCC extension.
|
|
1329
|
+
temporary_variable
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
def visit_postfix_increment_expression(node)
|
|
1333
|
+
checkpoint(node.location)
|
|
1334
|
+
|
|
1335
|
+
object = variable_reassigning_context { node.operand.accept(self) }
|
|
1336
|
+
|
|
1337
|
+
execute_postfix_increment_expression(node, object)
|
|
1338
|
+
end
|
|
1339
|
+
|
|
1340
|
+
def visit_postfix_decrement_expression(node)
|
|
1341
|
+
checkpoint(node.location)
|
|
1342
|
+
|
|
1343
|
+
object = variable_reassigning_context { node.operand.accept(self) }
|
|
1344
|
+
|
|
1345
|
+
execute_postfix_decrement_expression(node, object)
|
|
1346
|
+
end
|
|
1347
|
+
|
|
1348
|
+
def visit_compound_literal_expression(node)
|
|
1349
|
+
checkpoint(node.location)
|
|
1350
|
+
|
|
1351
|
+
# TODO: Should support C99 features.
|
|
1352
|
+
temporary_variable(node.type_name.type)
|
|
1353
|
+
end
|
|
1354
|
+
|
|
1355
|
+
def visit_prefix_increment_expression(node)
|
|
1356
|
+
checkpoint(node.location)
|
|
1357
|
+
|
|
1358
|
+
object = variable_reassigning_context { node.operand.accept(self) }
|
|
1359
|
+
|
|
1360
|
+
execute_prefix_increment_expression(node, object)
|
|
1361
|
+
end
|
|
1362
|
+
|
|
1363
|
+
def visit_prefix_decrement_expression(node)
|
|
1364
|
+
checkpoint(node.location)
|
|
1365
|
+
|
|
1366
|
+
object = variable_reassigning_context { node.operand.accept(self) }
|
|
1367
|
+
|
|
1368
|
+
execute_prefix_decrement_expression(node, object)
|
|
1369
|
+
end
|
|
1370
|
+
|
|
1371
|
+
def visit_address_expression(node)
|
|
1372
|
+
checkpoint(node.location)
|
|
1373
|
+
|
|
1374
|
+
object = node.operand.accept(self)
|
|
1375
|
+
temporary_variable(pointer_type(object.type), pointer_value_of(object))
|
|
1376
|
+
end
|
|
1377
|
+
|
|
1378
|
+
def visit_indirection_expression(node)
|
|
1379
|
+
checkpoint(node.location)
|
|
1380
|
+
|
|
1381
|
+
object = node.operand.accept(self)
|
|
1382
|
+
|
|
1383
|
+
execute_indirection_expression(node, object)
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
def visit_unary_arithmetic_expression(node)
|
|
1387
|
+
checkpoint(node.location)
|
|
1388
|
+
|
|
1389
|
+
object = node.operand.accept(self)
|
|
1390
|
+
|
|
1391
|
+
execute_unary_arithmetic_expression(node, object)
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1394
|
+
def visit_sizeof_expression(node)
|
|
1395
|
+
checkpoint(node.location)
|
|
1396
|
+
|
|
1397
|
+
object = node.operand.accept(self)
|
|
1398
|
+
if object.variable?
|
|
1399
|
+
variable = object
|
|
1400
|
+
result = temporary_variable(
|
|
1401
|
+
int_type, ScalarValue.of(variable.type.aligned_byte_size))
|
|
1402
|
+
notify_sizeof_expr_evaled(node, variable, result)
|
|
1403
|
+
else
|
|
1404
|
+
result = temporary_variable(int_type)
|
|
1405
|
+
end
|
|
1406
|
+
|
|
1407
|
+
result
|
|
1408
|
+
end
|
|
1409
|
+
|
|
1410
|
+
def visit_sizeof_type_expression(node)
|
|
1411
|
+
checkpoint(node.location)
|
|
1412
|
+
|
|
1413
|
+
resolve_unresolved_type(node.operand)
|
|
1414
|
+
|
|
1415
|
+
result = temporary_variable(
|
|
1416
|
+
int_type, ScalarValue.of(node.operand.type.aligned_byte_size))
|
|
1417
|
+
notify_sizeof_type_expr_evaled(node, node.operand.type, result)
|
|
1418
|
+
|
|
1419
|
+
result
|
|
1420
|
+
end
|
|
1421
|
+
|
|
1422
|
+
def visit_alignof_expression(node)
|
|
1423
|
+
checkpoint(node.location)
|
|
1424
|
+
|
|
1425
|
+
object = node.operand.accept(self)
|
|
1426
|
+
if object.variable?
|
|
1427
|
+
variable = object
|
|
1428
|
+
temporary_variable(int_type,
|
|
1429
|
+
ScalarValue.of(variable.type.byte_alignment))
|
|
1430
|
+
else
|
|
1431
|
+
temporary_variable(int_type)
|
|
1432
|
+
end
|
|
1433
|
+
end
|
|
1434
|
+
|
|
1435
|
+
def visit_alignof_type_expression(node)
|
|
1436
|
+
checkpoint(node.location)
|
|
1437
|
+
|
|
1438
|
+
resolve_unresolved_type(node.operand)
|
|
1439
|
+
|
|
1440
|
+
temporary_variable(int_type,
|
|
1441
|
+
ScalarValue.of(node.operand.type.aligned_byte_size))
|
|
1442
|
+
end
|
|
1443
|
+
|
|
1444
|
+
def visit_cast_expression(node)
|
|
1445
|
+
checkpoint(node.location)
|
|
1446
|
+
|
|
1447
|
+
object = node.operand.accept(self)
|
|
1448
|
+
|
|
1449
|
+
execute_cast_expression(node, object)
|
|
1450
|
+
end
|
|
1451
|
+
|
|
1452
|
+
def visit_multiplicative_expression(node)
|
|
1453
|
+
checkpoint(node.location)
|
|
1454
|
+
|
|
1455
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1456
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1457
|
+
|
|
1458
|
+
execute_multiplicative_expression(node, lhs_object, rhs_object)
|
|
1459
|
+
end
|
|
1460
|
+
|
|
1461
|
+
def visit_additive_expression(node)
|
|
1462
|
+
checkpoint(node.location)
|
|
1463
|
+
|
|
1464
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1465
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1466
|
+
|
|
1467
|
+
execute_additive_expression(node, lhs_object, rhs_object)
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1470
|
+
def visit_shift_expression(node)
|
|
1471
|
+
checkpoint(node.location)
|
|
1472
|
+
|
|
1473
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1474
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1475
|
+
|
|
1476
|
+
execute_shift_expression(node, lhs_object, rhs_object)
|
|
1477
|
+
end
|
|
1478
|
+
|
|
1479
|
+
def visit_relational_expression(node)
|
|
1480
|
+
checkpoint(node.location)
|
|
1481
|
+
|
|
1482
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1483
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1484
|
+
|
|
1485
|
+
if lhs_object.function? || rhs_object.function?
|
|
1486
|
+
return temporary_variable(int_type)
|
|
1487
|
+
end
|
|
1488
|
+
|
|
1489
|
+
lhs_variable = lhs_object
|
|
1490
|
+
rhs_variable = rhs_object
|
|
1491
|
+
|
|
1492
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
1493
|
+
return temporary_variable(int_type)
|
|
1494
|
+
end
|
|
1495
|
+
|
|
1496
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
1497
|
+
return temporary_variable(int_type)
|
|
1498
|
+
end
|
|
1499
|
+
|
|
1500
|
+
lhs_converted, rhs_converted =
|
|
1501
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
1502
|
+
|
|
1503
|
+
unless lhs_variable == lhs_converted
|
|
1504
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1505
|
+
lhs_variable, lhs_converted)
|
|
1506
|
+
end
|
|
1507
|
+
|
|
1508
|
+
unless rhs_variable == rhs_converted
|
|
1509
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
1510
|
+
rhs_variable, rhs_converted)
|
|
1511
|
+
end
|
|
1512
|
+
|
|
1513
|
+
case node.operator.type
|
|
1514
|
+
when "<"
|
|
1515
|
+
result = temporary_variable(int_type,
|
|
1516
|
+
lhs_converted.value < rhs_converted.value)
|
|
1517
|
+
when ">"
|
|
1518
|
+
result = temporary_variable(int_type,
|
|
1519
|
+
lhs_converted.value > rhs_converted.value)
|
|
1520
|
+
when "<="
|
|
1521
|
+
result = temporary_variable(int_type,
|
|
1522
|
+
lhs_converted.value <= rhs_converted.value)
|
|
1523
|
+
when ">="
|
|
1524
|
+
result = temporary_variable(int_type,
|
|
1525
|
+
lhs_converted.value >= rhs_converted.value)
|
|
1526
|
+
else
|
|
1527
|
+
# NOTREACHED
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
notify_relational_expr_evaled(node, lhs_converted, rhs_converted, result)
|
|
1531
|
+
result
|
|
1532
|
+
end
|
|
1533
|
+
|
|
1534
|
+
def visit_equality_expression(node)
|
|
1535
|
+
checkpoint(node.location)
|
|
1536
|
+
|
|
1537
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1538
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1539
|
+
|
|
1540
|
+
if lhs_object.function? || rhs_object.function?
|
|
1541
|
+
return temporary_variable(int_type)
|
|
1542
|
+
end
|
|
1543
|
+
|
|
1544
|
+
lhs_variable = lhs_object
|
|
1545
|
+
rhs_variable = rhs_object
|
|
1546
|
+
|
|
1547
|
+
unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
|
|
1548
|
+
return temporary_variable(int_type)
|
|
1549
|
+
end
|
|
1550
|
+
|
|
1551
|
+
unless lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
1552
|
+
return temporary_variable(int_type)
|
|
1553
|
+
end
|
|
1554
|
+
|
|
1555
|
+
lhs_converted, rhs_converted =
|
|
1556
|
+
do_usual_arithmetic_conversion(lhs_variable, rhs_variable)
|
|
1557
|
+
|
|
1558
|
+
unless lhs_variable == lhs_converted
|
|
1559
|
+
notify_implicit_conv_performed(node.lhs_operand,
|
|
1560
|
+
lhs_variable, lhs_converted)
|
|
1561
|
+
end
|
|
1562
|
+
|
|
1563
|
+
unless rhs_variable == rhs_converted
|
|
1564
|
+
notify_implicit_conv_performed(node.rhs_operand,
|
|
1565
|
+
rhs_variable, rhs_converted)
|
|
1566
|
+
end
|
|
1567
|
+
|
|
1568
|
+
case node.operator.type
|
|
1569
|
+
when "=="
|
|
1570
|
+
result = temporary_variable(int_type,
|
|
1571
|
+
lhs_converted.value == rhs_converted.value)
|
|
1572
|
+
when "!="
|
|
1573
|
+
result = temporary_variable(int_type,
|
|
1574
|
+
lhs_converted.value != rhs_converted.value)
|
|
1575
|
+
else
|
|
1576
|
+
# NOTREACHED
|
|
1577
|
+
end
|
|
1578
|
+
|
|
1579
|
+
notify_equality_expr_evaled(node, lhs_converted, rhs_converted, result)
|
|
1580
|
+
result
|
|
1581
|
+
end
|
|
1582
|
+
|
|
1583
|
+
def visit_and_expression(node)
|
|
1584
|
+
checkpoint(node.location)
|
|
1585
|
+
|
|
1586
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1587
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1588
|
+
|
|
1589
|
+
execute_and_expression(node, lhs_object, rhs_object)
|
|
1590
|
+
end
|
|
1591
|
+
|
|
1592
|
+
def visit_exclusive_or_expression(node)
|
|
1593
|
+
checkpoint(node.location)
|
|
1594
|
+
|
|
1595
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1596
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1597
|
+
|
|
1598
|
+
execute_exclusive_or_expression(node, lhs_object, rhs_object)
|
|
1599
|
+
end
|
|
1600
|
+
|
|
1601
|
+
def visit_inclusive_or_expression(node)
|
|
1602
|
+
checkpoint(node.location)
|
|
1603
|
+
|
|
1604
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1605
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1606
|
+
|
|
1607
|
+
execute_inclusive_or_expression(node, lhs_object, rhs_object)
|
|
1608
|
+
end
|
|
1609
|
+
|
|
1610
|
+
def visit_logical_and_expression(node)
|
|
1611
|
+
checkpoint(node.location)
|
|
1612
|
+
|
|
1613
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1614
|
+
return temporary_variable(int_type) unless lhs_object.variable?
|
|
1615
|
+
|
|
1616
|
+
lhs_variable = lhs_object
|
|
1617
|
+
if lhs_variable.value.scalar? && lhs_variable.value.must_be_false?
|
|
1618
|
+
# NOTE: Doing the short-circuit evaluation.
|
|
1619
|
+
return temporary_variable(int_type, ScalarValue.of_false)
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1622
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1623
|
+
return temporary_variable(int_type) unless rhs_object.variable?
|
|
1624
|
+
|
|
1625
|
+
rhs_variable = rhs_object
|
|
1626
|
+
|
|
1627
|
+
if lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
1628
|
+
# NOTE: No usual-arithmetic-conversion.
|
|
1629
|
+
result = temporary_variable(
|
|
1630
|
+
int_type, lhs_variable.value.logical_and(rhs_variable.value))
|
|
1631
|
+
else
|
|
1632
|
+
result = temporary_variable(int_type)
|
|
1633
|
+
end
|
|
1634
|
+
|
|
1635
|
+
notify_logical_and_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
1636
|
+
result
|
|
1637
|
+
end
|
|
1638
|
+
|
|
1639
|
+
def visit_logical_or_expression(node)
|
|
1640
|
+
checkpoint(node.location)
|
|
1641
|
+
|
|
1642
|
+
lhs_object = node.lhs_operand.accept(self)
|
|
1643
|
+
return temporary_variable(int_type) unless lhs_object.variable?
|
|
1644
|
+
|
|
1645
|
+
lhs_variable = lhs_object
|
|
1646
|
+
if lhs_variable.value.scalar? && lhs_variable.value.must_be_true?
|
|
1647
|
+
# NOTE: Doing the short-circuit evaluation.
|
|
1648
|
+
return temporary_variable(int_type, ScalarValue.of_true)
|
|
1649
|
+
end
|
|
1650
|
+
|
|
1651
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1652
|
+
return temporary_variable(int_type) unless rhs_object.variable?
|
|
1653
|
+
|
|
1654
|
+
rhs_variable = rhs_object
|
|
1655
|
+
|
|
1656
|
+
if lhs_variable.value.scalar? && rhs_variable.value.scalar?
|
|
1657
|
+
# NOTE: No usual-arithmetic-conversion.
|
|
1658
|
+
result = temporary_variable(
|
|
1659
|
+
int_type, lhs_variable.value.logical_or(rhs_variable.value))
|
|
1660
|
+
else
|
|
1661
|
+
result = temporary_variable(int_type)
|
|
1662
|
+
end
|
|
1663
|
+
|
|
1664
|
+
notify_logical_or_expr_evaled(node, lhs_variable, rhs_variable, result)
|
|
1665
|
+
result
|
|
1666
|
+
end
|
|
1667
|
+
|
|
1668
|
+
def visit_conditional_expression(node)
|
|
1669
|
+
checkpoint(node.location)
|
|
1670
|
+
|
|
1671
|
+
condition_object = node.condition.accept(self)
|
|
1672
|
+
|
|
1673
|
+
if condition_object.variable?
|
|
1674
|
+
case
|
|
1675
|
+
when condition_object.value.must_be_true?
|
|
1676
|
+
result_object = node.then_expression.accept(self)
|
|
1677
|
+
when condition_object.value.must_be_false?
|
|
1678
|
+
result_object = node.else_expression.accept(self)
|
|
1679
|
+
else
|
|
1680
|
+
then_object = node.then_expression.accept(self)
|
|
1681
|
+
else_object = node.else_expression.accept(self)
|
|
1682
|
+
if then_object.variable? && else_object.variable?
|
|
1683
|
+
result_value =
|
|
1684
|
+
then_object.value.single_value_unified_with(else_object.value)
|
|
1685
|
+
result_object = temporary_variable(then_object.type, result_value)
|
|
1686
|
+
end
|
|
1687
|
+
end
|
|
1688
|
+
end
|
|
1689
|
+
|
|
1690
|
+
result = result_object ? result_object : temporary_variable
|
|
1691
|
+
notify_conditional_expr_evaled(node, condition_object, result)
|
|
1692
|
+
result
|
|
1693
|
+
end
|
|
1694
|
+
|
|
1695
|
+
def visit_simple_assignment_expression(node)
|
|
1696
|
+
checkpoint(node.location)
|
|
1697
|
+
|
|
1698
|
+
lhs_object = variable_reassigning_context {
|
|
1699
|
+
node.lhs_operand.accept(self)
|
|
1700
|
+
}
|
|
1701
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1702
|
+
|
|
1703
|
+
execute_simple_assignment_expression(node, lhs_object, rhs_object)
|
|
1704
|
+
end
|
|
1705
|
+
|
|
1706
|
+
def visit_compound_assignment_expression(node)
|
|
1707
|
+
checkpoint(node.location)
|
|
1708
|
+
|
|
1709
|
+
lhs_object = variable_reassigning_context {
|
|
1710
|
+
node.lhs_operand.accept(self)
|
|
1711
|
+
}
|
|
1712
|
+
rhs_object = node.rhs_operand.accept(self)
|
|
1713
|
+
|
|
1714
|
+
execute_compound_assignment_expression(node, lhs_object, rhs_object)
|
|
1715
|
+
end
|
|
1716
|
+
|
|
1717
|
+
def visit_comma_separated_expression(node)
|
|
1718
|
+
checkpoint(node.location)
|
|
1719
|
+
|
|
1720
|
+
node.expressions.map { |expression| expression.accept(self) }.last
|
|
1721
|
+
end
|
|
1722
|
+
end
|
|
1723
|
+
|
|
1724
|
+
end
|
|
1725
|
+
end
|