ROSE  0.11.2.0
BaseSemanticsSValue.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics2_BaseSemantics_SValue_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics2_BaseSemantics_SValue_H
3 #include <rosePublicConfig.h>
4 #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
5 
6 #include <BaseSemanticsTypes.h>
7 #include <BinarySmtSolver.h>
8 
9 #include <boost/serialization/access.hpp>
10 #include <boost/serialization/nvp.hpp>
11 #include <Sawyer/SharedPointer.h>
12 
13 namespace Rose {
14 namespace BinaryAnalysis {
15 namespace InstructionSemantics2 {
16 namespace BaseSemantics {
17 
19 // Semantic Values
21 
22 // This is leftover for compatibility with an older API. The old API had code like this:
23 // User::SValue user_svalue = BaseSemantics::dynamic_pointer_cast<User::SValue>(base_svalue);
24 // Which can be replaced now with
25 // User::SValue user_svalue = base_svalue.dynamicCast<User::SValue>();
26 template<class To, class From>
27 Sawyer::SharedPointer<To> dynamic_pointer_cast(const Sawyer::SharedPointer<From> &from) {
28  return from.template dynamicCast<To>();
29 }
30 
46 protected:
47  size_t width;
49  // Serialization
51 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
52 private:
53  friend class boost::serialization::access;
54 
55  template<class S>
56  void serialize(S &s, const unsigned /*version*/) {
57  s & BOOST_SERIALIZATION_NVP(width);
58  }
59 #endif
60 
62  // Normal, protected, C++ constructors
63 protected:
64  SValue(): width(0) {} // needed for serialization
65  explicit SValue(size_t nbits): width(nbits) {} // hot
66  SValue(const SValue &other): Sawyer::SharedObject(other), width(other.width) {}
67 
68 public:
70  typedef SValuePtr Ptr;
71 
72 public:
73  virtual ~SValue() {}
74 
76  // Allocating static constructor. None are needed--this class is abstract.
77 
79  // Allocating virtual constructors. undefined_() needs underscores, so we do so consistently for all
80  // these allocating virtual c'tors. However, we use copy() rather than copy_() because this one is fundamentally
81  // different: the object (this) is use for more than just selecting which virtual method to invoke.
82  //
83  // The naming scheme we use here is a bit different than for most other objects for historical reasons. Most other classes
84  // use "create" and "clone" as the virtual constructor names, but SValue uses names ending in undercore, and "copy". The
85  // other difference (at least in this base class) is that we don't define any real constructors or static allocating
86  // constructors (usually named "instance")--it's because this is an abstract class.
87 public:
93  virtual SValuePtr undefined_(size_t nbits) const = 0; // hot
94 
103  virtual SValuePtr unspecified_(size_t nbits) const = 0;
104 
110  virtual SValuePtr bottom_(size_t nBits) const = 0;
111 
115  virtual SValuePtr number_(size_t nbits, uint64_t number) const = 0; // hot
116 
120  virtual SValuePtr boolean_(bool value) const { return number_(1, value?1:0); }
121 
125  virtual SValuePtr copy(size_t new_width=0) const = 0;
126 
154  createOptionalMerge(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const = 0;
155 
162  SValuePtr createMerged(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const /*final*/ {
163  return createOptionalMerge(other, merger, solver).orElse(copy());
164  }
165 
167  // Dynamic pointer casts. No-ops since this is the base class
168 public:
169  static SValuePtr promote(const SValuePtr &x) {
170  ASSERT_not_null(x);
171  return x;
172  }
173 
175  // The rest of the API...
176 public:
182  virtual bool isBottom() const = 0;
183 
186  virtual bool is_number() const = 0;
187 
190  virtual uint64_t get_number() const = 0;
191 
194  virtual size_t get_width() const { return width; }
195  virtual void set_width(size_t nbits) { width = nbits; }
199  virtual bool may_equal(const SValuePtr &other, const SmtSolverPtr &solver = SmtSolverPtr()) const = 0;
200 
202  virtual bool must_equal(const SValuePtr &other, const SmtSolverPtr &solver = SmtSolverPtr()) const = 0;
203 
206  bool isTrue() const {
207  return is_number() && get_number()!=0;
208  }
209 
212  bool isFalse() const {
213  return is_number() && get_number()==0;
214  }
215 
219  void print(std::ostream&) const;
220  virtual void print(std::ostream&, Formatter&) const = 0;
225  SValuePtr obj;
226  Formatter &fmt;
227  public:
228  WithFormatter(const SValuePtr &svalue, Formatter &fmt): obj(svalue), fmt(fmt) {}
229  void print(std::ostream &stream) const { obj->print(stream, fmt); }
230  };
231 
241  WithFormatter operator+(const std::string &linePrefix);
249  virtual std::string get_comment() const { return ""; }
250  virtual void set_comment(const std::string&) const {} // const is intended; cf. doxygen comment
252 };
253 
254 std::ostream& operator<<(std::ostream&, const SValue&);
255 std::ostream& operator<<(std::ostream&, const SValue::WithFormatter&);
256 
257 } // namespace
258 } // namespace
259 } // namespace
260 } // namespace
261 
262 #endif
263 #endif
SharedObject()
Default constructor.
Definition: SharedObject.h:70
virtual std::string get_comment() const
Some subclasses support the ability to add comments to values.
virtual void set_width(size_t nbits)
Accessor for value width.
WithFormatter with_format(Formatter &fmt)
Used for printing values with formatting.
virtual bool must_equal(const SValuePtr &other, const SmtSolverPtr &solver=SmtSolverPtr()) const =0
Returns true if two values must be equal.
void print(std::ostream &) const
Print a value to a stream using default format.
virtual SValuePtr boolean_(bool value) const
Create a new, Boolean value.
SValuePtr createMerged(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const
Create a new value by merging two existing values.
SValuePtr Ptr
Shared-ownership pointer for an SValue object.
WithFormatter operator+(Formatter &fmt)
Used for printing values with formatting.
Holds a value or nothing.
Definition: Optional.h:49
Small object support.
Definition: SmallObject.h:19
Main namespace for the ROSE library.
virtual SValuePtr unspecified_(size_t nbits) const =0
Create a new unspecified semantic value.
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
Name space for the entire library.
Sawyer::SharedPointer< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
virtual uint64_t get_number() const =0
Return the concrete number for this value.
Creates SharedPointer from this.
virtual bool may_equal(const SValuePtr &other, const SmtSolverPtr &solver=SmtSolverPtr()) const =0
Returns true if two values could be equal.
bool isTrue() const
Returns true if concrete non-zero.
virtual void set_comment(const std::string &) const
Some subclasses support the ability to add comments to values.
virtual SValuePtr bottom_(size_t nBits) const =0
Data-flow bottom value.
virtual bool isBottom() const =0
Determines whether a value is a data-flow bottom.
virtual SValuePtr number_(size_t nbits, uint64_t number) const =0
Create a new concrete semantic value.
Base class for reference counted objects.
Definition: SharedObject.h:64
virtual size_t get_width() const
Accessor for value width.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.
virtual bool is_number() const =0
Determines if the value is a concrete number.
virtual SValuePtr undefined_(size_t nbits) const =0
Create a new undefined semantic value.
virtual Sawyer::Optional< SValuePtr > createOptionalMerge(const SValuePtr &other, const MergerPtr &merger, const SmtSolverPtr &solver) const =0
Possibly create a new value by merging two existing values.
virtual SValuePtr copy(size_t new_width=0) const =0
Create a new value from an existing value, changing the width if new_width is non-zero.