Class: AdLint::Cc1::TypeTable

Inherits:
Object
  • Object
show all
Includes:
InterpreterOptions, StandardTypeCatalogAccessor
Defined in:
lib/adlint/cc1/type.rb

Constant Summary

Constants included from InterpreterOptions

InterpreterOptions::QUIET, InterpreterOptions::WITHOUT_SIDE_EFFECTS

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(traits, monitor, logger) ⇒ TypeTable

Returns a new instance of TypeTable.



7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
# File 'lib/adlint/cc1/type.rb', line 7305

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

Instance Attribute Details

#all_type_namesObject (readonly)

Returns the value of attribute all_type_names.



7321
7322
7323
# File 'lib/adlint/cc1/type.rb', line 7321

def all_type_names
  @all_type_names
end

#loggerObject (readonly)

Returns the value of attribute logger.



7319
7320
7321
# File 'lib/adlint/cc1/type.rb', line 7319

def logger
  @logger
end

#monitorObject (readonly)

Returns the value of attribute monitor.



7318
7319
7320
# File 'lib/adlint/cc1/type.rb', line 7318

def monitor
  @monitor
end

#standard_type_catalogObject (readonly)

Returns the value of attribute standard_type_catalog.



7320
7321
7322
# File 'lib/adlint/cc1/type.rb', line 7320

def standard_type_catalog
  @standard_type_catalog
end

#traitsObject (readonly)

Returns the value of attribute traits.



7317
7318
7319
# File 'lib/adlint/cc1/type.rb', line 7317

def traits
  @traits
end

Instance Method Details

#array_type(base_type, len = nil) ⇒ Object



7335
7336
7337
# File 'lib/adlint/cc1/type.rb', line 7335

def array_type(base_type, len = nil)
  ArrayType.new(self, base_type, len)
end

#bitfield_type(base_type, field_width) ⇒ Object



7347
7348
7349
# File 'lib/adlint/cc1/type.rb', line 7347

def bitfield_type(base_type, field_width)
  BitfieldType.new(self, base_type, field_width)
end

#builtin_function_typeObject



7343
7344
7345
# File 'lib/adlint/cc1/type.rb', line 7343

def builtin_function_type
  function_type(undeclared_type, [undeclared_type])
end

#enter_scopeObject



7374
7375
7376
7377
# File 'lib/adlint/cc1/type.rb', line 7374

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) ⇒ Object



7339
7340
7341
# File 'lib/adlint/cc1/type.rb', line 7339

def function_type(ret_type, param_types, have_va_list = false)
  FunctionType.new(self, ret_type, param_types, have_va_list)
end

#install(type) ⇒ Object



7368
7369
7370
7371
7372
# File 'lib/adlint/cc1/type.rb', line 7368

def install(type)
  @types_stack.last[type.id] = type
  @all_type_names.add(type.name)
  type
end

#install_enum_type(type_dcl) ⇒ Object



7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
# File 'lib/adlint/cc1/type.rb', line 7494

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) ⇒ Object



7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
# File 'lib/adlint/cc1/type.rb', line 7456

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) ⇒ Object



7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
# File 'lib/adlint/cc1/type.rb', line 7475

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) ⇒ Object



7513
7514
7515
7516
7517
7518
7519
7520
7521
# File 'lib/adlint/cc1/type.rb', line 7513

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_scopeObject



7379
7380
7381
7382
# File 'lib/adlint/cc1/type.rb', line 7379

def leave_scope
  @types_stack.pop
  @scope_stack.pop
end

#lookup(type_id) ⇒ Object



7359
7360
7361
7362
# File 'lib/adlint/cc1/type.rb', line 7359

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) ⇒ Object



7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
# File 'lib/adlint/cc1/type.rb', line 7420

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) ⇒ Object



7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
# File 'lib/adlint/cc1/type.rb', line 7384

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) ⇒ Object



7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
# File 'lib/adlint/cc1/type.rb', line 7435

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) ⇒ Object



7364
7365
7366
# File 'lib/adlint/cc1/type.rb', line 7364

def lookup_standard_type(name_str)
  @standard_type_catalog.lookup_by_name(name_str)
end

#lookup_type(type_specs, interp = nil) ⇒ Object



7416
7417
7418
# File 'lib/adlint/cc1/type.rb', line 7416

def lookup_type(type_specs, interp = nil)
  lookup(create_type_id(type_specs, interp))
end

#pointer_type(base_type) ⇒ Object



7351
7352
7353
# File 'lib/adlint/cc1/type.rb', line 7351

def pointer_type(base_type)
  PointerType.new(self, base_type)
end

#qualified_type(base_type, *cvr_quals) ⇒ Object



7355
7356
7357
# File 'lib/adlint/cc1/type.rb', line 7355

def qualified_type(base_type, *cvr_quals)
  QualifiedType.new(self, base_type, *cvr_quals)
end

#undeclared_typeObject



7323
7324
7325
# File 'lib/adlint/cc1/type.rb', line 7323

def undeclared_type
  @undeclared_type ||= UndeclaredType.new(self)
end

#unresolved_typeObject



7327
7328
7329
# File 'lib/adlint/cc1/type.rb', line 7327

def unresolved_type
  @unresolved_type ||= UnresolvedType.new(self)
end

#wchar_tObject



7331
7332
7333
# File 'lib/adlint/cc1/type.rb', line 7331

def wchar_t
  lookup(UserTypeId.new("wchar_t")) or int_t
end