class AdLint::Cc1::InitializerInterpreter
Public Class Methods
new(interp)
click to toggle source
# File lib/adlint/cc1/interp.rb, line 724 def initialize(interp) @interpreter = interp end
Public Instance Methods
execute(var_def)
click to toggle source
# File lib/adlint/cc1/interp.rb, line 728 def execute(var_def) checkpoint(var_def.initializer.location) case when expr = var_def.initializer.expression # NOTE: An implicit conversion is already notified in # #evaluate_expression. return evaluate_expression(expr, var_def.type) when inits = var_def.initializer.initializers var = evaluate_initializers(inits, var_def.type) # NOTE: Size deduction of an incomplete array type have been done by # #evaluate_initializers. if var_def.type.array? && var.type.array? var_def.type = var.type unless var_def.type.length end if var.type.same_as?(var_def.type) conved = var else conved = do_conversion(var, var_def.type) || create_tmpvar(var_def.type) notify_implicit_conv_performed(inits, var, conved) end else var = conved = create_tmpvar(var_def.type) end return var, conved end
Private Instance Methods
deduct_array_length_from_initializers(orig_ary_type, inits)
click to toggle source
# File lib/adlint/cc1/interp.rb, line 855 def deduct_array_length_from_initializers(orig_ary_type, inits) unless orig_ary_type.length if orig_ary_type.user? orig_ary_type = orig_ary_type.dup end orig_ary_type.length = inits.size end orig_ary_type end
evaluate_expression(expr, type)
click to toggle source
# File lib/adlint/cc1/interp.rb, line 760 def evaluate_expression(expr, type) checkpoint(expr.location) var = object_to_variable(interpret(expr), expr) if var.type.same_as?(type) conved = var else conved = do_conversion(var, type) || create_tmpvar(type) notify_implicit_conv_performed(expr, var, conved) end return var, conved end
evaluate_initializers(inits, type)
click to toggle source
# File lib/adlint/cc1/interp.rb, line 775 def evaluate_initializers(inits, type) case when type.union? # NOTE: The ISO C99 standard says; # # 6.7.8 Initialization # # Semantics # # 10 If an object that has automatic storage duration is not # initialized explicitly, its value is indeterminate. If an object # that has static storage duration is not initialized explicitly, # then: # -- if it has pointer type, it is initialized to a null pointer; # -- if it has arithmetic type, it is initialized to (positive or # unsigned) zero; # -- if it is an aggregate, every member is initialized # (recursively) according to these rules; # -- if it is a union, the first named member is initialized # (recursively) according to these rules. if fst_memb = type.members.first fst_obj = evaluate_initializers(inits, fst_memb.type) return create_tmpvar(type, value_of(fst_obj)) else return create_tmpvar(type) end when type.array? # NOTE: The ISO C99 standard says; # # 6.7.2.1 Structure and union specifiers # # Constraints # # 2 A structure or union shall not contain a member with incomplete # or function type (hence, a structure shall not contain an # instance of itself, but may contain a pointer to an instance of # itself), except that the last member of a structure with more # than one named member may have incomplete array type; such a # structure (and any union containing, possibly recursively, a # member that is such a structure) shall not be a member of a # structure or an element of an array. # # NOTE: Size of the last incomplete array member should not be # deducted in initialization. It is treated as a pointer. # # NOTE: ISO C90 does not support flexible array members. type = deduct_array_length_from_initializers(type, inits) memb_types = [type.unqualify.base_type] * type.impl_length when type.struct? memb_types = type.members.map { |memb| memb.type } else memb_types = [type] end vals = memb_types.zip(inits).map { |memb_type, init| if init checkpoint(init.location) case when expr = init.expression value_of(evaluate_expression(expr, memb_type).last) when inits = init.initializers value_of(evaluate_initializers(inits, memb_type)) else memb_type.undefined_value end else memb_type.undefined_value end } case when type.array? create_tmpvar(type, ArrayValue.new(vals)) when type.composite? create_tmpvar(type, CompositeValue.new(vals)) else create_tmpvar(type, vals.first) end end
interpreter()
click to toggle source
# File lib/adlint/cc1/interp.rb, line 865 def interpreter # NOTE: This is private attr_reader for InterpreterMediator. # This attribute is read via a normal method to suppress # `private attribute?' warning. @interpreter end