about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-06-04 02:53:24 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-06-04 02:53:24 +0000
commit83cfc5db5e014a04247d8e496524bb6f43e10617 (patch)
tree864dedf161857329846f959ff76042e9932b74c1
parentaf7594521cd133d438ac494716798d04bcc52b6e (diff)
downloadklee-83cfc5db5e014a04247d8e496524bb6f43e10617.tar.gz
Implement simplify_type for ref<>
 - This allows dyn_cast<> and friends to be applied to a ref. For example,
     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(foo)) {
       ... do something with CE ...
     }

 - This makes working with ref<Expr>s much more convenient, with the downside
   that it hides a potentially dangerous operation. Since the result is not
   itself a ref<>; clients are resposible for making sure the returned value is
   only used inside the lifetime of some other ref<>.


git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@72839 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/klee/util/Ref.h21
1 files changed, 20 insertions, 1 deletions
diff --git a/include/klee/util/Ref.h b/include/klee/util/Ref.h
index 39598b16..b56d5d6a 100644
--- a/include/klee/util/Ref.h
+++ b/include/klee/util/Ref.h
@@ -115,7 +115,6 @@ public:
   bool operator!=(const ref &rhs) const { return compare(rhs)!=0; }
 };
 
-
 template<class T>
 inline std::ostream &operator<<(std::ostream &os, const ref<T> &e) {
   os << *e;
@@ -144,6 +143,26 @@ const U* static_ref_cast(const ref<Expr> &src) {
   return static_cast<const U*>(src.ptr);
 }
 
+} // end namespace klee
+
+namespace llvm {
+  // simplify_type implementation for ref<>, which allows dyn_cast from on a
+  // ref<> to apply to the wrapper type. Conceptually the result of such a
+  // dyn_cast should probably be a ref of the casted type, but that breaks the
+  // idiom of initializing a variable to the result of a dyn_cast inside an if
+  // condition, or we would have to implement operator(bool) for ref<> with
+  // isNull semantics, which doesn't seem like a good idea.
+template<typename T>
+struct simplify_type<const ::klee::ref<T> > {
+  typedef T* SimpleType;
+  static SimpleType getSimplifiedValue(const ::klee::ref<T> &Ref) {
+    return Ref.get();
+  }
+};
+
+template<typename T> 
+struct simplify_type< ::klee::ref<T> >
+  : public simplify_type<const ::klee::ref<T> > {};
 }
 
 #endif /* KLEE_REF_H */