class AdLint::Cc1::TypeTable

Attributes

all_type_names[R]
logger[R]
monitor[R]
standard_type_catalog[R]
traits[R]

Public Class Methods

new(traits, monitor, logger) click to toggle source
# File lib/adlint/cc1/type.rb, line 7319
def initialize(traits, monitor, logger)
  @traits         = traits
  @monitor        = monitor
  @logger         = logger
  @types_stack    = [{}]
  @scope_stack    = [GlobalScope.new]
  @all_type_names = Set.new

  @standard_type_catalog = StandardTypeCatalog.new(self)
  install_standard_types
end

Public Instance Methods

array_type(base_type, len = nil) click to toggle source
# File lib/adlint/cc1/type.rb, line 7349
def array_type(base_type, len = nil)
  ArrayType.new(self, base_type, len)
end
bitfield_type(base_type, field_width) click to toggle source
# File lib/adlint/cc1/type.rb, line 7361
def bitfield_type(base_type, field_width)
  BitfieldType.new(self, base_type, field_width)
end
builtin_function_type() click to toggle source
# File lib/adlint/cc1/type.rb, line 7357
def builtin_function_type
  function_type(undeclared_type, [undeclared_type])
end
enter_scope() click to toggle source
# File lib/adlint/cc1/type.rb, line 7388
def enter_scope
  @types_stack.push({})
  @scope_stack.push(Scope.new(@scope_stack.size))
end
function_type(ret_type, param_types, have_va_list = false) click to toggle source
# File lib/adlint/cc1/type.rb, line 7353
def function_type(ret_type, param_types, have_va_list = false)
  FunctionType.new(self, ret_type, param_types, have_va_list)
end
install(type) click to toggle source
# File lib/adlint/cc1/type.rb, line 7382
def install(type)
  @types_stack.last[type.id] = type
  @all_type_names.add(type.name)
  type
