Class: AdLint::Cc1::DeclarationInterpreter

Inherits:
SubInterpreter show all
Defined in:
lib/adlint/cc1/interp.rb

Constant Summary

Constants included from InterpreterOptions

InterpreterOptions::QUIET, InterpreterOptions::WITHOUT_SIDE_EFFECTS

Instance Attribute Summary

Attributes inherited from SubInterpreter

#target_node_class

Instance Method Summary collapse

Methods included from LogUtil

#log_debug, #log_error, #log_fatal, #log_info, #log_warn

Methods included from MonitorUtil

#checkpoint, #monitored_region

Methods included from Conversion

#do_conversion, #do_default_argument_promotion, #do_integer_promotion, #do_usual_arithmetic_conversion, #untyped_pointer_conversion?

Methods included from InterpreterMediator

#constant_expression?, #current_branch, #interpret, #object_to_pointer, #object_to_variable, #pointer_value_of, #reset_environment, #scalar_value_of, #scalar_value_of_arbitrary, #scalar_value_of_false, #scalar_value_of_null, #scalar_value_of_true, #value_of

Methods included from InterpSyntaxBridge

#_interp_syntax_bridge_

Methods included from InterpObjectBridge

#_interp_object_bridge_

Methods included from ArithmeticAccessor

#arithmetic, #logical_right_shift?

Methods included from FunctionTableMediator

#declare_explicit_function, #declare_implicit_function, #define_anonymous_function, #define_explicit_function

Methods included from VariableTableMediator

#create_tmpvar, #local_variables

Methods included from MemoryPoolMediator

#pointee_of

Methods inherited from SyntaxTreeVisitor

#visit_abbreviated_function_declarator, #visit_additive_expression, #visit_address_expression, #visit_alignof_expression, #visit_alignof_type_expression, #visit_and_expression, #visit_ansi_function_declarator, #visit_ansi_function_definition, #visit_array_abstract_declarator, #visit_array_declarator, #visit_array_subscript_expression, #visit_bit_access_by_pointer_expression, #visit_bit_access_by_value_expression, #visit_break_statement, #visit_c99_for_statement, #visit_case_labeled_statement, #visit_cast_expression, #visit_comma_separated_expression, #visit_compound_assignment_expression, #visit_compound_literal_expression, #visit_compound_statement, #visit_conditional_expression, #visit_constant_specifier, #visit_continue_statement, #visit_declaration, #visit_declaration_specifiers, #visit_default_labeled_statement, #visit_do_statement, #visit_enum_specifier, #visit_enumerator, #visit_equality_expression, #visit_error_expression, #visit_error_statement, #visit_exclusive_or_expression, #visit_expression_statement, #visit_for_statement, #visit_function_abstract_declarator, #visit_function_call_expression, #visit_generic_labeled_statement, #visit_goto_statement, #visit_grouped_abstract_declarator, #visit_grouped_declarator, #visit_grouped_expression, #visit_identifier_declarator, #visit_if_else_statement, #visit_if_statement, #visit_inclusive_or_expression, #visit_indirection_expression, #visit_init_declarator, #visit_initializer, #visit_kandr_function_declarator, #visit_kandr_function_definition, #visit_logical_and_expression, #visit_logical_or_expression, #visit_member_access_by_pointer_expression, #visit_member_access_by_value_expression, #visit_member_declaration, #visit_multiplicative_expression, #visit_null_constant_specifier, #visit_object_specifier, #visit_parameter_declaration, #visit_parameter_definition, #visit_parameter_type_list, #visit_pointer_abstract_declarator, #visit_postfix_decrement_expression, #visit_postfix_increment_expression, #visit_prefix_decrement_expression, #visit_prefix_increment_expression, #visit_relational_expression, #visit_return_statement, #visit_shift_expression, #visit_simple_assignment_expression, #visit_sizeof_expression, #visit_sizeof_type_expression, #visit_specifier_qualifier_list, #visit_standard_type_specifier, #visit_string_literal_specifier, #visit_struct_declaration, #visit_struct_declarator, #visit_struct_specifier, #visit_switch_statement, #visit_translation_unit, #visit_type_name, #visit_typedef_type_specifier, #visit_typeof_type_specifier, #visit_unary_arithmetic_expression, #visit_union_specifier, #visit_while_statement

Constructor Details

