ExprUtil.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "klee/util/ExprUtil.h"
00011 #include "klee/util/ExprHashMap.h"
00012
00013 #include "klee/Expr.h"
00014
00015 #include "klee/util/ExprVisitor.h"
00016
00017 #include <set>
00018
00019 using namespace klee;
00020
00021 void klee::findReads(ref<Expr> e,
00022 bool visitUpdates,
00023 std::vector< ref<ReadExpr> > &results) {
00024
00025 std::vector< ref<Expr> > stack;
00026 ExprHashSet visited;
00027 std::set<const UpdateNode *> updates;
00028
00029 if (!isa<ConstantExpr>(e)) {
00030 visited.insert(e);
00031 stack.push_back(e);
00032 }
00033
00034 while (!stack.empty()) {
00035 ref<Expr> top = stack.back();
00036 stack.pop_back();
00037
00038 if (ReadExpr *re = dyn_cast<ReadExpr>(top)) {
00039
00040
00041 results.push_back(re);
00042
00043 if (!isa<ConstantExpr>(re->index) &&
00044 visited.insert(re->index).second)
00045 stack.push_back(re->index);
00046
00047 if (visitUpdates) {
00048
00049
00050
00051
00052
00053
00054 if (updates.insert(re->updates.head).second) {
00055 for (const UpdateNode *un=re->updates.head; un; un=un->next) {
00056 if (!isa<ConstantExpr>(un->index) &&
00057 visited.insert(un->index).second)
00058 stack.push_back(un->index);
00059 if (!isa<ConstantExpr>(un->value) &&
00060 visited.insert(un->value).second)
00061 stack.push_back(un->value);
00062 }
00063 }
00064 }
00065 } else if (!isa<ConstantExpr>(top)) {
00066 Expr *e = top.get();
00067 for (unsigned i=0; i<e->getNumKids(); i++) {
00068 ref<Expr> k = e->getKid(i);
00069 if (!isa<ConstantExpr>(k) &&
00070 visited.insert(k).second)
00071 stack.push_back(k);
00072 }
00073 }
00074 }
00075 }
00076
00078
00079 namespace klee {
00080
00081 class SymbolicObjectFinder : public ExprVisitor {
00082 protected:
00083 Action visitRead(const ReadExpr &re) {
00084 const UpdateList &ul = re.updates;
00085
00086
00087 for (const UpdateNode *un=ul.head; un; un=un->next) {
00088 visit(un->index);
00089 visit(un->value);
00090 }
00091
00092 if (ul.isRooted)
00093 if (results.insert(ul.root).second)
00094 objects.push_back(ul.root);
00095
00096 return Action::doChildren();
00097 }
00098
00099 public:
00100 std::set<const Array*> results;
00101 std::vector<const Array*> &objects;
00102
00103 SymbolicObjectFinder(std::vector<const Array*> &_objects)
00104 : objects(_objects) {}
00105 };
00106
00107 }
00108
00109 template<typename InputIterator>
00110 void klee::findSymbolicObjects(InputIterator begin,
00111 InputIterator end,
00112 std::vector<const Array*> &results) {
00113 SymbolicObjectFinder of(results);
00114 for (; begin!=end; ++begin)
00115 of.visit(*begin);
00116 }
00117
00118 void klee::findSymbolicObjects(ref<Expr> e,
00119 std::vector<const Array*> &results) {
00120 findSymbolicObjects(&e, &e+1, results);
00121 }
00122
00123 typedef std::vector< ref<Expr> >::iterator A;
00124 template void klee::findSymbolicObjects<A>(A, A, std::vector<const Array*> &);
00125
00126 typedef std::set< ref<Expr> >::iterator B;
00127 template void klee::findSymbolicObjects<B>(B, B, std::vector<const Array*> &);