CBMC
expr.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #ifndef CPROVER_UTIL_EXPR_H
10 #define CPROVER_UTIL_EXPR_H
11 
12 #include "as_const.h"
13 #include "type.h"
14 #include "validate_expressions.h"
15 #include "validate_types.h"
16 #include "validation_mode.h"
17 
18 #include <functional>
19 
20 #define forall_operands(it, expr) \
21  for(exprt::operandst::const_iterator \
22  it = as_const(expr).operands().begin(), \
23  it##_end = as_const(expr).operands().end(); \
24  it != it##_end; \
25  ++it)
26 
27 #define Forall_operands(it, expr) \
28  if((expr).has_operands()) /* NOLINT(readability/braces) */ \
29  for(exprt::operandst::iterator it=(expr).operands().begin(); \
30  it!=(expr).operands().end(); ++it)
31 
32 #define forall_expr(it, expr) \
33  for(exprt::operandst::const_iterator it=(expr).begin(); \
34  it!=(expr).end(); ++it)
35 
36 #define Forall_expr(it, expr) \
37  for(exprt::operandst::iterator it=(expr).begin(); \
38  it!=(expr).end(); ++it)
39 
40 class depth_iteratort;
43 
55 class exprt:public irept
56 {
57 public:
58  typedef std::vector<exprt> operandst;
59 
60  // constructors
61  exprt() { }
62  explicit exprt(const irep_idt &_id):irept(_id) { }
63 
64  exprt(irep_idt _id, typet _type)
65  : irept(std::move(_id), {{ID_type, std::move(_type)}}, {})
66  {
67  }
68 
69  exprt(irep_idt _id, typet _type, operandst &&_operands)
70  : irept(
71  std::move(_id),
72  {{ID_type, std::move(_type)}},
73  std::move((irept::subt &&) _operands))
74  {
75  }
76 
78  : exprt(id, std::move(type))
79  {
80  add_source_location() = std::move(loc);
81  }
82 
84  typet &type() { return static_cast<typet &>(add(ID_type)); }
85  const typet &type() const
86  {
87  return static_cast<const typet &>(find(ID_type));
88  }
89 
91  bool has_operands() const
92  { return !operands().empty(); }
93 
95  { return (operandst &)get_sub(); }
96 
97  const operandst &operands() const
98  { return (const operandst &)get_sub(); }
99 
102  {
103  if(location.is_not_nil())
104  add_source_location() = std::move(location);
105  return *this;
106  }
107 
110  {
111  if(location.is_not_nil())
112  add_source_location() = std::move(location);
113  return std::move(*this);
114  }
115 
118  {
119  if(other.source_location().is_not_nil())
120  add_source_location() = other.source_location();
121  return *this;
122  }
123 
125  exprt &&with_source_location(const exprt &other) &&
126  {
127  if(other.source_location().is_not_nil())
128  add_source_location() = other.source_location();
129  return std::move(*this);
130  }
131 
132 protected:
134  { return operands().front(); }
135 
137  { return operands()[1]; }
138 
140  { return operands()[2]; }
141 
143  { return operands()[3]; }
144 
145  const exprt &op0() const
146  { return operands().front(); }
147 
148  const exprt &op1() const
149  { return operands()[1]; }
150 
151  const exprt &op2() const
152  { return operands()[2]; }
153 
154  const exprt &op3() const
155  { return operands()[3]; }
156 
157 public:
159  { operands().reserve(n) ; }
160 
163  void copy_to_operands(const exprt &expr)
164  {
165  operands().push_back(expr);
166  }
167 
170  void add_to_operands(const exprt &expr)
171  {
172  copy_to_operands(expr);
173  }
174 
177  void add_to_operands(exprt &&expr)
178  {
179  operands().push_back(std::move(expr));
180  }
181 
185  void add_to_operands(exprt &&e1, exprt &&e2)
186  {
187  operandst &op = operands();
188  #ifndef USE_LIST
189  op.reserve(op.size() + 2);
190  #endif
191  op.push_back(std::move(e1));
192  op.push_back(std::move(e2));
193  }
194 
199  void add_to_operands(exprt &&e1, exprt &&e2, exprt &&e3)
200  {
201  operandst &op = operands();
202  #ifndef USE_LIST
203  op.reserve(op.size() + 3);
204  #endif
205  op.push_back(std::move(e1));
206  op.push_back(std::move(e2));
207  op.push_back(std::move(e3));
208  }
209 
212  bool is_constant() const
213  {
214  return id() == ID_constant;
215  }
216 
217  bool is_true() const;
218  bool is_false() const;
219  bool is_zero() const;
220  bool is_one() const;
221 
224  bool is_boolean() const
225  {
226  return type().id() == ID_bool;
227  }
228 
229  const source_locationt &find_source_location() const;
230 
232  {
233  return static_cast<const source_locationt &>(find(ID_C_source_location));
234  }
235 
237  {
238  return static_cast<source_locationt &>(add(ID_C_source_location));
239  }
240 
242  {
243  remove(ID_C_source_location);
244  }
245 
254  static void check(const exprt &, const validation_modet)
255  {
256  }
257 
266  static void validate(
267  const exprt &expr,
268  const namespacet &,
270  {
271  check_expr(expr, vm);
272  }
273 
282  static void validate_full(
283  const exprt &expr,
284  const namespacet &ns,
286  {
287  // first check operands (if any)
288  for(const exprt &op : expr.operands())
289  {
290  validate_full_expr(op, ns, vm);
291  }
292 
293  // type may be nil
294  const typet &t = expr.type();
295 
296  validate_full_type(t, ns, vm);
297 
298  validate_expr(expr, ns, vm);
299  }
300 
301 protected:
302  exprt &add_expr(const irep_idt &name)
303  {
304  return static_cast<exprt &>(add(name));
305  }
306 
307  const exprt &find_expr(const irep_idt &name) const
308  {
309  return static_cast<const exprt &>(find(name));
310  }
311 
312 public:
316  void visit(class expr_visitort &visitor);
317  void visit(class const_expr_visitort &visitor) const;
318  void visit_pre(std::function<void(exprt &)>);
319  void visit_pre(std::function<void(const exprt &)>) const;
320 
324  void visit_post(std::function<void(exprt &)>);
325  void visit_post(std::function<void(const exprt &)>) const;
326 
333  depth_iteratort depth_begin(std::function<exprt &()> mutate_root) const;
338 };
339 
343 class expr_protectedt : public exprt
344 {
345 protected:
346  // constructors
348  : exprt(std::move(_id), std::move(_type))
349  {
350  }
351 
352  expr_protectedt(irep_idt _id, typet _type, operandst _operands)
353  : exprt(std::move(_id), std::move(_type), std::move(_operands))
354  {
355  }
356 
357  // protect these low-level methods
358  using exprt::add;
359  using exprt::op0;
360  using exprt::op1;
361  using exprt::op2;
362  using exprt::op3;
363  using exprt::remove;
364 };
365 
367 {
368 public:
369  virtual ~expr_visitort() { }
370  virtual void operator()(exprt &) { }
371 };
372 
374 {
375 public:
376  virtual ~const_expr_visitort() { }
377  virtual void operator()(const exprt &) { }
378 };
379 
380 #endif // CPROVER_UTIL_EXPR_H
void validate_expr(const shuffle_vector_exprt &value)
Definition: c_expr.h:81
virtual void operator()(const exprt &)
Definition: expr.h:377
virtual ~const_expr_visitort()
Definition: expr.h:376
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
Base class for all expressions.
Definition: expr.h:344
expr_protectedt(irep_idt _id, typet _type)
Definition: expr.h:347
expr_protectedt(irep_idt _id, typet _type, operandst _operands)
Definition: expr.h:352
virtual void operator()(exprt &)
Definition: expr.h:370
virtual ~expr_visitort()
Definition: expr.h:369
Base class for all expressions.
Definition: expr.h:56
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
Definition: expr.cpp:147
std::vector< exprt > operandst
Definition: expr.h:58
bool is_one() const
Return whether the expression is a constant representing 1.
Definition: expr.cpp:96
exprt & with_source_location(source_locationt location) &
Add the source location from location, if it is non-nil.
Definition: expr.h:101
exprt & op3()
Definition: expr.h:142
bool has_operands() const
Return true if there is at least one operand.
Definition: expr.h:91
const exprt & op3() const
Definition: expr.h:154
void add_to_operands(exprt &&e1, exprt &&e2, exprt &&e3)
Add the given arguments to the end of exprt's operands.
Definition: expr.h:199
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:27
exprt && with_source_location(const exprt &other) &&
Add the source location from other, if it has any.
Definition: expr.h:125
exprt & op1()
Definition: expr.h:136
static void validate(const exprt &expr, const namespacet &, const validation_modet vm=validation_modet::INVARIANT)
Check that the expression is well-formed, assuming that its subexpressions and type have all ready be...
Definition: expr.h:266
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
Definition: expr.h:163
exprt & add_expr(const irep_idt &name)
Definition: expr.h:302
const typet & type() const
Definition: expr.h:85
depth_iteratort depth_end()
Definition: expr.cpp:249
const_depth_iteratort depth_cend() const
Definition: expr.cpp:257
source_locationt & add_source_location()
Definition: expr.h:236
exprt()
Definition: expr.h:61
const_unique_depth_iteratort unique_depth_end() const
Definition: expr.cpp:266
bool is_boolean() const
Return whether the expression represents a Boolean.
Definition: expr.h:224
depth_iteratort depth_begin()
Definition: expr.cpp:247
const source_locationt & source_location() const
Definition: expr.h:231
const_unique_depth_iteratort unique_depth_cend() const
Definition: expr.cpp:270
exprt && with_source_location(source_locationt location) &&
Add the source location from location, if it is non-nil.
Definition: expr.h:109
void visit(class expr_visitort &visitor)
These are pre-order traversal visitors, i.e., the visitor is executed on a node before its children h...
Definition: expr.cpp:237
exprt & op2()
Definition: expr.h:139
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:34
void reserve_operands(operandst::size_type n)
Definition: expr.h:158
static void check(const exprt &, const validation_modet)
Check that the expression is well-formed (shallow checks only, i.e., subexpressions and its type are ...
Definition: expr.h:254
bool is_zero() const
Return whether the expression is a constant representing 0.
Definition: expr.cpp:47
const exprt & op2() const
Definition: expr.h:151
void visit_pre(std::function< void(exprt &)>)
Definition: expr.cpp:227
typet & type()
Return the type of the expression.
Definition: expr.h:84
static void validate_full(const exprt &expr, const namespacet &ns, const validation_modet vm=validation_modet::INVARIANT)
Check that the expression is well-formed (full check, including checks of all subexpressions and the ...
Definition: expr.h:282
exprt(irep_idt _id, typet _type)
Definition: expr.h:64
exprt(irep_idt _id, typet _type, operandst &&_operands)
Definition: expr.h:69
bool is_constant() const
Return whether the expression is a constant.
Definition: expr.h:212
exprt & op0()
Definition: expr.h:133
const exprt & op0() const
Definition: expr.h:145
exprt(const irep_idt &_id)
Definition: expr.h:62
const_depth_iteratort depth_cbegin() const
Definition: expr.cpp:255
const operandst & operands() const
Definition: expr.h:97
operandst & operands()
Definition: expr.h:94
void visit_post(std::function< void(exprt &)>)
These are post-order traversal visitors, i.e., the visitor is executed on a node after its children h...
Definition: expr.cpp:198
const exprt & find_expr(const irep_idt &name) const
Definition: expr.h:307
void add_to_operands(exprt &&e1, exprt &&e2)
Add the given arguments to the end of exprt's operands.
Definition: expr.h:185
void add_to_operands(exprt &&expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:177
exprt(const irep_idt &id, typet type, source_locationt loc)
Definition: expr.h:77
exprt & with_source_location(const exprt &other) &
Add the source location from other, if it has any.
Definition: expr.h:117
void drop_source_location()
Definition: expr.h:241
const_unique_depth_iteratort unique_depth_cbegin() const
Definition: expr.cpp:268
const exprt & op1() const
Definition: expr.h:148
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:170
const_unique_depth_iteratort unique_depth_begin() const
Definition: expr.cpp:264
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:360
subt & get_sub()
Definition: irep.h:444
const irept & find(const irep_idt &name) const
Definition: irep.cpp:93
void remove(const irep_idt &name)
Definition: irep.cpp:87
const irep_idt & id() const
Definition: irep.h:384
irept & add(const irep_idt &name)
Definition: irep.cpp:103
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
The type of an expression, extends irept.
Definition: type.h:29
Defines typet, type_with_subtypet and type_with_subtypest.
#define size_type
Definition: unistd.c:347
void check_expr(const exprt &expr, const validation_modet vm)
Check that the given expression is well-formed (shallow checks only, i.e., subexpressions and its typ...
void validate_full_expr(const exprt &expr, const namespacet &ns, const validation_modet vm)
Check that the given expression is well-formed (full check, including checks of all subexpressions an...
void validate_full_type(const typet &type, const namespacet &ns, const validation_modet vm)
Check that the given type is well-formed (full check, including checks of subtypes)
validation_modet