CBMC
class_identifier.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Extract class identifier
4 
5 Author: Chris Smowton, chris.smowton@diffblue.com
6 
7 \*******************************************************************/
8 
11 
12 #include "class_identifier.h"
13 
14 #include <util/c_types.h>
15 #include <util/namespace.h>
16 #include <util/pointer_expr.h>
17 #include <util/std_expr.h>
18 
23  const exprt &src,
24  const namespacet &ns)
25 {
26  // the class identifier is in the root class
27  exprt e=src;
28 
29  while(1)
30  {
31  const typet &type=ns.follow(e.type());
32  const struct_typet &struct_type=to_struct_type(type);
33  const struct_typet::componentst &components=struct_type.components();
34  INVARIANT(!components.empty(), "class structs cannot be empty");
35 
36  const auto &first_member_name=components.front().get_name();
37  member_exprt member_expr(
38  e,
39  first_member_name,
40  components.front().type());
41 
42  if(first_member_name == JAVA_CLASS_IDENTIFIER_FIELD_NAME)
43  {
44  // found it
45  return std::move(member_expr);
46  }
47  else
48  {
49  e.swap(member_expr);
50  }
51  }
52 }
53 
58  const exprt &this_expr_in,
59  const struct_tag_typet &suggested_type,
60  const namespacet &ns)
61 {
62  // Get a pointer from which we can extract a clsid.
63  // If it's already a pointer to an object of some sort, just use it;
64  // if it's void* then use the suggested type.
65  PRECONDITION(this_expr_in.type().id() == ID_pointer);
66 
67  exprt this_expr=this_expr_in;
68  const auto &points_to = to_pointer_type(this_expr.type()).base_type();
69  if(points_to==empty_typet())
70  this_expr=typecast_exprt(this_expr, pointer_type(suggested_type));
71  const dereference_exprt deref{this_expr};
72  return build_class_identifier(deref, ns);
73 }
74 
84  struct_exprt &expr,
85  const namespacet &ns,
86  const struct_tag_typet &class_type)
87 {
88  const struct_typet &struct_type=to_struct_type(ns.follow(expr.type()));
89  const struct_typet::componentst &components=struct_type.components();
90 
91  if(components.empty())
92  // Presumably this means the type has not yet been determined
93  return;
94  PRECONDITION(!expr.operands().empty());
95 
96  if(components.front().get_name() == JAVA_CLASS_IDENTIFIER_FIELD_NAME)
97  {
98  INVARIANT(
99  expr.op0().id()==ID_constant, "@class_identifier must be a constant");
100  expr.op0()=constant_exprt(class_type.get_identifier(), string_typet());
101  }
102  else
103  {
104  // The first member must be the base class
105  INVARIANT(
106  expr.op0().id()==ID_struct, "Non @class_identifier must be a structure");
107  set_class_identifier(to_struct_expr(expr.op0()), ns, class_type);
108  }
109 }
tag_typet::get_identifier
const irep_idt & get_identifier() const
Definition: std_types.h:410
struct_union_typet::components
const componentst & components() const
Definition: std_types.h:147
JAVA_CLASS_IDENTIFIER_FIELD_NAME
#define JAVA_CLASS_IDENTIFIER_FIELD_NAME
Definition: class_identifier.h:20
to_struct_type
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
typet
The type of an expression, extends irept.
Definition: type.h:28
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
get_class_identifier_field
exprt get_class_identifier_field(const exprt &this_expr_in, const struct_tag_typet &suggested_type, const namespacet &ns)
Definition: class_identifier.cpp:57
exprt
Base class for all expressions.
Definition: expr.h:55
struct_union_typet::componentst
std::vector< componentt > componentst
Definition: std_types.h:140
struct_tag_typet
A struct tag type, i.e., struct_typet with an identifier.
Definition: std_types.h:448
namespace.h
struct_exprt
Struct constructor from list of elements.
Definition: std_expr.h:1818
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
set_class_identifier
void set_class_identifier(struct_exprt &expr, const namespacet &ns, const struct_tag_typet &class_type)
If expr has its components filled in then sets the @class_identifier member of the struct.
Definition: class_identifier.cpp:83
empty_typet
The empty type.
Definition: std_types.h:50
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
pointer_expr.h
build_class_identifier
static exprt build_class_identifier(const exprt &src, const namespacet &ns)
Definition: class_identifier.cpp:22
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
irept::swap
void swap(irept &irep)
Definition: irep.h:442
irept::id
const irep_idt & id() const
Definition: irep.h:396
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
struct_typet
Structure type, corresponds to C style structs.
Definition: std_types.h:230
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
string_typet
String type.
Definition: std_types.h:912
pointer_typet::base_type
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
class_identifier.h
exprt::operands
operandst & operands()
Definition: expr.h:94
INVARIANT
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition: invariant.h:423
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
constant_exprt
A constant literal expression.
Definition: std_expr.h:2941
multi_ary_exprt::op0
exprt & op0()
Definition: std_expr.h:877
std_expr.h
c_types.h
to_struct_expr
const struct_exprt & to_struct_expr(const exprt &expr)
Cast an exprt to a struct_exprt.
Definition: std_expr.h:1842