ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
symbol.h
Go to the documentation of this file.
1#ifndef CPROVER_SYMBOL_H
2#define CPROVER_SYMBOL_H
3
4#include <list>
5#include <vector>
6#include <irep2/irep2.h>
8#include <util/irep/expr.h>
10
12{
13public:
19
20 // global use
22
23 // ANSI-C
25
26 // For python use
27 bool is_set;
28 std::vector<typet> python_annotation_types;
29
30 symbolt();
31
32 // Type and value accessors. After the symbol-table migration
33 // (esbmc/esbmc#4715, boundary B2), the IREP2 forms `type_` / `value_` are
34 // the source of truth on both sides; the legacy `typet` / `exprt` are
35 // permanent on-demand caches populated lazily by the const readers.
36 // Whichever setter last wrote marks its side valid and invalidates the
37 // other; the reader on the invalidated side lazily derives via the
38 // migration layer on first access. This is the end-state design, not
39 // transitional -- see docs/roadmap/irep2-migration.md.
40 //
41 // The lazy split is deliberate: an eager forward migrate at set_type /
42 // set_value would walk legacy sub-expressions that the existing frontends
43 // sometimes build without populating intermediate types or kinds. The
44 // lazy design tolerates those latent holes as long as nothing reads the
45 // IREP2 side of the affected symbol -- which, in practice, no current
46 // pipeline path does for the tmp symbols involved.
47 const typet &get_type() const;
48 const exprt &get_value() const;
49 const type2tc &get_type2() const;
50 const expr2tc &get_value2() const;
51
52 // Type setters. Each writes one side and invalidates the other; the read
53 // side derives lazily on first access (with the nil/empty-id case guarded
54 // inside the readers).
55 void set_type(const typet &t);
56 void set_type(typet &&t);
57 void set_type(const type2tc &t);
58
59 // Value setters. Mirror of the type setters: legacy variants store the
60 // legacy form and invalidate the IREP2 side; the IREP2-side setter
61 // stores expr2tc directly and invalidates the legacy side.
62 // `migrate_expr_back` covers every expr2t kind a symbol value may hold --
63 // including code_block2t for function bodies -- so the lazy back-migration in
64 // get_value() is safe regardless of what was written.
65 void set_value(const exprt &v);
66 void set_value(exprt &&v);
67 void set_value(const expr2tc &v);
68
69 void clear();
70
71 void swap(symbolt &b);
72
73 void show(std::ostream &out) const;
74 DUMP_METHOD void dump() const;
75
76 void to_irep(irept &dest) const;
77 void from_irep(const irept &src);
78
80
81private:
82 // Type and value storage. IREP2 (`type_`, `value_`) is the source of
83 // truth on both sides; the legacy fields (`legacy_*_cache_`) are
84 // permanent on-demand caches. The setter that wrote last marks its
85 // side valid and invalidates the other; reading the invalidated side
86 // lazily derives via migrate_type / migrate_type_back /
87 // migrate_expr / migrate_expr_back. All fields are mutable so the
88 // const readers can populate from the other side on demand.
89 mutable type2tc type_;
90 mutable typet legacy_type_cache_;
91 mutable bool legacy_type_valid_;
92 mutable bool type2_valid_;
93
94 mutable expr2tc value_;
95 mutable exprt legacy_value_cache_;
96 mutable bool legacy_value_valid_;
97 mutable bool value2_valid_;
98};
99
100std::ostream &operator<<(std::ostream &out, const symbolt &symbol);
101
102typedef std::list<symbolt *> symbol_listt;
103
104#define forall_symbol_list(it, expr) \
105 for (symbol_listt::const_iterator it = (expr).begin(); it != (expr).end(); \
106 it++)
107
108#define Forall_symbol_list(it, expr) \
109 for (symbol_listt::iterator it = (expr).begin(); it != (expr).end(); it++)
110
111typedef std::list<const symbolt *> symbolptr_listt;
112
113#define forall_symbolptr_list(it, list) \
114 for (symbolptr_listt::const_iterator it = (list).begin(); \
115 it != (list).end(); \
116 it++)
117
118#define Forall_symbolptr_list(it, list) \
119 for (symbolptr_listt::iterator it = (list).begin(); it != (list).end(); it++)
120
121#endif
Definition expr.h:34
Definition irep_idt.h:12
Definition irep.h:36
Definition location.h:7
Definition symbol.h:12
irep_idt get_function_name() const
Definition symbol.cpp:323
bool is_set
Definition symbol.h:27
void swap(symbolt &b)
Definition symbol.cpp:159
void clear()
Definition symbol.cpp:35
void to_irep(irept &dest) const
Definition symbol.cpp:243
std::vector< typet > python_annotation_types
Definition symbol.h:28
symbolt()
Definition symbol.cpp:30
const expr2tc & get_value2() const
Definition symbol.cpp:146
bool is_extern
Definition symbol.h:24
DUMP_METHOD void dump() const
Definition symbol.cpp:191
bool is_macro
Definition symbol.h:21
bool static_lifetime
Definition symbol.h:24
const type2tc & get_type2() const
Definition symbol.cpp:119
void show(std::ostream &out) const
Definition symbol.cpp:198
const exprt & get_value() const
Definition symbol.cpp:130
bool file_local
Definition symbol.h:24
irep_idt module
Definition symbol.h:16
locationt location
Definition symbol.h:14
irep_idt id
Definition symbol.h:15
bool is_parameter
Definition symbol.h:21
bool is_thread_local
Definition symbol.h:24
bool is_type
Definition symbol.h:21
bool lvalue
Definition symbol.h:24
void set_value(const exprt &v)
Definition symbol.cpp:85
const typet & get_type() const
Definition symbol.cpp:106
irep_idt name
Definition symbol.h:17
void set_type(const typet &t)
Definition symbol.cpp:60
irep_idt mode
Definition symbol.h:18
void from_irep(const irept &src)
Definition symbol.cpp:284
Definition type.h:9
#define DUMP_METHOD
Definition compiler_defs.h:97
Classes and definitions for non-stringy internal representation.
irep_container< type2t > type2tc
Definition irep2.h:430
irep_container< expr2t > expr2tc
Definition irep2.h:431
std::list< const symbolt * > symbolptr_listt
Definition symbol.h:111
std::ostream & operator<<(std::ostream &out, const symbolt &symbol)
Definition symbol.cpp:237
std::list< symbolt * > symbol_listt
Definition symbol.h:102