CBMC
symbol.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "symbol.h"
10 
11 #include <ostream>
12 
13 #include "source_location.h"
14 #include "std_expr.h"
15 #include "suffix.h"
16 
19 void symbolt::show(std::ostream &out) const
20 {
21  out << " " << name << '\n';
22  out << " type: " << type.pretty(4) << '\n'
23  << " value: " << value.pretty(4) << '\n';
24 
25  out << " flags:";
26  if(is_lvalue)
27  out << " lvalue";
29  out << " static_lifetime";
30  if(is_thread_local)
31  out << " thread_local";
32  if(is_file_local)
33  out << " file_local";
34  if(is_type)
35  out << " type";
36  if(is_extern)
37  out << " extern";
38  if(is_input)
39  out << " input";
40  if(is_output)
41  out << " output";
42  if(is_macro)
43  out << " macro";
44  if(is_parameter)
45  out << " parameter";
46  if(is_auxiliary)
47  out << " auxiliary";
48  if(is_weak)
49  out << " weak";
50  if(is_property)
51  out << " property";
52  if(is_state_var)
53  out << " state_var";
54  if(is_exported)
55  out << " exported";
56  if(is_volatile)
57  out << " volatile";
58  if(!mode.empty())
59  out << " mode=" << mode;
60  if(!base_name.empty())
61  out << " base_name=" << base_name;
62  if(!module.empty())
63  out << " module=" << module;
64  if(!pretty_name.empty())
65  out << " pretty_name=" << pretty_name;
66  out << '\n';
67  out << " location: " << location << '\n';
68 
69  out << '\n';
70 }
71 
76 std::ostream &operator<<(std::ostream &out,
77  const symbolt &symbol)
78 {
79  symbol.show(out);
80  return out;
81 }
82 
86 {
87  #define SYM_SWAP1(x) x.swap(b.x)
88 
89  SYM_SWAP1(type);
91  SYM_SWAP1(name);
95  SYM_SWAP1(mode);
97 
98  #define SYM_SWAP2(x) std::swap(x, b.x)
99 
116 }
117 
122 {
123  return symbol_exprt(name, type);
124 }
125 
129 {
130  // Well-formedness criterion number 1 is for a symbol
131  // to have a non-empty mode (see #1880)
132  if(mode.empty())
133  {
134  return false;
135  }
136 
137  // Well-formedness criterion number 2 is for a symbol
138  // to have it's base name as a suffix to it's more
139  // general name.
140 
141  // Exception: Java symbols' base names do not have type signatures
142  // (for example, they can have name "someclass.method:(II)V" and base name
143  // "method")
144  if(
145  !has_suffix(id2string(name), id2string(base_name)) && mode != ID_java &&
146  mode != ID_cpp)
147  {
148  bool criterion_must_hold = true;
149 
150  // There are some special cases where this criterion doesn't hold, check
151  // to see if we have one of those cases
152 
153  if(is_type)
154  {
155  // Typedefs
156  if(
157  type.find(ID_C_typedef).is_not_nil() &&
158  type.find(ID_C_typedef).id() == base_name)
159  {
160  criterion_must_hold = false;
161  }
162 
163  // Tag types
164  if(type.find(ID_tag).is_not_nil() && type.find(ID_tag).id() == base_name)
165  {
166  criterion_must_hold = false;
167  }
168  }
169 
170  // Linker renaming may have added $linkN suffixes to the name, and other
171  // suffixes such as #return_value may have then be subsequently added.
172  // Strip out the first $linkN substring and then see if the criterion holds
173  const auto &unstripped_name = id2string(name);
174  const size_t dollar_link_start_pos = unstripped_name.find("$link");
175 
176  if(dollar_link_start_pos != std::string::npos)
177  {
178  size_t dollar_link_end_pos = dollar_link_start_pos + 5;
179  while(isdigit(unstripped_name[dollar_link_end_pos]))
180  {
181  ++dollar_link_end_pos;
182  }
183 
184  const auto stripped_name =
185  unstripped_name.substr(0, dollar_link_start_pos) +
186  unstripped_name.substr(dollar_link_end_pos, std::string::npos);
187 
188  if(has_suffix(stripped_name, id2string(base_name)))
189  criterion_must_hold = false;
190  }
191 
192  if(criterion_must_hold)
193  {
194  // For all other cases this criterion should hold
195  return false;
196  }
197  }
198 
199  return true;
200 }
201 
202 bool symbolt::operator==(const symbolt &other) const
203 {
204  // clang-format off
205  return
206  type == other.type &&
207  value == other.value &&
208  location == other.location &&
209  name == other.name &&
210  module == other.module &&
211  base_name == other.base_name &&
212  mode == other.mode &&
213  pretty_name == other.pretty_name &&
214  is_type == other.is_type &&
215  is_macro == other.is_macro &&
216  is_exported == other.is_exported &&
217  is_input == other.is_input &&
218  is_output == other.is_output &&
219  is_state_var == other.is_state_var &&
220  is_property == other.is_property &&
221  is_parameter == other.is_parameter &&
222  is_auxiliary == other.is_auxiliary &&
223  is_weak == other.is_weak &&
224  is_lvalue == other.is_lvalue &&
226  is_thread_local == other.is_thread_local &&
227  is_file_local == other.is_file_local &&
228  is_extern == other.is_extern &&
229  is_volatile == other.is_volatile;
230  // clang-format on
231 }
232 
233 bool symbolt::operator!=(const symbolt &other) const
234 {
235  return !(*this == other);
236 }
symbolt::is_state_var
bool is_state_var
Definition: symbol.h:62
symbolt::is_macro
bool is_macro
Definition: symbol.h:61
irept::pretty
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:495
irept::find
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
symbolt::type
typet type
Type of symbol.
Definition: symbol.h:31
symbolt::operator==
bool operator==(const symbolt &other) const
Definition: symbol.cpp:202
symbolt::is_input
bool is_input
Definition: symbol.h:62
symbolt::base_name
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
has_suffix
bool has_suffix(const std::string &s, const std::string &suffix)
Definition: suffix.h:17
symbolt::pretty_name
irep_idt pretty_name
Language-specific display name.
Definition: symbol.h:52
symbolt::is_thread_local
bool is_thread_local
Definition: symbol.h:65
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
symbolt::is_well_formed
bool is_well_formed() const
Check that a symbol is well formed.
Definition: symbol.cpp:128
symbolt::mode
irep_idt mode
Language mode.
Definition: symbol.h:49
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
source_location.h
symbolt::is_exported
bool is_exported
Definition: symbol.h:61
symbolt::is_parameter
bool is_parameter
Definition: symbol.h:67
symbol.h
Symbol table entry.
irept::id
const irep_idt & id() const
Definition: irep.h:396
SYM_SWAP1
#define SYM_SWAP1(x)
dstringt::empty
bool empty() const
Definition: dstring.h:88
symbolt::value
exprt value
Initial value of symbol.
Definition: symbol.h:34
symbolt::is_output
bool is_output
Definition: symbol.h:62
symbolt::is_extern
bool is_extern
Definition: symbol.h:66
suffix.h
symbolt::is_volatile
bool is_volatile
Definition: symbol.h:66
symbolt::location
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
symbolt
Symbol table entry.
Definition: symbol.h:27
symbolt::is_type
bool is_type
Definition: symbol.h:61
symbolt::show
void show(std::ostream &out) const
Dump the state of a symbol object to a given output stream.
Definition: symbol.cpp:19
symbolt::is_auxiliary
bool is_auxiliary
Definition: symbol.h:67
symbolt::is_static_lifetime
bool is_static_lifetime
Definition: symbol.h:65
symbolt::swap
void swap(symbolt &b)
Swap values between two symbols.
Definition: symbol.cpp:85
symbolt::operator!=
bool operator!=(const symbolt &other) const
Definition: symbol.cpp:233
symbolt::is_file_local
bool is_file_local
Definition: symbol.h:66
symbolt::is_lvalue
bool is_lvalue
Definition: symbol.h:66
symbolt::module
irep_idt module
Name of module the symbol belongs to.
Definition: symbol.h:43
std_expr.h
symbolt::is_weak
bool is_weak
Definition: symbol.h:67
SYM_SWAP2
#define SYM_SWAP2(x)
symbolt::name
irep_idt name
The unique identifier.
Definition: symbol.h:40
symbolt::is_property
bool is_property
Definition: symbol.h:62
operator<<
std::ostream & operator<<(std::ostream &out, const symbolt &symbol)
Overload of stream operator to work with symbols.
Definition: symbol.cpp:76