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.



7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
# 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

Instance Attribute Details

#all_type_namesObject (readonly)

Returns the value of attribute all_type_names.



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

def all_type_names
  @all_type_names
end

#loggerObject (readonly)

Returns the value of attribute logger.



7333
7334
7335
# File 'lib/adlint/cc1/type.rb', line 7333

def logger
  @logger
end

#monitorObject (readonly)

Returns the value of attribute monitor.



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

def monitor
  @monitor
end

#standard_type_catalogObject (readonly)

Returns the value of attribute standard_type_catalog.



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

def standard_type_catalog
  @standard_type_catalog
end

#traitsObject (readonly)

Returns the value of attribute traits.



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

def traits
  @traits
end

Instance Method Details

#array_type(base_type, len = nil) ⇒ Object



7349
7350
7351
# 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) ⇒ Object



7361
7362
7363
# 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_typeObject



7357
7358
7359
# File 'lib/adlint/cc1/type.rb', line 7357

def builtin_function_type
  function_type(undeclared_type, [undeclared_type])
end

#enter_scopeObject



7388
7389
7390
7391
# 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) ⇒ Object



7353
7354
7355
# 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) ⇒ Object



7382
7383
7384
7385
7386
# 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) ⇒ Object



7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
# 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) ⇒ Object



7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
# 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) ⇒ Object



7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
# 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) ⇒ Object



7527
7528
7529
7530
7531
7532
7533
7534
7535
# 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_scopeObject



7393
7394
7395
7396
# File 'lib/adlint/cc1/type.rb', line 7393

def leave_scope
  @types_stack.pop
  @scope_stack.pop
end

#lookup(type_id) ⇒ Object



7373
7374
7375
7376
# 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) ⇒ Object



7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
# 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) ⇒ Object



7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
# 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) ⇒ Object



7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
# 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) ⇒ Object



7378
7379
7380
# 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) ⇒ Object



7430
7431
7432
# 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) ⇒ Object



7365
7366
7367
# 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) ⇒ Object



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

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

#undeclared_typeObject



7337
7338
7339
# File 'lib/adlint/cc1/type.rb', line 7337

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

#unresolved_typeObject



7341
7342
7343
# File 'lib/adlint/cc1/type.rb', line 7341

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

#wchar_tObject



7345
7346
7347
# File 'lib/adlint/cc1/type.rb', line 7345

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