end
install_enum_type(type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7508
def install_enum_type(type_dcl)
  type_id = EnumTypeId.new(type_dcl.identifier.value)

  if type = lookup(type_id) and type.scope == current_scope
    if type_dcl.enumerators
      rewrite_enum_type(type, type_dcl)
      return type
    end
  end

  type = EnumType.new(self, type_dcl)
  type.scope = current_scope
  install(type)
  if type_dcl.enumerators
    rewrite_enum_type(type, type_dcl)
  end
  type
end
install_struct_type(type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7470
def install_struct_type(type_dcl)
  type_id = StructTypeId.new(type_dcl.identifier.value)

  if type = lookup(type_id) and type.scope == current_scope
    if type_dcl.struct_declarations
      rewrite_struct_type(type, type_dcl)
      return type
    end
  end

  type = StructType.new(self, type_dcl, [])
  type.scope = current_scope
  install(type)
  if type_dcl.struct_declarations
    rewrite_struct_type(type, type_dcl)
  end
  type
end
install_union_type(type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7489
def install_union_type(type_dcl)
  type_id = UnionTypeId.new(type_dcl.identifier.value)

  if type = lookup(type_id) and type.scope == current_scope
    if type_dcl.struct_declarations
      rewrite_union_type(type, type_dcl)
      return type
    end
  end

  type = UnionType.new(self, type_dcl, [])
  type.scope = current_scope
  install(type)
  if type_dcl.struct_declarations
    rewrite_union_type(type, type_dcl)
  end
  type
end
install_user_type(type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7527
def install_user_type(type_dcl)
  base_type = lookup_or_install_type(type_dcl.type_qualifiers,
                                     type_dcl.type_specifiers,
                                     type_dcl.declarator)
  type = UserType.new(self, type_dcl, base_type)
  type.scope = current_scope
  install(type)
  type
end
leave_scope() click to toggle source
# File lib/adlint/cc1/type.rb, line 7393
def leave_scope
  @types_stack.pop
  @scope_stack.pop
end
lookup(type_id) click to toggle source
# File lib/adlint/cc1/type.rb, line 7373
def lookup(type_id)
  @types_stack.reverse_each { |hash| type = hash[type_id] and return type }
  nil
end
lookup_function_type(fun_def, interp = nil) click to toggle source
# File lib/adlint/cc1/type.rb, line 7434
def lookup_function_type(fun_def, interp = nil)
  if dcl_specs = fun_def.declaration_specifiers
    type = lookup_or_install_type(dcl_specs.type_qualifiers,
                                  dcl_specs.type_specifiers,
                                  fun_def.declarator, interp)
  else
    type = lookup_or_install_type([], [], fun_def.declarator, interp)
  end

  return nil unless type

  param_types = fun_def.parameter_definitions.map { |pdef| pdef.type }
  function_type(type.return_type, param_types, type.have_va_list?)
end
lookup_or_install_type(type_quals, type_specs, dcr, interp = nil) click to toggle source
# File lib/adlint/cc1/type.rb, line 7398
def lookup_or_install_type(type_quals, type_specs, dcr, interp = nil)
  case fst_type_spec = type_specs.first
  when TypeofTypeSpecifier
    if type_name = fst_type_spec.type_name
      return type_name.type
    else
      if interp
        return interp.execute(fst_type_spec.expression, QUIET).type
      else
        return nil
      end
    end
  else
    unless base_type = lookup_type(type_specs, interp)
      case fst_type_spec
      when StructSpecifier
        base_type = install_struct_type(
          PseudoStructTypeDeclaration.new(fst_type_spec))
      when UnionSpecifier
        base_type = install_union_type(
          PseudoUnionTypeDeclaration.new(fst_type_spec))
      when EnumSpecifier
        base_type = install_enum_type(
          PseudoEnumTypeDeclaration.new(fst_type_spec))
      else
        return nil
      end
    end
    qualify_type(base_type, type_quals, dcr, interp)
  end
end
lookup_parameter_type(dcl_or_def, interp = nil) click to toggle source
# File lib/adlint/cc1/type.rb, line 7449
def lookup_parameter_type(dcl_or_def, interp = nil)
  dcr = dcl_or_def.declarator
  dcl_specs = dcl_or_def.declaration_specifiers

  if dcl_specs
    type_quals = dcl_specs.type_qualifiers
    type_specs = dcl_specs.type_specifiers
  else
    type_quals = []
    type_specs = []
  end

  if type = lookup_or_install_type(type_quals, type_specs, dcr, interp)
    type = pointer_type(type) if type.function?
  else
    return nil
  end

  ParameterType.new(self, type, dcl_or_def)
end
lookup_standard_type(name_str) click to toggle source
# File lib/adlint/cc1/type.rb, line 7378
def lookup_standard_type(name_str)
  @standard_type_catalog.lookup_by_name(name_str)
end
lookup_type(type_specs, interp = nil) click to toggle source
# File lib/adlint/cc1/type.rb, line 7430
def lookup_type(type_specs, interp = nil)
  lookup(create_type_id(type_specs, interp))
end
pointer_type(base_type) click to toggle source
# File lib/adlint/cc1/type.rb, line 7365
def pointer_type(base_type)
  PointerType.new(self, base_type)
end
qualified_type(base_type, *cvr_quals) click to toggle source
# File lib/adlint/cc1/type.rb, line 7369
def qualified_type(base_type, *cvr_quals)
  QualifiedType.new(self, base_type, *cvr_quals)
end
undeclared_type() click to toggle source
# File lib/adlint/cc1/type.rb, line 7337
def undeclared_type
  @undeclared_type ||= UndeclaredType.new(self)
end
unresolved_type() click to toggle source
# File lib/adlint/cc1/type.rb, line 7341
def unresolved_type
  @unresolved_type ||= UnresolvedType.new(self)
end
wchar_t() click to toggle source
# File lib/adlint/cc1/type.rb, line 7345
def wchar_t
  lookup(UserTypeId.new("wchar_t")) or int_t
end

Private Instance Methods

create_enum_type_id(type_specs) click to toggle source
# File lib/adlint/cc1/type.rb, line 7578
def create_enum_type_id(type_specs)
  EnumTypeId.new(type_specs.first.identifier.value)
end
create_members(struct_dcls) click to toggle source
# File lib/adlint/cc1/type.rb, line 7615
def create_members(struct_dcls)
  struct_dcls.map { |struct_dcl|
    struct_dcl.items.map do |item|
      Member.new(item.identifier ? item.identifier.value : nil, item.type)
    end
  }.flatten
end
create_standard_type_id(type_specs) click to toggle source
# File lib/adlint/cc1/type.rb, line 7558
def create_standard_type_id(type_specs)
  if type = @standard_type_catalog.lookup_by_type_specifiers(type_specs)
    type.id
  else
    int_t.id
  end
end
create_struct_type_id(type_specs) click to toggle source
# File lib/adlint/cc1/type.rb, line 7570
def create_struct_type_id(type_specs)
  StructTypeId.new(type_specs.first.identifier.value)
end
create_type_id(type_specs, interp) click to toggle source
# File lib/adlint/cc1/type.rb, line 7538
def create_type_id(type_specs, interp)
  case type_specs.first
  when StandardTypeSpecifier
    type_id = create_standard_type_id(type_specs)
  when TypedefTypeSpecifier
    type_id = create_user_type_id(type_specs)
  when StructSpecifier
    type_id = create_struct_type_id(type_specs)
  when UnionSpecifier
    type_id = create_union_type_id(type_specs)
  when EnumSpecifier
    type_id = create_enum_type_id(type_specs)
  when nil
    type_id = int_t.id
  else
    raise TypeError
  end
  type_id
end
create_union_type_id(type_specs) click to toggle source
# File lib/adlint/cc1/type.rb, line 7574
def create_union_type_id(type_specs)
  UnionTypeId.new(type_specs.first.identifier.value)
end
create_user_type_id(type_specs) click to toggle source
# File lib/adlint/cc1/type.rb, line 7566
def create_user_type_id(type_specs)
  UserTypeId.new(type_specs.first.identifier.value)
end
current_scope() click to toggle source
# File lib/adlint/cc1/type.rb, line 7629
def current_scope
  @scope_stack.last
end
install_standard_types() click to toggle source
# File lib/adlint/cc1/type.rb, line 7633
def install_standard_types
  @standard_type_catalog.all_types.each { |type| install(type) }
end
qualify_type(type, type_quals, dcr, interp = nil) click to toggle source
# File lib/adlint/cc1/type.rb, line 7582
def qualify_type(type, type_quals, dcr, interp = nil)
  cvr_quals = type_quals.map { |tok|
    case tok.type
    when :CONST then :const
    when :VOLATILE then :volatile
    else
      # TODO: Should support C99 `restrict' qualifier.
    end
  }.compact
  type = qualified_type(type, *cvr_quals) unless cvr_quals.empty?

  if dcr
    dcr_interp = DeclaratorInterpreter.new(self, interp, type)
    dcr.accept(dcr_interp)
  else
    type
  end
end
rewrite_enum_type(enum_type, type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7623
def rewrite_enum_type(enum_type, type_dcl)
  enum_type.declarations.push(type_dcl)
  enum_type.image = type_dcl.enum_specifier.to_s
  enum_type.location = type_dcl.location
end
rewrite_struct_type(struct_type, type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7601
def rewrite_struct_type(struct_type, type_dcl)
  struct_type.declarations.push(type_dcl)
  struct_type.image = type_dcl.struct_specifier.to_s
  struct_type.location = type_dcl.location
  struct_type.members.replace(create_members(type_dcl.struct_declarations))
end
rewrite_union_type(union_type, type_dcl) click to toggle source
# File lib/adlint/cc1/type.rb, line 7608
def rewrite_union_type(union_type, type_dcl)
  union_type.declarations.push(type_dcl)
  union_type.image = type_dcl.union_specifier.to_s
  union_type.location = type_dcl.location
  union_type.members.replace(create_members(type_dcl.struct_declarations))
end