module AdLint::Cc1::ExpressionEvaluator
Public Instance Methods
visit_additive_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 253 def visit_additive_expression(node) checkpoint(node.location) eval_additive_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_address_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 159 def visit_address_expression(node) checkpoint(node.location) eval_address_expr(node, node.operand.accept(self)) end
visit_alignof_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 208 def visit_alignof_expression(node) checkpoint(node.location) ope_obj = rslt_var = nil eval_quietly_without_side_effects do rslt_type = type_of(UserTypeId.new("size_t")) || unsigned_long_t ope_obj = node.operand.accept(self) if ope_obj.variable? align = ope_obj.type.byte_alignment rslt_var = create_tmpvar(rslt_type, scalar_value_of(align)) else rslt_var = create_tmpvar(rslt_type) end end notify_alignof_expr_evaled(node, ope_obj, rslt_var) rslt_var end
visit_alignof_type_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 227 def visit_alignof_type_expression(node) checkpoint(node.location) resolve_unresolved_type(node.operand) rslt_var = nil eval_quietly_without_side_effects do rslt_type = type_of(UserTypeId.new("size_t")) || unsigned_long_t align = node.operand.type.aligned_byte_size rslt_var = create_tmpvar(rslt_type, scalar_value_of(align)) end notify_alignof_type_expr_evaled(node, node.operand.type, rslt_var) rslt_var end
visit_and_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 277 def visit_and_expression(node) checkpoint(node.location) eval_and_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_array_subscript_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 102 def visit_array_subscript_expression(node) checkpoint(node.location) eval_array_subscript_expr(node, node.expression.accept(self), node.array_subscript.accept(self)) end
visit_bit_access_by_pointer_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 129 def visit_bit_access_by_pointer_expression(node) checkpoint(node.location) eval_bit_access_by_pointer_expr(node, node.expression.accept(self)) end
visit_bit_access_by_value_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 124 def visit_bit_access_by_value_expression(node) checkpoint(node.location) eval_bit_access_by_value_expr(node, node.expression.accept(self)) end
visit_cast_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 242 def visit_cast_expression(node) checkpoint(node.location) eval_cast_expr(node, node.operand.accept(self)) end
visit_comma_separated_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 411 def visit_comma_separated_expression(node) checkpoint(node.location) node.expressions.map { |expr| expr.accept(self) }.last end
visit_compound_assignment_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 405 def visit_compound_assignment_expression(node) checkpoint(node.location) eval_compound_assignment_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_compound_literal_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 144 def visit_compound_literal_expression(node) checkpoint(node.location) eval_compound_literal_expr(node) end
visit_constant_specifier(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 58 def visit_constant_specifier(node) checkpoint(node.location) if const_var = eval_constant(node) notify_constant_referred(node, const_var) rslt_var = const_var else rslt_var = create_tmpvar end notify_constant_specifier_evaled(node, rslt_var) rslt_var end
visit_equality_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 271 def visit_equality_expression(node) checkpoint(node.location) eval_equality_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_error_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 48 def visit_error_expression(node) checkpoint(node.location) create_tmpvar.tap { |rslt_var| notify_error_expr_evaled(node, rslt_var) } end
visit_exclusive_or_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 283 def visit_exclusive_or_expression(node) checkpoint(node.location) eval_exclusive_or_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_function_call_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 108 def visit_function_call_expression(node) checkpoint(node.location) args = node.argument_expressions.map { |expr| [expr.accept(self), expr] } eval_function_call_expr(node, node.expression.accept(self), args) end
visit_grouped_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 97 def visit_grouped_expression(node) checkpoint(node.location) node.expression.accept(self) end
visit_inclusive_or_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 289 def visit_inclusive_or_expression(node) checkpoint(node.location) eval_inclusive_or_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_indirection_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 164 def visit_indirection_expression(node) checkpoint(node.location) eval_indirection_expr(node, node.operand.accept(self)) end
visit_logical_and_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 295 def visit_logical_and_expression(node) checkpoint(node.location) lhs_obj = node.lhs_operand.accept(self) if lhs_obj.variable? lhs_var = lhs_obj else return create_tmpvar(int_t) end # NOTE: The ISO C99 standard says; # # 6.5.13 Logical AND operator # # Semantics # # 4 Unlike the bitwise binary & operator, the && operator guarantees # left-to-right evaluation; there is a sequence point after the # evaluation of the first operand. If the first operand compares equal # to 0, the second operand is not evaluated. notify_sequence_point_reached(SequencePoint.new(node.lhs_operand)) lhs_val = lhs_var.value if lhs_val.scalar? && lhs_val.test_must_be_false.true? # NOTE: Doing the short-circuit evaluation. notify_variable_value_referred(node, lhs_var) return create_tmpvar(int_t, scalar_value_of_false) end rhs_obj = node.rhs_operand.accept(self) if rhs_obj.variable? rhs_var = rhs_obj else return create_tmpvar(int_t) end notify_sequence_point_reached(SequencePoint.new(node.rhs_operand)) rhs_val = rhs_var.value if lhs_val.scalar? && rhs_val.scalar? # NOTE: No usual-arithmetic-conversion. rslt_var = create_tmpvar(int_t, lhs_val.logical_and(rhs_val)) else rslt_var = create_tmpvar(int_t) end notify_variable_value_referred(node, lhs_var) notify_variable_value_referred(node, rhs_var) notify_logical_and_expr_evaled(node, lhs_var, rhs_var, rslt_var) rslt_var end
visit_logical_or_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 347 def visit_logical_or_expression(node) checkpoint(node.location) lhs_obj = node.lhs_operand.accept(self) if lhs_obj.variable? lhs_var = lhs_obj else return create_tmpvar(int_t) end # NOTE: The ISO C99 standard says; # # 6.5.14 Logical OR operator # # Semantics # # 4 Unlike the bitwise | operator, the || operator guarantees # left-to-right evaluation; there is a sequence point after the # evaluation of the first operand. If the first operand compares # unequal to 0, the second operand is not evaluated. notify_sequence_point_reached(SequencePoint.new(node.lhs_operand)) lhs_val = lhs_var.value if lhs_val.scalar? && lhs_val.test_must_be_true.true? # NOTE: Doing the short-circuit evaluation. notify_variable_value_referred(node, lhs_var) return create_tmpvar(int_t, scalar_value_of_true) end rhs_obj = node.rhs_operand.accept(self) if rhs_obj.variable? rhs_var = rhs_obj else return create_tmpvar(int_t) end notify_sequence_point_reached(SequencePoint.new(node.rhs_operand)) rhs_val = rhs_var.value if lhs_val.scalar? && rhs_val.scalar? # NOTE: No usual-arithmetic-conversion. rslt_var = create_tmpvar(int_t, lhs_val.logical_or(rhs_val)) else rslt_var = create_tmpvar(int_t) end notify_variable_value_referred(node, lhs_var) notify_variable_value_referred(node, rhs_var) notify_logical_or_expr_evaled(node, lhs_var, rhs_var, rslt_var) rslt_var end
visit_member_access_by_pointer_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 119 def visit_member_access_by_pointer_expression(node) checkpoint(node.location) eval_member_access_by_pointer_expr(node,node.expression.accept(self)) end
visit_member_access_by_value_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 114 def visit_member_access_by_value_expression(node) checkpoint(node.location) eval_member_access_by_value_expr(node, node.expression.accept(self)) end
visit_multiplicative_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 247 def visit_multiplicative_expression(node) checkpoint(node.location) eval_multiplicative_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_null_constant_specifier(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 90 def visit_null_constant_specifier(node) checkpoint(node.location) rslt_var = create_tmpvar(pointer_type(void_t), scalar_value_of_null) notify_null_constant_specifier_evaled(node, rslt_var) rslt_var end
visit_object_specifier(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 53 def visit_object_specifier(node) checkpoint(node.location) eval_object_specifier(node) end
visit_postfix_decrement_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 139 def visit_postfix_decrement_expression(node) checkpoint(node.location) eval_postfix_decrement_expr(node, node.operand.accept(self)) end
visit_postfix_increment_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 134 def visit_postfix_increment_expression(node) checkpoint(node.location) eval_postfix_increment_expr(node, node.operand.accept(self)) end
visit_prefix_decrement_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 154 def visit_prefix_decrement_expression(node) checkpoint(node.location) eval_prefix_decrement_expr(node, node.operand.accept(self)) end
visit_prefix_increment_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 149 def visit_prefix_increment_expression(node) checkpoint(node.location) eval_prefix_increment_expr(node, node.operand.accept(self)) end
visit_relational_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 265 def visit_relational_expression(node) checkpoint(node.location) eval_relational_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_shift_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 259 def visit_shift_expression(node) checkpoint(node.location) eval_shift_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_simple_assignment_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 399 def visit_simple_assignment_expression(node) checkpoint(node.location) eval_simple_assignment_expr(node, node.lhs_operand.accept(self), node.rhs_operand.accept(self)) end
visit_sizeof_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 174 def visit_sizeof_expression(node) checkpoint(node.location) ope_obj = rslt_var = nil eval_quietly_without_side_effects do rslt_type = type_of(UserTypeId.new("size_t")) || unsigned_long_t ope_obj = node.operand.accept(self) if ope_obj.variable? size = ope_obj.type.aligned_byte_size rslt_var = create_tmpvar(rslt_type, scalar_value_of(size)) else rslt_var = create_tmpvar(rslt_type) end end notify_sizeof_expr_evaled(node, ope_obj, rslt_var) rslt_var end
visit_sizeof_type_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 193 def visit_sizeof_type_expression(node) checkpoint(node.location) resolve_unresolved_type(node.operand) rslt_var = nil eval_quietly_without_side_effects do rslt_type = type_of(UserTypeId.new("size_t")) || unsigned_long_t size = node.operand.type.aligned_byte_size rslt_var = create_tmpvar(rslt_type, scalar_value_of(size)) end notify_sizeof_type_expr_evaled(node, node.operand.type, rslt_var) rslt_var end
visit_string_literal_specifier(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 72 def visit_string_literal_specifier(node) checkpoint(node.location) case node.literal.value when /\A"(.*)"\z/ rslt_var = create_tmpvar(array_type(char_t, $1.length + 1), create_array_value_of_string($1)) when /\AL"(.*)"\z/i rslt_var = create_tmpvar(array_type(wchar_t, $1.length + 1), create_array_value_of_string($1)) else rslt_var = create_tmpvar(array_type(char_t)) end notify_string_literal_specifier_evaled(node, rslt_var) rslt_var end
visit_unary_arithmetic_expression(node)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 169 def visit_unary_arithmetic_expression(node) checkpoint(node.location) eval_unary_arithmetic_expr(node, node.operand.accept(self)) end
Private Instance Methods
create_array_value_of_string(str)
click to toggle source
# File lib/adlint/cc1/expr.rb, line 437 def create_array_value_of_string(str) ArrayValue.new(str.chars.map { |ch| scalar_value_of(ch.ord) } + [scalar_value_of("\0".ord)]) end
eval_quietly_without_side_effects() { || ... }
click to toggle source
# File lib/adlint/cc1/expr.rb, line 417 def eval_quietly_without_side_effects(&block) unless orig_quiet = interpreter.quiet? interpreter._quiet = true end unless orig_without_side_effects = interpreter.without_side_effects? interpreter._without_side_effects = true end yield ensure unless orig_quiet interpreter._quiet = false # FIXME: Evaluation of an object-specifier doesn't refer to value # of a variable. Thus, no cross-reference record on a # sizeof-expression because cross-reference extraction # watches variable value reference not variable reference. # collect_object_specifiers(node).each { |os| os.accept(self) } end interpreter._without_side_effects = orig_without_side_effects end