class AdLint::Cc1::VariableTable
Public Class Methods
new(mem_pool)
click to toggle source
# File lib/adlint/cc1/object.rb, line 671 def initialize(mem_pool) @memory_pool = mem_pool @named_variables = [{}] @temp_variables = [[]] @scope_stack = [GlobalScope.new] end
Public Instance Methods
all_named_variables()
click to toggle source
# File lib/adlint/cc1/object.rb, line 678 def all_named_variables @named_variables.map { |hash| hash.values }.flatten end
begin_variables_value_versioning()
click to toggle source
# File lib/adlint/cc1/object.rb, line 773 def begin_variables_value_versioning @named_variables.each do |hash| hash.each_value { |var| var.begin_value_versioning } end end
declare(dcl, br)
click to toggle source
# File lib/adlint/cc1/object.rb, line 700 def declare(dcl, br) if var = lookup(dcl.identifier.value) var.declarations_and_definitions.push(dcl) return var end # NOTE: External variable may have undefined values. define_variable(dcl, br, dcl.type, allocate_memory(dcl), dcl.type.undefined_value) end
define(dcl_or_def, br, init_val = nil)
click to toggle source
# File lib/adlint/cc1/object.rb, line 711 def define(dcl_or_def, br, init_val = nil) if storage_duration_of(dcl_or_def) == :static && !dcl_or_def.type.const? # NOTE: Value of the inconstant static duration variable should be # arbitrary because execution of its accessors are out of order. # So, a value of the initializer should be ignored. init_val = dcl_or_def.type.arbitrary_value else init_val ||= dcl_or_def.type.undefined_value end if var = lookup(dcl_or_def.identifier.value) if var.scope == current_scope var.declarations_and_definitions.push(dcl_or_def) var.value.force_overwrite!(init_val.coerce_to(var.type)) if repr_elem = var.representative_element repr_elem.value.force_overwrite!(repr_elem.type.arbitrary_value) end return var end end # NOTE: Domain of the init-value will be restricted by type's min-max in # define_variable. define_variable(dcl_or_def, br, dcl_or_def.type, allocate_memory(dcl_or_def), init_val) end
define_temporary(type, init_val)
click to toggle source
# File lib/adlint/cc1/object.rb, line 738 def define_temporary(type, init_val) mem = @memory_pool.allocate_dynamic(type.aligned_byte_size) # NOTE: Domain of the init-value will be restricted by type's min-max in # define_variable. define_variable(nil, nil, type, mem, init_val) end
designators()
click to toggle source
# File lib/adlint/cc1/object.rb, line 755 def designators @named_variables.map { |hash| hash.keys }.flatten.to_set end
end_variables_value_versioning()
click to toggle source
# File lib/adlint/cc1/object.rb, line 779 def end_variables_value_versioning @named_variables.each do |hash| hash.each_value { |var| var.end_value_versioning } end end
enter_scope()
click to toggle source
# File lib/adlint/cc1/object.rb, line 682 def enter_scope @named_variables.push({}) @temp_variables.push([]) @scope_stack.push(Scope.new(@scope_stack.size)) end
enter_variables_value_versioning_group()
click to toggle source
# File lib/adlint/cc1/object.rb, line 759 def enter_variables_value_versioning_group @named_variables.each do |hash| hash.each_value { |var| var.enter_value_versioning_group } end end
leave_scope()
click to toggle source
# File lib/adlint/cc1/object.rb, line 688 def leave_scope @named_variables.pop.each_value do |var| @memory_pool.free(var.binding.memory) end @temp_variables.pop.each do |var| @memory_pool.free(var.binding.memory) end @scope_stack.pop rollback_all_global_variables_value! if current_scope.global? end
leave_variables_value_versioning_group(raise_complement)
click to toggle source
# File lib/adlint/cc1/object.rb, line 765 def leave_variables_value_versioning_group(raise_complement) @named_variables.each do |hash| hash.each_value do |var| var.leave_value_versioning_group(raise_complement) end end end
lookup(name_str)
click to toggle source
# File lib/adlint/cc1/object.rb, line 746 def lookup(name_str) @named_variables.reverse_each do |hash| if var = hash[name_str] return var end end nil end
storage_duration_of(dcl_or_def)
click to toggle source
# File lib/adlint/cc1/object.rb, line 791 def storage_duration_of(dcl_or_def) # NOTE: The ISO C99 standard says; # # 6.2.2 Linkages of identifiers # # 1 An identifier declared in different scopes or in the same scope more # than once can be made to refer to the same object or function by a # process called linkage. There are three kinds of linkage: external, # internal, and none. # # 3 If the declaration of a file scope identifier for an object or a # function contains the storage-class specifier static, the identifier # has internal linkage. # # 4 For an identifier declared with the storage-class specifier extern in # a scope in which a prior declaration of that identifier is visible, # if the prior declaration specifies internal or external linkage, the # linkage of the identifier at the later declaration is the same as the # linkage specified at the prior declaration. If no prior declaration # is visible, or if the prior declaration specifies no linkage, then # the identifier has external linkage. # # 5 If the declaration of an identifier for a function has no # storage-class specifier, its linkage is determined exactly as if it # were declared with the storage-class specifier extern. If the # declaration of an identifier for an object has file scope and no # storage-class specifier, its linkage is external. # # 6 The following identifiers have no linkage: an identifier declared to # be anything other than an object or a function; an identifier # declared to be a function parameter; a block scope identifier for an # object declared without the storage-class specifier extern. # # 6.2.4 Storage durations of objects # # 1 An object has a storage duration that determines its lifetime. There # are three storage durations: static, automatic, and allocated. # Allocated storage is described in 7.20.3. # # 3 An object whose identifier is declared with external or internal # linkage, or with the storage-class specifier static has static # storage duration. Its lifetime is the entire execution of the program # and its stored value is initialized only once, prior to program # startup. # # 4 An object whose identifier is declared with no linkage and without # the storage-class specifier static has automatic storage duration. if sc_spec = dcl_or_def.storage_class_specifier and sc_spec.type == :EXTERN || sc_spec.type == :STATIC :static else current_scope.global? ? :static : :automatic end end
thin_latest_variables_value_version!(with_rollback)
click to toggle source
# File lib/adlint/cc1/object.rb, line 785 def thin_latest_variables_value_version!(with_rollback) @named_variables.each do |hash| hash.each_value { |var| var.thin_latest_value_version!(with_rollback) } end end
Private Instance Methods
allocate_memory(dcl_or_def)
click to toggle source
# File lib/adlint/cc1/object.rb, line 861 def allocate_memory(dcl_or_def) byte_size = dcl_or_def.type.aligned_byte_size if storage_duration_of(dcl_or_def) == :static @memory_pool.allocate_static(byte_size) else @memory_pool.allocate_dynamic(byte_size) end end
create_variable(dcl_or_def, type, mem)
click to toggle source
# File lib/adlint/cc1/object.rb, line 870 def create_variable(dcl_or_def, type, mem) if dcl_or_def NamedVariable.new(mem, dcl_or_def, current_scope) else TemporaryVariable.new(mem, type, current_scope) end end
current_scope()
click to toggle source
# File lib/adlint/cc1/object.rb, line 878 def current_scope @scope_stack.last end
define_variable(dcl_or_def, br, type, mem, init_val)
click to toggle source
# File lib/adlint/cc1/object.rb, line 848 def define_variable(dcl_or_def, br, type, mem, init_val) var = create_variable(dcl_or_def, type, mem) var.assign!(init_val, dcl_or_def, br) if var.named? @named_variables.last[var.name] = var else @temp_variables.last.push(var) end var end
rollback_all_global_variables_value!()
click to toggle source
# File lib/adlint/cc1/object.rb, line 882 def rollback_all_global_variables_value! @named_variables.first.each_value do |var| # NOTE: Rollback effects recorded to global variables because execution # of its accessors are out of order. var.rollback_all_value_versions! end end