ROSE  0.11.145.0
SymbolicExpression.h
1 #ifndef ROSE_BinaryAnalysis_SymbolicExpression_H
2 #define ROSE_BinaryAnalysis_SymbolicExpression_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #ifndef __STDC_FORMAT_MACROS
7 #define __STDC_FORMAT_MACROS
8 #endif
9 
10 #include "Map.h"
11 
12 #include <boost/any.hpp>
13 #include <boost/lexical_cast.hpp>
14 #include <boost/logic/tribool.hpp>
15 #include <boost/serialization/access.hpp>
16 #include <boost/serialization/base_object.hpp>
17 #include <boost/serialization/export.hpp>
18 #include <boost/serialization/split_member.hpp>
19 #include <boost/serialization/string.hpp>
20 #include <boost/serialization/vector.hpp>
21 #include <boost/unordered_map.hpp>
22 #include <cassert>
23 #include <inttypes.h>
24 #include <Rose/Exception.h>
25 #include <Sawyer/Attribute.h>
26 #include <Sawyer/BitVector.h>
27 #include <Sawyer/Optional.h>
28 #include <Sawyer/Set.h>
29 #include <Sawyer/SharedPointer.h>
30 #include <Sawyer/SmallObject.h>
31 #include <set>
32 #include <string>
33 #include <vector>
34 
35 namespace Rose {
36 namespace BinaryAnalysis {
37 
43 namespace SymbolicExpression {
44 
46 // Basic Types and settings
48 
57 extern bool serializeVariableIds;
58 
60 namespace TypeStyle {
62  enum Flag {
63  FULL,
65  };
66 }
67 
68 
70 class Exception: public Rose::Exception {
71 public:
72  explicit Exception(const std::string &mesg): Rose::Exception(mesg) {}
73 };
74 
80 enum Operator {
152 };
153 
154 std::string toStr(Operator);
155 
156 using Nodes = std::vector<Ptr>;
157 using RenameMap = Map<uint64_t, uint64_t>;
158 
160 using Hash = uint64_t;
161 
163 class Formatter {
164 public:
170  };
171  Formatter()
173  max_depth(0), cur_depth(0), show_type(true), show_flags(true) {}
175  bool do_rename;
176  bool add_renames;
178  size_t max_depth;
179  size_t cur_depth;
181  bool show_type;
182  bool show_flags;
183 };
184 
190 };
191 
196 extern const uint64_t MAX_NNODES; // defined in .C so we don't pollute user namespace with limit macros
197 
209 class Visitor {
210 public:
211  virtual ~Visitor() {}
212 
213  virtual VisitAction preVisit(const Ptr&);
214  virtual VisitAction postVisit(const Ptr&);
215 
216  virtual VisitAction preVisit(const Node*);
217  virtual VisitAction postVisit(const Node*);
218 };
219 
221 // Expression type information
223 
225 class Type {
226 public:
228  enum TypeClass {
230  FP,
233  };
234 
235 private:
236  // We use a 32-bit data member and pack into it the totalWidth (15 bits: 0 through 14), the secondaryWidth (15 bits: 15 through 29),
237  // and the type class (2 bits: 30 and 31).
238  uint32_t fields_;
239 
240 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
241 private:
242  friend class boost::serialization::access;
243 
244  template<class S>
245  void serialize(S &s, const unsigned version) {
246  if (version >= 1) {
247  s & BOOST_SERIALIZATION_NVP(fields_);
248  } else {
249  TypeClass t = typeClass();
250  size_t z1 = nBits();
251  size_t z2 = secondaryWidth();
252  s & boost::serialization::make_nvp("typeClass_", t);
253  s & boost::serialization::make_nvp("totalWidth_", z1);
254  s & boost::serialization::make_nvp("secondaryWidth_", z2);
255  typeClass(t);
256  nBits(z1);
257  secondaryWidth(z2);
258  }
259  }
260 #endif
261 
265 public:
267  : fields_(0) {
269  nBits(0);
270  secondaryWidth(0);
271  }
272 
273 private:
274  Type(TypeClass tc, size_t w1, size_t w2)
275  : fields_(0) {
276  typeClass(tc);
277  nBits(w1);
278  secondaryWidth(w2);
279  }
280 
281 public:
285  static Type none() {
286  return Type();
287  }
288 
294  static Type integer(size_t nBits) {
295  return Type(INTEGER, nBits, 0);
296  }
297 
301  static Type memory(size_t addressWidth, size_t valueWidth) {
302  return Type(MEMORY, valueWidth, addressWidth);
303  }
304 
314  return Type(FP, 1 /*sign bit*/ + exponentWidth + significandWidth - 1 /*implied bit*/, exponentWidth);
315  }
316 
320  bool isValid() const {
321  return typeClass() != INVALID;
322  }
323 
328  return (TypeClass)((fields_ >> 30) & 0x3);
329  }
330 
335  size_t nBits() const {
336  return fields_ & 0x7fff;
337  }
338 
343  size_t addressWidth() const {
344  ASSERT_require(MEMORY == typeClass());
345  return secondaryWidth();
346  }
347 
352  size_t exponentWidth() const {
353  ASSERT_require(FP == typeClass());
354  return secondaryWidth();
355  }
356 
362  size_t significandWidth() const {
363  ASSERT_require(FP == typeClass());
364  ASSERT_require(nBits() > 1 /*sign bit*/ + exponentWidth() - 1 /*implied bit*/);
365  return nBits() - (1 /*sign bit*/ + exponentWidth() - 1 /*implied bit*/);
366  }
367 
373  bool operator==(const Type &other) const {
374  return fields_ == other.fields_;
375  }
376  bool operator!=(const Type &other) const {
377  return !(*this == other);
378  }
382  bool operator<(const Type &other) const;
383 
385  void print(std::ostream&, TypeStyle::Flag style = TypeStyle::FULL) const;
386 
388  std::string toString(TypeStyle::Flag style = TypeStyle::FULL) const;
389 
390 private:
391  // mutators are all private
392  void typeClass(TypeClass tc) {
393  unsigned n = tc;
394  ASSERT_require(n <= 3);
395  fields_ = (fields_ & 0x3fffffff) | (n << 30);
396  }
397 
398  // mutators are all private
399  void nBits(size_t n) {
400  if (n > 0x7fff)
401  throw Exception("type width is out of range");
402  fields_ = (fields_ & 0xffff8000) | n;
403  }
404 
405  // mutators are all private
406  void secondaryWidth(size_t n) {
407  if (n > 0x7fff)
408  throw Exception("second width is out of range");
409  fields_ = (fields_ & 0xc0007fff) | (n << 15);
410  }
411 
412  size_t secondaryWidth() const {
413  return (fields_ >> 15) & 0x7fff;
414  }
415 };
416 
418 // Base Node Type
420 
458 class Node
459  : public Sawyer::SharedObject,
460  public Sawyer::SharedFromThis<Node>,
461  public Sawyer::SmallObject,
462  public Sawyer::Attribute::Storage<> { // Attributes are not significant for hashing or arithmetic
463 protected:
464  Type type_;
465  unsigned flags_;
466  std::string comment_;
467  mutable Hash hashval_;
468  boost::any userData_;
470 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
471 private:
472  friend class boost::serialization::access;
473 
474  template<class S>
475  void serialize(S &s, const unsigned version) {
476  if (version < 1)
477  ASSERT_not_reachable("SymbolicExpression version " + boost::lexical_cast<std::string>(version) + " is no longer supported");
478  s & BOOST_SERIALIZATION_NVP(type_);
479  s & BOOST_SERIALIZATION_NVP(flags_);
480  s & BOOST_SERIALIZATION_NVP(comment_);
481  s & BOOST_SERIALIZATION_NVP(hashval_);
482  // s & userData_;
483  }
484 #endif
485 
486 public:
487  // Bit flags
488 
490  static const unsigned RESERVED_FLAGS = 0x0000ffff;
491 
493  static const unsigned INDETERMINATE = 0x00000001;
494 
499  static const unsigned UNSPECIFIED = 0x00000002;
500 
503  static const unsigned BOTTOM = 0x00000004;
504 
505 public:
506  virtual ~Node() {}
507 
508 protected:
509  Node()
510  : type_(Type::integer(0)), flags_(0), hashval_(0) {}
511  explicit Node(const std::string &comment, unsigned flags=0)
512  : type_(Type::integer(0)), flags_(flags), comment_(comment), hashval_(0) {}
513 
514 public:
516  Type type() const {
517  return type_;
518  }
519 
526  static boost::logic::tribool (*mayEqualCallback)(const Ptr &a, const Ptr &b, const SmtSolverPtr&);
527 
533  virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
534 
536  virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
537 
543  virtual bool isEquivalentTo(const Ptr &other) = 0;
544 
550  virtual int compareStructure(const Ptr &other) = 0;
551 
557  virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) = 0;
558 
566  Ptr substituteMultiple(const ExprExprHashMap &substitutions, const SmtSolverPtr &solver = SmtSolverPtr());
567 
575  Ptr renameVariables(ExprExprHashMap &index /*in,out*/, size_t &nextVariableId /*in,out*/,
576  const SmtSolverPtr &solver = SmtSolverPtr());
577 
581  virtual Operator getOperator() const = 0;
582 
586  virtual size_t nChildren() const = 0;
587 
594  virtual const Ptr& child(size_t idx) const = 0;
595  virtual const Node* childRaw(size_t idx) const = 0;
601  virtual const Nodes& children() const = 0;
602 
607  virtual Sawyer::Optional<uint64_t> toUnsigned() const = 0;
608 
612  virtual Sawyer::Optional<int64_t> toSigned() const = 0;
613 
615  bool isIntegerExpr() const {
616  return type_.typeClass() == Type::INTEGER;
617  }
618 
620  bool isFloatingPointExpr() const {
621  return type_.typeClass() == Type::FP;
622  }
623 
625  bool isMemoryExpr() const {
626  return type_.typeClass() == Type::MEMORY;
627  }
628 
632  bool isScalarExpr() const {
633  return isIntegerExpr() || isFloatingPointExpr();
634  }
635 
637  virtual bool isConstant() const = 0;
638 
640  bool isIntegerConstant() const {
641  return isIntegerExpr() && isConstant();
642  }
643 
645  bool isFloatingPointConstant() const {
646  return isFloatingPointExpr() && isConstant();
647  }
648 
652  bool isScalarConstant() const {
654  }
655 
657  bool isFloatingPointNan() const;
658 
664  virtual bool isVariable2() const = 0;
665 
670 
672  bool isIntegerVariable() const {
673  return isIntegerExpr() && isVariable2();
674  }
675 
677  bool isFloatingPointVariable() const {
678  return isFloatingPointExpr() && isVariable2();
679  }
680 
682  bool isMemoryVariable() const {
683  return isMemoryExpr() && isVariable2();
684  }
685 
689  bool isScalarVariable() const {
691  }
692 
701  const std::string& comment() const {
702  return comment_;
703  }
704  void comment(const std::string &s) {
705  comment_ = s;
706  }
716  void userData(boost::any &data) {
717  userData_ = data;
718  }
719  const boost::any& userData() const {
720  return userData_;
721  }
727  size_t nBits() const {
728  return type_.nBits();
729  }
730 
735  unsigned flags() const {
736  return flags_;
737  }
738 
742  Ptr newFlags(unsigned flags) const;
743 
747  size_t domainWidth() const {
748  return type_.addressWidth();
749  }
750 
754  bool isScalar() const {
755  return type_.typeClass() != Type::MEMORY;
756  }
757 
762  virtual VisitAction depthFirstTraversal(Visitor&) const = 0;
763 
779  virtual uint64_t nNodes() const = 0;
780 
782  uint64_t nNodesUnique() const;
783 
785  std::set<LeafPtr> getVariables() const;
786 
792  InteriorPtr isInteriorNode() const;
793  Interior* isInteriorNodeRaw() const;
801  LeafPtr isLeafNode() const;
802  Leaf* isLeafNodeRaw() const;
808  bool isHashed() const {
809  return hashval_ != 0;
810  }
811 
814  Hash hash() const;
815 
816  // used internally to set the hash value
817  void hash(Hash) const;
818 
821  private:
822  Ptr node;
823  Formatter &formatter;
824  public:
825  WithFormatter(const Ptr &node, Formatter &formatter): node(node), formatter(formatter) {}
826  void print(std::ostream &stream) const { node->print(stream, formatter); }
827  };
828 
850  virtual void print(std::ostream&, Formatter&) const = 0;
851  void print(std::ostream &o) const { Formatter fmt; print(o, fmt); }
855  std::string toString() const;
856 
858  void assertAcyclic() const;
859 
865  std::vector<Ptr> findCommonSubexpressions() const;
866 
872  bool matchAddVariableConstant(LeafPtr &variable/*out*/, LeafPtr &constant/*out*/) const;
873 
876 
877 protected:
878  void printFlags(std::ostream &o, unsigned flags, char &bracket) const;
879 
880 public: // only used internally
881  using EquivPairs = std::map<Node*, std::vector<std::pair<Node*, bool>>>;
882  virtual bool isEquivalentHelper(Node*, EquivPairs&) = 0;
883 };
884 
886 class Simplifier {
887 public:
888  virtual ~Simplifier() {}
889 
893  virtual Ptr fold(Nodes::const_iterator /*begin*/, Nodes::const_iterator /*end*/) const {
894  return Ptr();
895  }
896 
899  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const {
900  return Ptr();
901  }
902 };
903 
905  size_t operator()(const Ptr &expr) const {
906  return expr->hash();
907  }
908 };
909 
911  bool operator()(const Ptr &a, const Ptr &b) const {
912  return a->isEquivalentTo(b);
913  }
914 };
915 
918 public:
919  bool operator()(const Ptr &a, const Ptr &b) const;
920 };
921 
923 class ExprExprHashMap: public boost::unordered_map<SymbolicExpression::Ptr, SymbolicExpression::Ptr,
924  ExprExprHashMapHasher, ExprExprHashMapCompare> {
925 public:
926  ExprExprHashMap invert() const;
927 };
928 
931 
932 
934 // Simplification
936 
938  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
939  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
940 };
942  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
943  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
944 };
946  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
947 };
949  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
950  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
951 };
953  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
954  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
955 };
957  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
958 };
960  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
961 };
963  virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override;
964  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
965 };
967  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
968 };
970  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
971 };
973  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
974 };
976  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
977 };
979  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
980 };
982  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
983 };
985  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
986 };
988  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
989 };
991  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
992 };
994  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
995 };
997  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
998 };
1000  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1001 };
1003  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1004 };
1006  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1007 };
1009  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1010 };
1012  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1013 };
1015  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1016 };
1018  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1019 };
1021  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1022 };
1024  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1025 };
1027  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1028 };
1030  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1031 };
1033  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1034 };
1036  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1037 };
1039  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1040 };
1042  bool newbits;
1043  ShiftSimplifier(bool newbits): newbits(newbits) {}
1044  Ptr combine_strengths(Ptr strength1, Ptr strength2, size_t value_width, const SmtSolverPtr &solver) const;
1045 };
1047  ShlSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1048  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1049 };
1051  ShrSimplifier(bool newbits): ShiftSimplifier(newbits) {}
1052  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1053 };
1055  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1056 };
1058  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1059 };
1061  virtual Ptr rewrite(Interior*, const SmtSolverPtr&) const override;
1062 };
1063 
1064 
1065 
1067 // Interior Nodes
1069 
1076 class Interior: public Node {
1077 private:
1078  Operator op_;
1079  Nodes children_;
1080  uint64_t nnodes_; // total number of nodes; self + children's nnodes
1081 
1082  //--------------------------------------------------------
1083  // Serialization
1084  //--------------------------------------------------------
1085 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1086 private:
1087  friend class boost::serialization::access;
1088 
1089  template<class S>
1090  void serialize(S &s, const unsigned /*version*/) {
1091  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1092  s & BOOST_SERIALIZATION_NVP(op_);
1093  s & BOOST_SERIALIZATION_NVP(children_);
1094  s & BOOST_SERIALIZATION_NVP(nnodes_);
1095  }
1096 #endif
1097 
1098  //--------------------------------------------------------
1099  // Real constructors
1100  //--------------------------------------------------------
1101 private:
1102  Interior(); // needed for serialization
1103  // Only constructs, does not simplify.
1104  Interior(const Type&, Operator, const Nodes &arguments, const std::string &comment, unsigned flags);
1105 
1106  //--------------------------------------------------------
1107  // Allocating constructors
1108  //--------------------------------------------------------
1109 public:
1113  static Ptr instance(Operator op, const Ptr &a,
1114  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1115  static Ptr instance(const Type &type, Operator op, const Ptr &a,
1116  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1117  static Ptr instance(Operator op, const Ptr &a, const Ptr &b,
1118  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1119  static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b,
1120  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1121  static Ptr instance(Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1122  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1123  static Ptr instance(const Type &type, Operator op, const Ptr &a, const Ptr &b, const Ptr &c,
1124  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1125  static Ptr instance(Operator op, const Nodes &arguments,
1126  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1127  static Ptr instance(const Type &type, Operator op, const Nodes &arguments,
1128  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1131  //--------------------------------------------------------
1132  // Overrides
1133  //--------------------------------------------------------
1134 public:
1135  virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1136  virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1137  virtual bool isEquivalentTo(const Ptr &other) override;
1138  virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1139  virtual int compareStructure(const Ptr& other) override;
1140  virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1141  virtual VisitAction depthFirstTraversal(Visitor&) const override;
1142  virtual uint64_t nNodes() const override { return nnodes_; }
1143  virtual const Nodes& children() const override { return children_; }
1144  virtual Operator getOperator() const override { return op_; }
1145  virtual size_t nChildren() const override { return children_.size(); }
1146  virtual const Ptr& child(size_t idx) const override;
1147  virtual Node* childRaw(size_t idx) const override;
1148  virtual Sawyer::Optional<uint64_t> toUnsigned() const override { return Sawyer::Nothing(); }
1149  virtual Sawyer::Optional<int64_t> toSigned() const override { return Sawyer::Nothing(); }
1150  virtual bool isConstant() const override { return false; }
1151  virtual bool isVariable2() const override { return false; }
1152 
1153  //--------------------------------------------------------
1154  // Simplification
1155  //--------------------------------------------------------
1156 public:
1160  Ptr simplifyTop(const SmtSolverPtr &solver = SmtSolverPtr());
1161 
1164  Ptr foldConstants(const Simplifier&);
1165 
1171 
1177 
1184  InteriorPtr idempotent(const SmtSolverPtr &solver = SmtSolverPtr());
1185 
1189  Ptr involutary();
1190 
1194  Ptr additiveNesting(const SmtSolverPtr &solver = SmtSolverPtr());
1195 
1199  Ptr identity(uint64_t ident, const SmtSolverPtr &solver = SmtSolverPtr());
1200 
1205  Ptr poisonNan(const SmtSolverPtr &solver = SmtSolverPtr());
1206 
1208  Ptr unaryNoOp();
1209 
1213  Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver = SmtSolverPtr());
1214 
1215  //--------------------------------------------------------
1216  // Functions specific to internal nodes
1217  //--------------------------------------------------------
1218 public:
1219  virtual void print(std::ostream&, Formatter&) const override;
1220 
1221 protected:
1223  void addChild(const Ptr &child);
1224 
1228  void adjustWidth(const Type&);
1229 
1232  void adjustBitFlags(unsigned extraFlags);
1233 };
1234 
1235 
1237 // Leaf Nodes
1239 
1243 class Leaf: public Node {
1244 private:
1245  Sawyer::Container::BitVector bits_; // Value for constants if size > 0
1246  uint64_t name_; // Variable ID for variables when bits_.size() == 0
1247 
1248  //--------------------------------------------------------
1249  // Serialization
1250  //--------------------------------------------------------
1251 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1252 private:
1253  friend class boost::serialization::access;
1254 
1255  template<class S>
1256  void save(S &s, const unsigned /*version*/) const {
1257  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1258  s & BOOST_SERIALIZATION_NVP(bits_);
1259  s & BOOST_SERIALIZATION_NVP(name_);
1260  }
1261 
1262  template<class S>
1263  void load(S &s, const unsigned /*version*/) {
1264  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Node);
1265  s & BOOST_SERIALIZATION_NVP(bits_);
1266  s & BOOST_SERIALIZATION_NVP(name_);
1267  nextNameCounter(name_);
1268  }
1269 
1270  BOOST_SERIALIZATION_SPLIT_MEMBER();
1271 #endif
1272 
1273  //--------------------------------------------------------
1274  // Private constructors. Use create methods instead.
1275  //--------------------------------------------------------
1276 private:
1277  Leaf()
1278  : name_(0) {}
1279  explicit Leaf(const std::string &comment, unsigned flags=0)
1280  : Node(comment, flags), name_(0) {}
1281 
1282  // Allocating constructors.
1283 public:
1285  static LeafPtr createVariable(const Type&,
1286  const std::string &comment = "", unsigned flags = 0);
1287 
1289  static LeafPtr createVariable(const Type&, const uint64_t id,
1290  const std::string &comment = "", unsigned flags = 0);
1291 
1294  const std::string &comment = "", unsigned flags = 0);
1295 
1296  //--------------------------------------------------------
1297  // Override base class implementations
1298  //--------------------------------------------------------
1299 public:
1300  virtual size_t nChildren() const override { return 0; }
1301  virtual const Ptr& child(size_t idx) const override;
1302  virtual const Node* childRaw(size_t) const override { return nullptr; }
1303  virtual const Nodes& children() const override;
1304  virtual Operator getOperator() const override { return OP_NONE; }
1305  virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1306  virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1307  virtual bool isEquivalentTo(const Ptr &other) override;
1308  virtual bool isEquivalentHelper(Node*, EquivPairs&) override;
1309  virtual int compareStructure(const Ptr& other) override;
1310  virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver = SmtSolverPtr()) override;
1311  virtual VisitAction depthFirstTraversal(Visitor&) const override;
1312  virtual uint64_t nNodes() const override { return 1; }
1313  virtual Sawyer::Optional<uint64_t> toUnsigned() const override;
1314  virtual Sawyer::Optional<int64_t> toSigned() const override;
1315  virtual bool isConstant() const override { return !bits_.isEmpty(); }
1316  virtual bool isVariable2() const override { return !isConstant(); }
1317  virtual void print(std::ostream&, Formatter&) const override;
1318 
1319  //--------------------------------------------------------
1320  // Leaf-specific methods
1321  //--------------------------------------------------------
1322 public:
1324  const Sawyer::Container::BitVector& bits() const;
1325 
1327  bool isIntegerVariable() const {
1328  return type().typeClass() == Type::INTEGER && !isConstant();
1329  }
1330 
1333  return type().typeClass() == Type::FP && !isConstant();
1334  }
1335 
1337  bool isFloatingPointNan() const;
1338 
1340  bool isMemoryVariable() const {
1341  return type().typeClass() == Type::MEMORY && !isConstant();
1342  }
1343 
1348  uint64_t nameId() const;
1349 
1354  std::string toString() const;
1355 
1357  void printAsSigned(std::ostream&, Formatter&, bool asSigned = true) const;
1358 
1360  void printAsUnsigned(std::ostream &o, Formatter &f) const {
1361  printAsSigned(o, f, false);
1362  }
1363 
1364 private:
1365  // Obtain or register a name ID
1366  static uint64_t nextNameCounter(uint64_t useThis = (uint64_t)(-1));
1367 };
1368 
1370 // Factories
1372 
1378 LeafPtr makeVariable(const Type&, const std::string &comment="", unsigned flags=0);
1379 LeafPtr makeVariable(const Type&, uint64_t id, const std::string &comment="", unsigned flags=0);
1380 LeafPtr makeConstant(const Type&, const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1381 LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0);
1382 LeafPtr makeIntegerVariable(size_t nBits, uint64_t id, const std::string &comment="", unsigned flags=0);
1383 LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0);
1384 LeafPtr makeIntegerConstant(const Sawyer::Container::BitVector&, const std::string &comment="", unsigned flags=0);
1385 LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0);
1386 LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0);
1387 LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, uint64_t id, const std::string &comment="", unsigned flags=0);
1388 LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1389 LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, uint64_t id, const std::string &comment="", unsigned flags=0);
1390 LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0);
1391 LeafPtr makeFloatingPointConstant(double, const std::string &comment="", unsigned flags=0);
1392 LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0);
1401 Ptr makeAdd(const Ptr&a, const Ptr &b,
1402  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1403 Ptr makeAsr(const Ptr &sa, const Ptr &a,
1404  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1405 Ptr makeAnd(const Ptr &a, const Ptr &b,
1406  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1407 Ptr makeOr(const Ptr &a, const Ptr &b,
1408  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1409 Ptr makeXor(const Ptr &a, const Ptr &b,
1410  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1411 Ptr makeConcat(const Ptr &hi, const Ptr &lo,
1412  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1413 Ptr makeConvert(const Ptr &a, const Type &b,
1414  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1415 Ptr makeEq(const Ptr &a, const Ptr &b,
1416  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1417 Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a,
1418  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1419 Ptr makeInvert(const Ptr &a,
1420  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1421 Ptr makeIsInfinite(const Ptr &a,
1422  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1423 Ptr makeIsNan(const Ptr &a,
1424  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1425 Ptr makeIsNeg(const Ptr &a,
1426  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1427 Ptr makeIsNorm(const Ptr &a,
1428  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1429 Ptr makeIsPos(const Ptr &a,
1430  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1431 Ptr makeIsSubnorm(const Ptr &a,
1432  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1433 Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b,
1434  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1435 Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c,
1436  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1437 Ptr makeLssb(const Ptr &a,
1438  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1439 Ptr makeMax(const Ptr &a, const Ptr &b,
1440  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1441 Ptr makeMin(const Ptr &a, const Ptr &b,
1442  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1443 Ptr makeMssb(const Ptr &a,
1444  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1445 Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c,
1446  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1447 Ptr makeNe(const Ptr &a, const Ptr &b,
1448  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1449 Ptr makeNegate(const Ptr &a,
1450  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1451 Ptr makeRead(const Ptr &mem, const Ptr &addr,
1452  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1453 Ptr makeReinterpret(const Ptr &a, const Type &b,
1454  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1455 Ptr makeRol(const Ptr &sa, const Ptr &a,
1456  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1457 Ptr makeRor(const Ptr &sa, const Ptr &a,
1458  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1459 Ptr makeRound(const Ptr &a,
1460  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1461 Ptr makeSet(const Ptr &a, const Ptr &b,
1462  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1463 Ptr makeSet(const Ptr &a, const Ptr &b, const Ptr &c,
1464  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1465 Ptr makeSignedDiv(const Ptr &a, const Ptr &b,
1466  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1467 Ptr makeSignExtend(const Ptr &newSize, const Ptr &a,
1468  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1469 Ptr makeSignedGe(const Ptr &a, const Ptr &b,
1470  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1471 Ptr makeSignedGt(const Ptr &a, const Ptr &b,
1472  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1473 Ptr makeShl0(const Ptr &sa, const Ptr &a,
1474  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1475 Ptr makeShl1(const Ptr &sa, const Ptr &a,
1476  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1477 Ptr makeShr0(const Ptr &sa, const Ptr &a,
1478  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1479 Ptr makeShr1(const Ptr &sa, const Ptr &a,
1480  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1481 Ptr makeIsSignedPos(const Ptr &a,
1482  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1483 Ptr makeSignedLe(const Ptr &a, const Ptr &b,
1484  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1485 Ptr makeSignedLt(const Ptr &a, const Ptr &b,
1486  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1487 Ptr makeSignedMax(const Ptr &a, const Ptr &b,
1488  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1489 Ptr makeSignedMin(const Ptr &a, const Ptr &b,
1490  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1491 Ptr makeSignedMod(const Ptr &a, const Ptr &b,
1492  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1493 Ptr makeSignedMul(const Ptr &a, const Ptr &b,
1494  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1495 Ptr makeSqrt(const Ptr &a,
1496  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1497 Ptr makeDiv(const Ptr &a, const Ptr &b,
1498  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1499 Ptr makeExtend(const Ptr &newSize, const Ptr &a,
1500  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1501 Ptr makeGe(const Ptr &a, const Ptr &b,
1502  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1503 Ptr makeGt(const Ptr &a, const Ptr &b,
1504  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1505 Ptr makeLe(const Ptr &a, const Ptr &b,
1506  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1507 Ptr makeLt(const Ptr &a, const Ptr &b,
1508  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1509 Ptr makeMod(const Ptr &a, const Ptr &b,
1510  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1511 Ptr makeMul(const Ptr &a, const Ptr &b,
1512  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1513 Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a,
1514  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1515 Ptr makeZerop(const Ptr &a,
1516  const SmtSolverPtr &solver = SmtSolverPtr(), const std::string &comment="", unsigned flags=0);
1520 // Miscellaneous functions
1523 
1524 
1525 std::ostream& operator<<(std::ostream &o, const Node&);
1526 std::ostream& operator<<(std::ostream &o, const Node::WithFormatter&);
1527 
1529 Ptr setToIte(const Ptr&, const SmtSolverPtr &solver = SmtSolverPtr(), const LeafPtr &var = LeafPtr());
1530 
1535 Hash hash(const std::vector<Ptr>&);
1536 
1541 template<typename InputIterator>
1542 uint64_t
1543 nNodes(InputIterator begin, InputIterator end) {
1544  uint64_t total = 0;
1545  for (InputIterator ii=begin; ii!=end; ++ii) {
1546  uint64_t n = (*ii)->nnodes();
1547  if (MAX_NNODES==n)
1548  return MAX_NNODES;
1549  if (total + n < total)
1550  return MAX_NNODES;
1551  total += n;
1552  }
1553  return total;
1554 }
1555 
1560 template<typename InputIterator>
1561 uint64_t
1562 nNodesUnique(InputIterator begin, InputIterator end)
1563 {
1564  struct T1: Visitor {
1565  typedef std::set<const Node*> SeenNodes;
1566 
1567  SeenNodes seen; // nodes that we've already seen, and the subtree size
1568  uint64_t nUnique; // number of unique nodes
1569 
1570  T1(): nUnique(0) {}
1571 
1572  VisitAction preVisit(const Node *node) override {
1573  ASSERT_not_null(node);
1574  if (seen.insert(node).second) {
1575  ++nUnique;
1576  return CONTINUE; // this node has not been seen before; traverse into children
1577  } else {
1578  return TRUNCATE; // this node has been seen already; skip over the children
1579  }
1580  }
1581 
1582  VisitAction postVisit(const Node*) override {
1583  return CONTINUE;
1584  }
1585  } visitor;
1586 
1587  VisitAction status = CONTINUE;
1588  for (InputIterator ii=begin; ii!=end && TERMINATE!=status; ++ii)
1589  status = (*ii)->depthFirstTraversal(visitor);
1590  return visitor.nUnique;
1591 }
1592 
1599 std::vector<Ptr> findCommonSubexpressions(const std::vector<Ptr>&);
1600 
1601 template<typename InputIterator>
1602 std::vector<Ptr>
1603 findCommonSubexpressions(InputIterator begin, InputIterator end) {
1605  struct T1: Visitor {
1606  NodeCounts nodeCounts;
1607  std::vector<Ptr> result;
1608 
1609  VisitAction preVisit(const Node *node) override {
1610  ASSERT_not_null(node);
1611  size_t &nSeen = nodeCounts.insertMaybe(node, 0);
1612  if (2 == ++nSeen)
1613  result.push_back(Ptr(const_cast<Node*>(node)));
1614  return nSeen>1 ? TRUNCATE : CONTINUE;
1615  }
1616 
1617  VisitAction postVisit(const Node*) override {
1618  return CONTINUE;
1619  }
1620  } visitor;
1621 
1622  for (InputIterator ii=begin; ii!=end; ++ii)
1623  (*ii)->depthFirstTraversal(visitor);
1624  return visitor.result;
1625 }
1635 template<class Substitution>
1636 Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver = SmtSolverPtr()) {
1637  if (!src)
1638  return Ptr(); // no input implies no output
1639 
1640  // Try substituting the whole expression, returning the result.
1641  Ptr dst = subber(src, solver);
1642  ASSERT_not_null(dst);
1643  if (dst != src)
1644  return dst;
1645 
1646  // Try substituting all the subexpressions.
1647  const Interior *inode = src->isInteriorNodeRaw();
1648  if (!inode)
1649  return src;
1650  bool anyChildChanged = false;
1651  Nodes newChildren;
1652  newChildren.reserve(inode->nChildren());
1653  for (const Ptr &child: inode->children()) {
1654  Ptr newChild = substitute(child, subber, solver);
1655  if (newChild != child)
1656  anyChildChanged = true;
1657  newChildren.push_back(newChild);
1658  }
1659  if (!anyChildChanged)
1660  return src;
1661 
1662  // Some subexpression changed, so build a new expression
1663  return Interior::instance(inode->getOperator(), newChildren, solver, inode->comment(), inode->flags());
1664 }
1665 
1666 } // namespace
1667 
1668 using SymbolicExpressionPtr = SymbolicExpression::Ptr;
1669 
1670 } // namespace
1671 } // namespace
1672 
1673 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
1675 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::SymbolicExpression::Leaf);
1676 BOOST_CLASS_VERSION(Rose::BinaryAnalysis::SymbolicExpression::Type, 1);
1677 BOOST_CLASS_VERSION(Rose::BinaryAnalysis::SymbolicExpression::Node, 1);
1678 #endif
1679 
1680 #endif
1681 #endif
Ptr makeAsr(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
std::vector< Ptr > findCommonSubexpressions(const std::vector< Ptr > &)
Find common subexpressions.
uint64_t nameId() const
Returns the name ID of a free variable.
static const unsigned INDETERMINATE
Value is somehow indeterminate.
static const unsigned UNSPECIFIED
Value is somehow unspecified.
virtual Operator getOperator() const =0
Operator for interior nodes.
Ptr makeConvert(const Ptr &a, const Type &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr()) override
Substitute one value for another.
static LeafPtr createConstant(const Type &, const Sawyer::Container::BitVector &, const std::string &comment="", unsigned flags=0)
Create a constant.
Ordered set of values.
Definition: Set.h:52
Ptr makeLet(const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
void addChild(const Ptr &child)
Appends child as a new child of this node.
bool isFloatingPointVariable() const
True if this expression is a floating-point variable.
Ptr makeMultiplyAdd(const Ptr &a, const Ptr &b, const Ptr &c, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
void printAsSigned(std::ostream &, Formatter &, bool asSigned=true) const
Prints an integer constant interpreted as a signed value.
Hash hash() const
Returns (and caches) the hash value for this node.
LeafPtr isLeafNode() const
Dynamic cast of this object to a leaf node.
Floating-point greater-than or equal.
virtual size_t nChildren() const override
Number of arguments.
virtual VisitAction depthFirstTraversal(Visitor &) const override
Traverse the expression.
bool isFloatingPointConstant() const
True if this epxression is a floating-point constant.
virtual bool isConstant() const =0
True if this expression is a constant.
virtual bool isVariable2() const override
True if this expression is a variable.
virtual Sawyer::Optional< int64_t > toSigned() const override
The signed integer value of the expression.
Ptr makeMul(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Compare two expressions for STL containers.
virtual Sawyer::Optional< uint64_t > toUnsigned() const =0
The unsigned integer value of the expression.
LeafPtr makeConstant(const Type &, const Sawyer::Container::BitVector &, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeIsNeg(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeNegate(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Base class for visiting nodes during expression traversal.
virtual Sawyer::Optional< int64_t > toSigned() const override
The signed integer value of the expression.
Ptr makeSignedMin(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeGt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual uint64_t nNodes() const override
Computes the size of an expression by counting the number of nodes.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
std::string toString() const
Convert expression to string.
Floating-point round to integer as FP type.
virtual size_t nChildren() const override
Number of arguments.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
bool isMemoryExpr() const
True if this expression is of a memory type.
Ptr makeReinterpret(const Ptr &a, const Type &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
void print(std::ostream &, TypeStyle::Flag style=TypeStyle::FULL) const
Print the type.
virtual Node * childRaw(size_t idx) const override
Argument.
Ptr makeSignedMul(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeXor(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool isFloatingPointVariable() const
Is this node a floating-point variable?
void print(std::ostream &o) const
Print the expression to a stream.
const boost::any & userData() const
Property: User-defined data.
InteriorPtr idempotent(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies idempotent operators.
Like CMT_AFTER, but show comments instead of variable names.
Ptr makeIsInfinite(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
bool matchAddVariableConstant(LeafPtr &variable, LeafPtr &constant) const
Determine whether an expression is a variable plus a constant.
static const unsigned BOTTOM
Value represents bottom in dataflow analysis.
LeafPtr makeMemoryVariable(size_t addressWidth, size_t valueWidth, const std::string &comment="", unsigned flags=0)
Leaf constructor.
LeafPtr makeFloatingPointVariable(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Operator
Operators for interior nodes of the expression tree.
Ptr substituteMultiple(const ExprExprHashMap &substitutions, const SmtSolverPtr &solver=SmtSolverPtr())
Rewrite expression by substituting subexpressions.
Ptr makeSignedMod(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeRound(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedGt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedLt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeWrite(const Ptr &mem, const Ptr &addr, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
static LeafPtr createVariable(const Type &, const std::string &comment="", unsigned flags=0)
Create a new variable.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual VisitAction depthFirstTraversal(Visitor &) const override
Traverse the expression.
Ptr substitute(const Ptr &src, Substitution &subber, const SmtSolverPtr &solver=SmtSolverPtr())
On-the-fly substitutions.
size_t max_depth
If non-zero, then replace deep parts of expressions with "...".
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
bool isFloatingPointExpr() const
True if this expression is of a floating-point type.
Base class for symbolic expression nodes.
Hash hashval_
Optional hash used as a quick way to indicate that two expressions are different. ...
Sawyer::SharedPointer< Leaf > LeafPtr
Reference counting pointer.
LeafPtr makeBooleanConstant(bool, const std::string &comment="", unsigned flags=0)
Leaf constructor.
virtual void print(std::ostream &, Formatter &) const =0
Print the expression to a stream.
bool isMemoryVariable() const
Is this node a memory variable?
Ptr simplifyTop(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies the specified interior node.
Small object support.
Definition: SmallObject.h:19
static Type floatingPoint(size_t exponentWidth, size_t significandWidth)
Create a new floating-point type.
static Type integer(size_t nBits)
Create a new integer type.
virtual bool isVariable2() const override
True if this expression is a variable.
virtual const Nodes & children() const override
Arguments.
bool isFloatingPointNan() const
True if this expression is a floating-point NaN constant.
Ptr foldConstants(const Simplifier &)
Perform constant folding.
ShowComments show_comments
Show node comments when printing?
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeGe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool isIntegerConstant() const
True if this expression is an integer constant.
virtual VisitAction depthFirstTraversal(Visitor &) const =0
Traverse the expression.
LeafPtr makeFloatingPointConstant(float, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Main namespace for the ROSE library.
Ptr makeLe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
static const unsigned RESERVED_FLAGS
These flags are reserved for use within ROSE.
bool isScalar() const
Check whether expression is scalar.
bool isIntegerVariable() const
Is this node an integer variable?
InteriorPtr isInteriorNode() const
Dynamic cast of this object to an interior node.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeEq(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool isScalarConstant() const
True if this expression is a scalar constant.
Ptr makeSignedDiv(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr())=0
Returns true if two expressions might be equal, but not necessarily be equal.
void printAsUnsigned(std::ostream &o, Formatter &f) const
Prints an integer constant interpreted as an unsigned value.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions must be equal (cannot be unequal).
bool operator!=(const Type &other) const
Type equality.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions might be equal, but not necessarily be equal.
Ptr makeMod(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeOr(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Interior * isInteriorNodeRaw() const
Dynamic cast of this object to an interior node.
bool isValid() const
Check whether this object is valid.
Ptr identity(uint64_t ident, const SmtSolverPtr &solver=SmtSolverPtr())
Removes identity arguments.
Ptr makeIsPos(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Leaf * isLeafNodeRaw() const
Dynamic cast of this object to a leaf node.
size_t significandWidth() const
Property: Significand width.
Interpret the value as a different type without converting.
Ptr involutary()
Simplifies involutary operators.
bool isMemoryVariable() const
True if this expression is a memory state variable.
SharedPointer< Node > sharedFromThis()
Create a shared pointer from this.
Ptr makeLt(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Operator-specific simplification methods.
TypeClass typeClass() const
Property: Type class.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
WithFormatter operator+(Formatter &fmt)
Combines a node with a formatter for printing.
virtual bool isEquivalentTo(const Ptr &other) override
Tests two expressions for structural equivalence.
virtual void print(std::ostream &, Formatter &) const override
Print the expression to a stream.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr())=0
Returns true if two expressions must be equal (cannot be unequal).
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr()) override
Substitute one value for another.
bool isScalarVariable() const
True if this expression is a scalar variable.
static Type memory(size_t addressWidth, size_t valueWidth)
Create a new memory type.
Ptr makeSignedMax(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Shift right, introducing zeros at msb.
virtual int compareStructure(const Ptr &other)=0
Compare two expressions structurally for sorting.
Ptr makeMax(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
void userData(boost::any &data)
Property: User-defined data.
virtual Sawyer::Optional< int64_t > toSigned() const =0
The signed integer value of the expression.
Ptr renameVariables(ExprExprHashMap &index, size_t &nextVariableId, const SmtSolverPtr &solver=SmtSolverPtr())
Rewrite using lowest numbered variable names.
virtual uint64_t nNodes() const override
Computes the size of an expression by counting the number of nodes.
bool show_flags
Show user-defined flags inside square brackets.
Ptr makeConcat(const Ptr &hi, const Ptr &lo, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeIsNan(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
size_t exponentWidth() const
Property: Exponent width.
Ptr makeInvert(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
static boost::logic::tribool(* mayEqualCallback)(const Ptr &a, const Ptr &b, const SmtSolverPtr &)
User-supplied predicate to augment alias checking.
size_t nBits() const
Property: Total width of values.
void assertAcyclic() const
Asserts that expressions are acyclic.
Ptr makeSqrt(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Like CMT_INSTEAD, but show the name as a comment.
static Ptr instance(Operator op, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Create a new expression node.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Creates SharedPointer from this.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual bool isConstant() const override
True if this expression is a constant.
Write (update) memory with a new value.
virtual uint64_t nNodes() const =0
Computes the size of an expression by counting the number of nodes.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
LeafPtr makeIntegerVariable(size_t nBits, const std::string &comment="", unsigned flags=0)
Leaf constructor.
InteriorPtr commutative()
Simplifies commutative operators by sorting arguments.
virtual void print(std::ostream &, Formatter &) const override
Print the expression to a stream.
Ptr newFlags(unsigned flags) const
Sets flags.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Flag
Flag to pass as type stringification style.
std::set< LeafPtr > getVariables() const
Returns the variables appearing in the expression.
Ptr makeIsSignedPos(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual int compareStructure(const Ptr &other) override
Compare two expressions structurally for sorting.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual bool isVariable2() const =0
True if this expression is a variable.
Ptr makeSignedLe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool isIntegerExpr() const
True if this expression is of an integer type.
Shift left, introducing ones at lsb.
virtual size_t nChildren() const =0
Number of arguments.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
void adjustWidth(const Type &)
Adjust width based on operands.
InteriorPtr associative()
Simplifies non-associative operators by flattening the specified interior node with its children that...
Ptr makeLssb(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
size_t nBits() const
Property: Number of significant bits.
Ptr makeSet(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool isHashed() const
Returns true if this node has a hash value computed and cached.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const
Constant folding.
virtual bool mayEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions might be equal, but not necessarily be equal.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual bool isEquivalentTo(const Ptr &other)=0
Tests two expressions for structural equivalence.
virtual const Ptr & child(size_t idx) const override
Argument.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
uint64_t Hash
Hash of symbolic expression.
virtual bool mustEqual(const Ptr &other, const SmtSolverPtr &solver=SmtSolverPtr()) override
Returns true if two expressions must be equal (cannot be unequal).
bool isFloatingPointNan() const
Is this node a floating-point NaN constant?
const uint64_t MAX_NNODES
Maximum number of nodes that can be reported.
bool serializeVariableIds
Whether to serialize variable IDs.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual bool isConstant() const override
True if this expression is a constant.
Ptr makeSignExtend(const Ptr &newSize, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual const Node * childRaw(size_t) const override
Argument.
Ptr rewrite(const Simplifier &simplifier, const SmtSolverPtr &solver=SmtSolverPtr())
Simplify an interior node.
Ptr makeRol(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool use_hexadecimal
Show values in hexadecimal and decimal rather than just decimal.
Ptr makeMssb(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual int compareStructure(const Ptr &other) override
Compare two expressions structurally for sorting.
bool add_renames
Add additional entries to the renames as variables are encountered?
Ptr makeZerop(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Operator getOperator() const override
Operator for interior nodes.
virtual Ptr substitute(const Ptr &from, const Ptr &to, const SmtSolverPtr &solver=SmtSolverPtr())=0
Substitute one value for another.
WithFormatter withFormat(Formatter &fmt)
Combines a node with a formatter for printing.
LeafPtr makeIntegerConstant(size_t nBits, uint64_t value, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Ptr makeIsSubnorm(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool do_rename
Use the renames map to rename variables to shorter names?
boost::any userData_
Additional user-specified data.
Base class for reference counted objects.
Definition: SharedObject.h:64
virtual const Node * childRaw(size_t idx) const =0
Argument.
Ptr makeIte(const Ptr &cond, const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShr1(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const
Rewrite the entire expression to something simpler.
Ptr unaryNoOp()
Replaces a binary operator with its only argument.
virtual const Ptr & child(size_t idx) const =0
Argument.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
virtual Sawyer::Optional< uint64_t > toUnsigned() const override
The unsigned integer value of the expression.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
void comment(const std::string &s)
Property: Comment.
Ptr setToIte(const Ptr &, const SmtSolverPtr &solver=SmtSolverPtr(), const LeafPtr &var=LeafPtr())
Convert a set to an ite expression.
InteriorPtr isOperator(Operator) const
True (non-null) if this node is the specified operator.
Controls formatting of expression trees when printing.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
Ptr makeShl1(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeShl0(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Sawyer::Optional< uint64_t > toUnsigned() const override
The unsigned integer value of the expression.
uint64_t nNodesUnique() const
Number of unique nodes in expression.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
Leaf node of an expression tree for instruction semantics.
const std::string & comment() const
Property: Comment.
Ptr makeRor(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeExtend(const Ptr &newSize, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
bool show_type
Show data type inside square brackets.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeIsNorm(const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
LeafPtr makeVariable(const Type &, const std::string &comment="", unsigned flags=0)
Leaf constructor.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeShr0(const Ptr &sa, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
For a pre-order depth-first visit, do not descend into children.
virtual const Nodes & children() const override
Arguments.
LeafPtr makeFloatingPointNan(size_t eb, size_t sb, const std::string &comment="", unsigned flags=0)
Leaf constructor.
Interior node of an expression tree for instruction semantics.
bool isEmpty() const
Determines if the vector is empty.
Definition: BitVector.h:184
bool isScalarExpr() const
True if the expression is a scalar type.
virtual bool isEquivalentTo(const Ptr &other) override
Tests two expressions for structural equivalence.
API and storage for attributes.
Definition: Attribute.h:215
Ptr poisonNan(const SmtSolverPtr &solver=SmtSolverPtr())
Returns NaN if any argument is NaN.
std::string toString(TypeStyle::Flag style=TypeStyle::FULL) const
Print the type to a string.
Ptr makeExtract(const Ptr &begin, const Ptr &end, const Ptr &a, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeSignedGe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Ptr makeDiv(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Represents no value.
Definition: Optional.h:32
Shift right, introducing ones at msb.
Shift left, introducing zeros at lsb.
virtual Ptr fold(Nodes::const_iterator, Nodes::const_iterator) const override
Constant folding.
Ptr makeAnd(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
Sawyer::Container::Set< Ptr, ExpressionLessp > ExpressionSet
Set of expressions ordered by hash.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr additiveNesting(const SmtSolverPtr &solver=SmtSolverPtr())
Simplifies nested shift-like operators.
Base class for all ROSE exceptions.
Definition: Rose/Exception.h:9
virtual Operator getOperator() const override
Operator for interior nodes.
void adjustBitFlags(unsigned extraFlags)
Adjust user-defined bit flags.
std::vector< Ptr > findCommonSubexpressions() const
Find common subexpressions.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
Ptr makeAdd(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
virtual const Nodes & children() const =0
Arguments.
uint64_t nNodes(InputIterator begin, InputIterator end)
Counts the number of nodes.
virtual const Ptr & child(size_t idx) const override
Argument.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
virtual Ptr rewrite(Interior *, const SmtSolverPtr &) const override
Rewrite the entire expression to something simpler.
unsigned flags() const
Property: User-defined bit flags.
bool operator<(const Type &other) const
Type comparison.
Ptr makeMin(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
size_t addressWidth() const
Property: Width of memory addresses.
Ptr makeNe(const Ptr &a, const Ptr &b, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
bool isIntegerVariable() const
True if this expression is an integer variable.
std::string toString() const
Returns a string for the leaf.
const Sawyer::Container::BitVector & bits() const
Property: Bits stored for numeric constants.
Container associating values with keys.
Definition: Sawyer/Map.h:66
Ptr makeRead(const Ptr &mem, const Ptr &addr, const SmtSolverPtr &solver=SmtSolverPtr(), const std::string &comment="", unsigned flags=0)
Interior node constructor.
uint64_t nNodesUnique(InputIterator begin, InputIterator end)
Counts the number of unique nodes.
RenameMap renames
Map for renaming variables to use smaller integers.
Hash hash(const std::vector< Ptr > &)
Hash zero or more expressions.
Sawyer::Optional< uint64_t > variableId() const
Variable ID number.
bool operator==(const Type &other) const
Type equality.
size_t domainWidth() const
Property: Width for memory expressions.