cprover
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/std_expr.h>
15 #include <util/c_types.h>
16 #include <util/namespace.h>
17 
22  const exprt &src,
23  const namespacet &ns)
24 {
25  // the class identifier is in the root class
26  exprt e=src;
27 
28  while(1)
29  {
30  const typet &type=ns.follow(e.type());
31  const struct_typet &struct_type=to_struct_type(type);
32  const struct_typet::componentst &components=struct_type.components();
33  assert(!components.empty());
34 
35  const auto &first_member_name=components.front().get_name();
36  member_exprt member_expr(
37  e,
38  first_member_name,
39  components.front().type());
40 
41  if(first_member_name=="@class_identifier")
42  {
43  // found it
44  return member_expr;
45  }
46  else
47  {
48  e.swap(member_expr);
49  }
50  }
51 }
52 
57  const exprt &this_expr_in,
58  const symbol_typet &suggested_type,
59  const namespacet &ns)
60 {
61  // Get a pointer from which we can extract a clsid.
62  // If it's already a pointer to an object of some sort, just use it;
63  // if it's void* then use the suggested type.
64 
65  exprt this_expr=this_expr_in;
66  assert(this_expr.type().id()==ID_pointer &&
67  "Non-pointer this-arg in remove-virtuals?");
68  const auto &points_to=this_expr.type().subtype();
69  if(points_to==empty_typet())
70  this_expr=typecast_exprt(this_expr, pointer_type(suggested_type));
71  const dereference_exprt deref(this_expr, this_expr.type().subtype());
72  return build_class_identifier(deref, ns);
73 }
74 
84  struct_exprt &expr,
85  const namespacet &ns,
86  const symbol_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()=="@class_identifier")
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 }
The type of an expression.
Definition: type.h:22
semantic type conversion
Definition: std_expr.h:2111
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:243
exprt & op0()
Definition: expr.h:72
std::vector< componentt > componentst
Definition: std_types.h:243
const componentst & components() const
Definition: std_types.h:245
typet & type()
Definition: expr.h:56
A constant literal expression.
Definition: std_expr.h:4422
Structure type.
Definition: std_types.h:297
void set_class_identifier(struct_exprt &expr, const namespacet &ns, const symbol_typet &class_type)
If expr has its components filled in then sets the @class_identifier member of the struct...
#define INVARIANT(CONDITION, REASON)
Definition: invariant.h:204
Extract member of struct or union.
Definition: std_expr.h:3869
TO_BE_DOCUMENTED.
Definition: std_types.h:1578
const irep_idt & id() const
Definition: irep.h:259
A reference into the symbol table.
Definition: std_types.h:110
The empty type.
Definition: std_types.h:54
Operator to dereference a pointer.
Definition: std_expr.h:3282
API to expression classes.
TO_BE_DOCUMENTED.
Definition: namespace.h:74
#define PRECONDITION(CONDITION)
Definition: invariant.h:242
const typet & follow(const typet &) const
Definition: namespace.cpp:55
const struct_typet & to_struct_type(const typet &type)
Cast a generic typet to a struct_typet.
Definition: std_types.h:318
static exprt build_class_identifier(const exprt &src, const namespacet &ns)
exprt get_class_identifier_field(const exprt &this_expr_in, const symbol_typet &suggested_type, const namespacet &ns)
const struct_exprt & to_struct_expr(const exprt &expr)
Cast a generic exprt to a struct_exprt.
Definition: std_expr.h:1838
Base class for all expressions.
Definition: expr.h:42
void swap(irept &irep)
Definition: irep.h:303
Extract class identifier.
const typet & subtype() const
Definition: type.h:33
operandst & operands()
Definition: expr.h:66
struct constructor from list of elements
Definition: std_expr.h:1815
const irep_idt & get_identifier() const
Definition: std_types.h:123