Class: AdLint::Cc1::ControllingExpression

Inherits:
Object
  • Object
show all
Includes:
SyntaxNodeCollector
Defined in:
lib/adlint/cc1/ctrlexpr.rb

Overview

DESCRIPTION

Class structure

ControllingExpression
|
+-> ValueDomainManipulator
    | <-- ValueDomainNarrower
    | <-- ValueDomainWidener
    | <-- NilValueDomainNarrower
    | <-- NilValueDomainWidener
    |
    +-> ValueDomainNarrowing
          <-- ValueComparison
          <-- LogicalAnd
          <-- LogicalOr
          <-- StrictObjectDerivation
          <-- DelayedObjectDerivation

Instance Method Summary collapse

Methods included from SyntaxNodeCollector

collect_additive_expressions, collect_array_declarators, collect_compound_assignment_expressions, collect_constant_specifiers, collect_equality_expressions, collect_function_declarators, collect_generic_labeled_statements, collect_goto_statements, collect_identifier_declarators, collect_if_else_statements, collect_if_statements, collect_logical_and_expressions, collect_logical_or_expressions, collect_object_specifiers, collect_postfix_decrement_expressions, collect_postfix_increment_expressions, collect_prefix_decrement_expressions, collect_prefix_increment_expressions, collect_relational_expressions, collect_simple_assignment_expressions, collect_typedef_type_specifiers

Constructor Details

#initialize(interp, branch, target_expr = nil) ⇒ ControllingExpression

Returns a new instance of ControllingExpression.



62
63
64
65
66
67
# File 'lib/adlint/cc1/ctrlexpr.rb', line 62

def initialize(interp, branch, target_expr = nil)
  @interpreter  = interp
  @branch       = branch
  @target_expr  = target_expr
  @manipulators = []
end

Instance Method Details

#affected_variablesObject



109
110
111
# File 'lib/adlint/cc1/ctrlexpr.rb', line 109

def affected_variables
  @manipulators.map { |manip| manip.affected_variables }.flatten.uniq
end

#complexly_compounded?Boolean

Returns:

  • (Boolean)


121
122
123
124
125
# File 'lib/adlint/cc1/ctrlexpr.rb', line 121

def complexly_compounded?
  # NOTE: This method determines whether the controlling expression is too
  #       complex to thin value domains of controlling variables.
  @target_expr && !collect_logical_and_expressions(@target_expr).empty?
end

#ensure_true_by_narrowing(alt_expr = nil) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/adlint/cc1/ctrlexpr.rb', line 69

def ensure_true_by_narrowing(alt_expr = nil)
  expr = alt_expr || @target_expr

  if expr
    new_manip = ValueDomainNarrower.new(@interpreter, expr)
    if @branch.implicit_condition?
      eval_quietly { new_manip.prepare! }
    else
      new_manip.prepare!
    end
  else
    new_manip = NilValueDomainNarrower.new(@interpreter, @branch.group)
  end

  @manipulators.push(new_manip)
  new_manip
end

#ensure_true_by_widening(alt_expr = nil) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/adlint/cc1/ctrlexpr.rb', line 87

def ensure_true_by_widening(alt_expr = nil)
  expr = alt_expr || @target_expr

  if expr
    new_manip = ValueDomainWidener.new(@interpreter, expr)
    if @branch.implicit_condition?
      eval_quietly { new_manip.prepare! }
    else
      new_manip.prepare!
    end
  else
    new_manip = NilValueDomainWidener.new(@interpreter, @branch.group)
  end

  @manipulators.push(new_manip)
  new_manip
end

#restore_affected_variablesObject



117
118
119
# File 'lib/adlint/cc1/ctrlexpr.rb', line 117

def restore_affected_variables
  @manipulators.each { |manip| manip.restore! }
end

#save_affected_variablesObject



113
114
115
# File 'lib/adlint/cc1/ctrlexpr.rb', line 113

def save_affected_variables
  @manipulators.each { |manip| manip.save! }
end

#to_exprObject



127
128
129
# File 'lib/adlint/cc1/ctrlexpr.rb', line 127

def to_expr
  @target_expr
end

#undo(path_terminated) ⇒ Object



105
106
107
# File 'lib/adlint/cc1/ctrlexpr.rb', line 105

def undo(path_terminated)
  @manipulators.each { |manip| manip.rollback! } if path_terminated
end