class AdLint::Exam::CBuiltin::W0789

Public Class Methods

new(phase_ctxt) click to toggle source
Calls superclass method AdLint::Examination::new
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19539
def initialize(phase_ctxt)
  super
  interp = phase_ctxt[:cc1_interpreter]
  interp.on_variable_declared          += T(:check_object_dcl)
  interp.on_variable_defined           += T(:check_object_dcl)
  interp.on_explicit_function_declared += T(:check_object_dcl)
  interp.on_explicit_function_defined  += T(:check_object_dcl)
  interp.on_typedef_declared           += T(:check_typedef_dcl)
  interp.on_enum_declared              += T(:check_enum_dcl)
  interp.on_block_started              += T(:enter_scope)
  interp.on_block_ended                += T(:leave_scope)

  @obj_dcls     = [Hash.new { |hash, key| hash[key] = [] }]
  @typedef_dcls = [Hash.new { |hash, key| hash[key] = [] }]
  @enum_names   = [Hash.new { |hash, key| hash[key] = [] }]
end

Private Instance Methods

check_enum_dcl(enum_dcl) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19593
def check_enum_dcl(enum_dcl)
  enum_dcl.enumerators.each { |enum| check_enumerator(enum) }
end
check_enumerator(enum) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19597
def check_enumerator(enum)
  name = enum.identifier.value

  pairs = merge_upper_scopes(name, @obj_dcls) +
          merge_upper_scopes(name, @typedef_dcls) +
          merge_upper_scopes(name, @enum_names)

  unless pairs.empty?
    W(enum.location, name, *pairs.map { |pair|
      C(:C0001, pair.location, pair.identifier.value)
    })
  end

  @enum_names.last[name].push(enum)
end
check_object_dcl(obj_dcl, *) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19557
def check_object_dcl(obj_dcl, *)
  name = obj_dcl.identifier.value
  type = obj_dcl.type

  pairs =
    merge_upper_scopes(name, @obj_dcls).select { |dcl| dcl.type != type } +
    merge_upper_scopes(name, @typedef_dcls) +
    merge_upper_scopes(name, @enum_names)

  unless pairs.empty?
    W(obj_dcl.location, name, *pairs.map { |pair|
      C(:C0001, pair.location, pair.identifier.value)
    })
  end

  @obj_dcls.last[name].push(obj_dcl)
end
check_typedef_dcl(typedef_dcl) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19575
def check_typedef_dcl(typedef_dcl)
  name = typedef_dcl.identifier.value
  type = typedef_dcl.type

  pairs = merge_upper_scopes(name, @obj_dcls) +
          merge_upper_scopes(name, @typedef_dcls).select { |dcl|
            dcl.type != type
          } + merge_upper_scopes(name, @enum_names)

  unless pairs.empty?
    W(typedef_dcl.location, name, *pairs.map { |pair|
      C(:C0001, pair.location, pair.identifier.value)
    })
  end

  @typedef_dcls.last[name].push(typedef_dcl)
end
enter_scope(*) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19613
def enter_scope(*)
  @obj_dcls.push(Hash.new { |hash, key| hash[key] = [] })
  @typedef_dcls.push(Hash.new { |hash, key| hash[key] = [] })
  @enum_names.push(Hash.new { |hash, key| hash[key] = [] })
end
leave_scope(*) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19619
def leave_scope(*)
  @obj_dcls.pop
  @typedef_dcls.pop
  @enum_names.pop
end
merge_upper_scopes(name, scoped_hash) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19625
def merge_upper_scopes(name, scoped_hash)
  scoped_hash[0..-2].reduce([]) { |scopes, hash| scopes + hash[name] }
end