class AdLint::Exam::CBuiltin::W0787

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 19339
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] = [] }]

  @obj_dcls_in_other_scope     = Hash.new { |hash, key| hash[key] = [] }
  @typedef_dcls_in_other_scope = Hash.new { |hash, key| hash[key] = [] }
  @enum_names_in_other_scope   = 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 19398
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 19402
def check_enumerator(enum)
  name = enum.identifier.value

  pairs = @obj_dcls_in_other_scope[name] +
          @typedef_dcls_in_other_scope[name] +
          @enum_names_in_other_scope[name]

  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, obj) click to toggle source
# File lib/adlint/exam/c_builtin/cc1_check.rb, line 19361
def check_object_dcl(obj_dcl, obj)
  return unless obj.declared_as_extern?

  name = obj_dcl.identifier.value
  type = obj_dcl.type

  pairs =
    @obj_dcls_in_other_scope[name].select { |dcl| dcl.type != type } +
    @typedef_dcls_in_other_scope[name] + @enum_names_in_other_scope[name]

  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 19380
def check_typedef_dcl(typedef_dcl)
  name = typedef_dcl.identifier.value
  type = typedef_dcl.type

  pairs = @obj_dcls_in_other_scope[name] +
          @typedef_dcls_in_other_scope[name].select { |dcl|
            dcl.type != type
          } + @enum_names_in_other_scope[name]

  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 19418
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 19424
def leave_scope(*)
  @obj_dcls.last.each do |name, dcls|
    @obj_dcls_in_other_scope[name].concat(dcls)
  end
  @obj_dcls.pop

  @typedef_dcls.last.each do |name, dcls|
    @typedef_dcls_in_other_scope[name].concat(dcls)
  end
  @typedef_dcls.pop

  @enum_names.last.each do |name, enums|
    @enum_names_in_other_scope[name].concat(enums)
  end
  @enum_names.pop
end