CBMC
anonymous_member.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: ANSI-C Language Type Checking
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "anonymous_member.h"
13 
14 #include <util/namespace.h>
15 #include <util/std_expr.h>
16 
18  const exprt &struct_union,
20  const namespacet &ns)
21 {
22  member_exprt result(
23  struct_union, component.get_name(), component.type());
24 
25  if(struct_union.get_bool(ID_C_lvalue))
26  result.set(ID_C_lvalue, true);
27 
28  // todo: should to typedef chains properly
29  const auto &tag_type = to_struct_or_union_tag_type(struct_union.type());
30  if(
31  ns.follow_tag(tag_type).get_bool(ID_C_constant) ||
32  struct_union.type().get_bool(ID_C_constant))
33  {
34  result.type().set(ID_C_constant, true);
35  }
36 
37  return result;
38 }
39 
41  const exprt &struct_union,
42  const irep_idt &component_name,
43  const namespacet &ns)
44 {
45  const auto &tag_type = to_struct_or_union_tag_type(struct_union.type());
46 
47  for(const auto &comp : ns.follow_tag(tag_type).components())
48  {
49  const typet &type = comp.type();
50 
51  if(comp.get_name()==component_name)
52  {
53  return std::move(make_member_expr(struct_union, comp, ns));
54  }
55  else if(
56  comp.get_anonymous() &&
57  (type.id() == ID_struct_tag || type.id() == ID_union_tag))
58  {
59  const member_exprt tmp = make_member_expr(struct_union, comp, ns);
60  exprt result=get_component_rec(tmp, component_name, ns);
61  if(result.is_not_nil())
62  return result;
63  }
64  }
65 
66  return nil_exprt();
67 }
68 
70  const typet &type,
71  const irep_idt &component_name,
72  const namespacet &ns)
73 {
74  const auto &tag_type = to_struct_or_union_tag_type(type);
75 
76  for(const auto &comp : ns.follow_tag(tag_type).components())
77  {
78  if(comp.get_name()==component_name)
79  {
80  return true;
81  }
82  else if(
83  comp.get_anonymous() &&
84  (comp.type().id() == ID_struct_tag || comp.type().id() == ID_union_tag))
85  {
86  if(has_component_rec(comp.type(), component_name, ns))
87  return true;
88  }
89  }
90 
91  return false;
92 }
bool has_component_rec(const typet &type, const irep_idt &component_name, const namespacet &ns)
static member_exprt make_member_expr(const exprt &struct_union, const struct_union_typet::componentt &component, const namespacet &ns)
exprt get_component_rec(const exprt &struct_union, const irep_idt &component_name, const namespacet &ns)
C Language Type Checking.
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:56
typet & type()
Return the type of the expression.
Definition: expr.h:84
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:57
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:408
bool is_not_nil() const
Definition: irep.h:368
const irep_idt & id() const
Definition: irep.h:384
Extract member of struct or union.
Definition: std_expr.h:2841
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
The NIL expression.
Definition: std_expr.h:3073
const componentst & components() const
Definition: std_types.h:147
The type of an expression, extends irept.
Definition: type.h:29
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition: std_expr.cpp:80
API to expression classes.
const struct_or_union_tag_typet & to_struct_or_union_tag_type(const typet &type)
Cast a typet to a struct_or_union_tag_typet.
Definition: std_types.h:478