CBMC
xml_expr.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Expressions in XML
4 
5 Author: Daniel Kroening
6 
7  Date: November 2005
8 
9 \*******************************************************************/
10 
13 
14 #include "xml_expr.h"
15 
16 #include <util/arith_tools.h>
17 #include <util/c_types.h>
18 #include <util/config.h>
19 #include <util/fixedbv.h>
20 #include <util/ieee_float.h>
21 #include <util/invariant.h>
22 #include <util/namespace.h>
23 #include <util/pointer_expr.h>
24 #include <util/xml.h>
25 
26 xmlt xml(const typet &type, const namespacet &ns)
27 {
28  xmlt result;
29 
30  if(type.id() == ID_unsignedbv)
31  {
32  result.name = "integer";
33  result.set_attribute("width", to_unsignedbv_type(type).get_width());
34  }
35  else if(type.id() == ID_signedbv)
36  {
37  result.name = "integer";
38  result.set_attribute("width", to_signedbv_type(type).get_width());
39  }
40  else if(type.id() == ID_floatbv)
41  {
42  result.name = "float";
43  result.set_attribute("width", to_floatbv_type(type).get_width());
44  }
45  else if(type.id() == ID_bv)
46  {
47  result.name = "integer";
48  result.set_attribute("width", to_bv_type(type).get_width());
49  }
50  else if(type.id() == ID_c_bit_field)
51  {
52  result.name = "integer";
53  result.set_attribute("width", to_c_bit_field_type(type).get_width());
54  }
55  else if(type.id() == ID_c_enum_tag)
56  {
57  // we return the underlying type
58  return xml(ns.follow_tag(to_c_enum_tag_type(type)).underlying_type(), ns);
59  }
60  else if(type.id() == ID_fixedbv)
61  {
62  result.name = "fixed";
63  result.set_attribute("width", to_fixedbv_type(type).get_width());
64  }
65  else if(type.id() == ID_pointer)
66  {
67  result.name = "pointer";
68  result.new_element("subtype").new_element() =
69  xml(to_pointer_type(type).base_type(), ns);
70  }
71  else if(type.id() == ID_bool)
72  {
73  result.name = "boolean";
74  }
75  else if(type.id() == ID_array)
76  {
77  result.name = "array";
78  result.new_element("subtype").new_element() =
79  xml(to_array_type(type).element_type(), ns);
80  result.new_element("size").new_element() =
81  xml(to_array_type(type).size(), ns);
82  }
83  else if(type.id() == ID_vector)
84  {
85  result.name = "vector";
86  result.new_element("subtype").new_element() =
87  xml(to_vector_type(type).element_type(), ns);
88  result.new_element("size").new_element() =
89  xml(to_vector_type(type).size(), ns);
90  }
91  else if(type.id() == ID_struct)
92  {
93  result.name = "struct";
94  const struct_typet::componentst &components =
95  to_struct_type(type).components();
96  for(const auto &component : components)
97  {
98  xmlt &e = result.new_element("member");
99  e.set_attribute("name", id2string(component.get_name()));
100  e.new_element("type").new_element() = xml(component.type(), ns);
101  }
102  }
103  else if(type.id() == ID_struct_tag)
104  {
105  return xml(ns.follow_tag(to_struct_tag_type(type)), ns);
106  }
107  else if(type.id() == ID_union)
108  {
109  result.name = "union";
110  const union_typet::componentst &components =
111  to_union_type(type).components();
112  for(const auto &component : components)
113  {
114  xmlt &e = result.new_element("member");
115  e.set_attribute("name", id2string(component.get_name()));
116  e.new_element("type").new_element() = xml(component.type(), ns);
117  }
118  }
119  else if(type.id() == ID_union_tag)
120  {
121  return xml(ns.follow_tag(to_union_tag_type(type)), ns);
122  }
123  else
124  result.name = "unknown";
125 
126  return result;
127 }
128 
129 xmlt xml(const exprt &expr, const namespacet &ns)
130 {
131  xmlt result;
132 
133  if(expr.is_constant())
134  {
135  const auto &constant_expr = to_constant_expr(expr);
136  const auto &value = constant_expr.get_value();
137 
138  const typet &type = expr.type();
139 
140  if(
141  type.id() == ID_unsignedbv || type.id() == ID_signedbv ||
142  type.id() == ID_c_bit_field || type.id() == ID_c_bool)
143  {
144  mp_integer i = numeric_cast_v<mp_integer>(constant_expr);
145  std::size_t width = to_bitvector_type(type).get_width();
146 
147  result.name = "integer";
148  result.set_attribute("binary", integer2binary(i, width));
149  result.set_attribute("width", width);
150 
151  const typet &underlying_type =
152  type.id() == ID_c_bit_field
154  : type;
155 
156  bool is_signed = underlying_type.id() == ID_signedbv;
157 
158  std::string sig = is_signed ? "" : "unsigned ";
159 
160  if(type.id() == ID_c_bool)
161  result.set_attribute("c_type", "_Bool");
162  else if(width == config.ansi_c.char_width)
163  result.set_attribute("c_type", sig + "char");
164  else if(width == config.ansi_c.int_width)
165  result.set_attribute("c_type", sig + "int");
166  else if(width == config.ansi_c.short_int_width)
167  result.set_attribute("c_type", sig + "short int");
168  else if(width == config.ansi_c.long_int_width)
169  result.set_attribute("c_type", sig + "long int");
170  else if(width == config.ansi_c.long_long_int_width)
171  result.set_attribute("c_type", sig + "long long int");
172 
173  result.data = integer2string(i);
174  }
175  else if(type.id() == ID_c_enum)
176  {
177  const auto width =
178  to_bitvector_type(to_c_enum_type(type).underlying_type()).get_width();
179 
180  const auto integer_value = bvrep2integer(value, width, false);
181  result.name = "integer";
182  result.set_attribute("binary", integer2binary(integer_value, width));
183  result.set_attribute("width", width);
184  result.set_attribute("c_type", "enum");
185 
186  result.data = integer2string(integer_value);
187  }
188  else if(type.id() == ID_c_enum_tag)
189  {
190  constant_exprt tmp(
191  constant_expr.get_value(), ns.follow_tag(to_c_enum_tag_type(type)));
192  return xml(tmp, ns);
193  }
194  else if(type.id() == ID_bv)
195  {
196  result.name = "bitvector";
197  result.set_attribute("binary", constant_expr.get_string(ID_value));
198  }
199  else if(type.id() == ID_fixedbv)
200  {
201  const auto width = to_fixedbv_type(type).get_width();
202  result.name = "fixed";
203  result.set_attribute("width", width);
204  result.set_attribute(
205  "binary", integer2binary(bvrep2integer(value, width, false), width));
206  result.data = fixedbvt(constant_expr).to_ansi_c_string();
207  }
208  else if(type.id() == ID_floatbv)
209  {
210  const auto width = to_floatbv_type(type).get_width();
211  result.name = "float";
212  result.set_attribute("width", width);
213  result.set_attribute(
214  "binary", integer2binary(bvrep2integer(value, width, false), width));
215  result.data = ieee_floatt(constant_expr).to_ansi_c_string();
216  }
217  else if(type.id() == ID_pointer)
218  {
219  const auto width = to_pointer_type(type).get_width();
220  result.name = "pointer";
221  result.set_attribute(
222  "binary", integer2binary(bvrep2integer(value, width, false), width));
223  if(constant_expr.is_null_pointer())
224  result.data = "NULL";
225  }
226  else if(type.id() == ID_bool)
227  {
228  result.name = "boolean";
229  result.set_attribute("binary", constant_expr.is_true() ? "1" : "0");
230  result.data = constant_expr.is_true() ? "TRUE" : "FALSE";
231  }
232  else
233  {
234  result.name = "unknown";
235  }
236  }
237  else if(expr.id() == ID_array)
238  {
239  result.name = "array";
240 
241  unsigned index = 0;
242 
243  for(const auto &op : expr.operands())
244  {
245  xmlt &e = result.new_element("element");
246  e.set_attribute("index", index);
247  e.new_element(xml(op, ns));
248  index++;
249  }
250  }
251  else if(expr.id() == ID_struct)
252  {
253  result.name = "struct";
254 
255  const struct_typet &struct_type =
256  expr.type().id() == ID_struct_tag
257  ? ns.follow_tag(to_struct_tag_type(expr.type()))
258  : to_struct_type(expr.type());
259  const struct_typet::componentst &components = struct_type.components();
260  PRECONDITION(components.size() == expr.operands().size());
261 
262  for(unsigned m = 0; m < expr.operands().size(); m++)
263  {
264  xmlt &e = result.new_element("member");
265  e.new_element() = xml(expr.operands()[m], ns);
266  e.set_attribute("name", id2string(components[m].get_name()));
267  }
268  }
269  else if(expr.id() == ID_union)
270  {
271  const union_exprt &union_expr = to_union_expr(expr);
272  result.name = "union";
273 
274  xmlt &e = result.new_element("member");
275  e.new_element(xml(union_expr.op(), ns));
276  e.set_attribute("member_name", id2string(union_expr.get_component_name()));
277  }
278  else
279  result.name = "unknown";
280 
281  return result;
282 }
configt config
Definition: config.cpp:25
mp_integer bvrep2integer(const irep_idt &src, std::size_t width, bool is_signed)
convert a bit-vector representation (possibly signed) to integer
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const bv_typet & to_bv_type(const typet &type)
Cast a typet to a bv_typet.
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Definition: c_types.h:335
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Definition: c_types.h:224
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Definition: c_types.h:80
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:184
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
Definition: c_types.h:377
std::size_t get_width() const
Definition: std_types.h:925
const typet & underlying_type() const
Definition: c_types.h:30
struct configt::ansi_ct ansi_c
A constant literal expression.
Definition: std_expr.h:3000
Base class for all expressions.
Definition: expr.h:56
typet & type()
Return the type of the expression.
Definition: expr.h:84
bool is_constant() const
Return whether the expression is a constant.
Definition: expr.h:212
operandst & operands()
Definition: expr.h:94
std::string to_ansi_c_string() const
Definition: fixedbv.h:62
std::string to_ansi_c_string() const
Definition: ieee_float.h:280
const irep_idt & id() const
Definition: irep.h:388
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
Structure type, corresponds to C style structs.
Definition: std_types.h:231
const componentst & components() const
Definition: std_types.h:147
std::vector< componentt > componentst
Definition: std_types.h:140
The type of an expression, extends irept.
Definition: type.h:29
const exprt & op() const
Definition: std_expr.h:391
Union constructor from single element.
Definition: std_expr.h:1770
irep_idt get_component_name() const
Definition: std_expr.h:1778
Definition: xml.h:21
void set_attribute(const std::string &attribute, unsigned value)
Definition: xml.cpp:198
xmlt & new_element(const std::string &key)
Definition: xml.h:95
std::string data
Definition: xml.h:39
std::string name
Definition: xml.h:39
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
const std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103
const std::string integer2binary(const mp_integer &n, std::size_t width)
Definition: mp_arith.cpp:64
API to expression classes for Pointers.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:93
BigInt mp_integer
Definition: smt_terms.h:17
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:97
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:3055
const union_exprt & to_union_expr(const exprt &expr)
Cast an exprt to a union_exprt.
Definition: std_expr.h:1816
const vector_typet & to_vector_type(const typet &type)
Cast a typet to a vector_typet.
Definition: std_types.h:1113
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:888
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition: std_types.h:518
std::size_t long_long_int_width
Definition: config.h:142
std::size_t long_int_width
Definition: config.h:138
std::size_t short_int_width
Definition: config.h:141
std::size_t char_width
Definition: config.h:140
std::size_t int_width
Definition: config.h:137
bool is_signed(const typet &t)
Convenience function – is the type signed?
Definition: util.cpp:45
xmlt xml(const typet &type, const namespacet &ns)
Definition: xml_expr.cpp:26