#initialize(owner) ⇒ DeclarationInterpreter

Returns a new instance of DeclarationInterpreter.



566
567
568
# File 'lib/adlint/cc1/interp.rb', line 566

def initialize(owner)
  super(owner, Declaration)
end

Instance Method Details

#visit_enum_type_declaration(node) ⇒ Object



645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/adlint/cc1/interp.rb', line 645

def visit_enum_type_declaration(node)
  checkpoint(node)

  if enums = node.enum_specifier.enumerators
    seq = 0
    enums.each do |enum|
      if expr = enum.expression
        obj = interpret(expr)
        if obj.variable? && obj.value.scalar?
          enum.value = obj.value.unique_sample
        end
      end
      enum.value ||= seq
      define_enumerator(enum)
      seq = enum.value + 1
    end
  end

  notify_enum_declared(node)
end

#visit_function_declaration(node) ⇒ Object



570
571
572
573
574
575
576
577
578
579
580
581
# File 'lib/adlint/cc1/interp.rb', line 570

def visit_function_declaration(node)
  checkpoint(node.location)

  resolve_unresolved_type(node)
  node.type.declarations.each do |dcl|
    dcl.mark_as_referred_by(node.identifier)
  end

  fun = declare_explicit_function(node)
  notify_explicit_function_declared(node, fun)
  evaluate_sequence_point(node.init_declarator.declarator)
end

#visit_struct_type_declaration(node) ⇒ Object



631
632
633
634
635
636
# File 'lib/adlint/cc1/interp.rb', line 631

def visit_struct_type_declaration(node)
  checkpoint(node.location)

  resolve_unresolved_type(node)
  notify_struct_declared(node)
end

#visit_typedef_declaration(node) ⇒ Object



666
667
668
669
670
671
672
673
674
675
676
677
678
679
# File 'lib/adlint/cc1/interp.rb', line 666

def visit_typedef_declaration(node)
  checkpoint(node.location)

  resolve_unresolved_type(node)
  node.type.real_type.declarations.each do |dcl|
    dcl.mark_as_referred_by(node.identifier)
  end

  notify_typedef_declared(node)
  evaluate_sequence_point(node.init_declarator.declarator)

  LOG_I("user-type `#{node.identifier.value}' " +
        "defined at #{node.location.to_s}.")
end

#visit_union_type_declaration(node) ⇒ Object



638
639
640
641
642
643
# File 'lib/adlint/cc1/interp.rb', line 638

def visit_union_type_declaration(node)
  checkpoint(node.location)

  resolve_unresolved_type(node)
  notify_union_declared(node)
end

#visit_variable_declaration(node) ⇒ Object



583
584
585
586
587
588
589
590
591
592
593
594
# File 'lib/adlint/cc1/interp.rb', line 583

def visit_variable_declaration(node)
  checkpoint(node.location)

  resolve_unresolved_type(node)
  node.type.declarations.each do |dcl|
    dcl.mark_as_referred_by(node.identifier)
  end

  var = declare_variable(node, current_branch)
  notify_variable_declared(node, var)
  evaluate_sequence_point(node.declarator)
end

#visit_variable_definition(node) ⇒ Object



596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
# File 'lib/adlint/cc1/interp.rb', line 596

def visit_variable_definition(node)
  checkpoint(node.location)

  resolve_unresolved_type(node)
  node.type.declarations.each do |dcl|
    dcl.mark_as_referred_by(node.identifier)
  end

  if node.initializer
    if node.type.incomplete?
      # NOTE: Unable to define variable of incomplete type such as an array
      #       without length.
      init_var, init_conved = evaluate_initializer(node)
      var = define_variable(node, current_branch,
                            init_conved.value.to_defined_value)
    else
      # NOTE: Declare variable first in order to correctly evaluate
      #       sizeof-expression that refers to the defining variable in the
      #       initializer.
      declare_variable(node, current_branch)
      init_var, init_conved = evaluate_initializer(node)
      var = define_variable(node, current_branch,
                            init_conved.value.to_defined_value)
    end

    notify_variable_value_referred(node, init_var)
    notify_variable_defined(node, var)
    notify_variable_initialized(node, var, init_var)
  else
    notify_variable_defined(node, define_variable(node, current_branch))
  end

  evaluate_sequence_point(node.init_declarator.declarator)
end