[PATCH] D15910: Make isa, cast, dyn_cast, etc. work with std::unique_ptr and std::shared_ptr.

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 13 22:47:17 PST 2016


Justin Lebar via llvm-commits <llvm-commits at lists.llvm.org> writes:
> jlebar created this revision.
> jlebar added a reviewer: echristo.
> jlebar added a subscriber: llvm-commits.
>
> This lets us use these functions without calling 'get()' everywhere.

Making this work for isa<> is really nice, but I'm kind of uncomfortable
witht the subtlety it adds to cast/dyn_cast/dyn_cast_or_null wrt
unique_ptr. I worry about accidentally escaping (and then capturing) the
raw pointer via a type cast.

> http://reviews.llvm.org/D15910
>
> Files:
>   include/llvm/Support/Casting.h
>   unittests/Support/Casting.cpp
>
> Index: unittests/Support/Casting.cpp
> ===================================================================
> --- unittests/Support/Casting.cpp
> +++ unittests/Support/Casting.cpp
> @@ -165,6 +165,26 @@
>    EXPECT_NE(F5, null_foo);
>  }
>  
> +// We should be able to treat unique_ptr<T> just like T* for the purposes of
> +// isa, dyn_cast, cast, etc.
> +TEST(CastingTest, unique_ptr) {
> +  std::unique_ptr<foo> a(new foo());
> +  EXPECT_TRUE(isa<foo>(a));
> +
> +  std::unique_ptr<bar> b(new bar());
> +  EXPECT_NE(dyn_cast_or_null<foo>(b), null_foo);
> +}
> +
> +// We should be able to treat shared_ptr<T> just like T* for the purposes of
> +// isa, dyn_cast, cast, etc.
> +TEST(CastingTest, shared_ptr) {
> +  auto a = std::make_shared<foo>();
> +  EXPECT_TRUE(isa<foo>(a));
> +
> +  auto b = std::make_shared<bar>();
> +  EXPECT_NE(dyn_cast_or_null<foo>(b), null_foo);
> +}
> +
>  // These lines are errors...
>  //foo *F20 = cast<foo>(B2);  // Yields const foo*
>  //foo &F21 = cast<foo>(B3);  // Yields const foo&
> Index: include/llvm/Support/Casting.h
> ===================================================================
> --- include/llvm/Support/Casting.h
> +++ include/llvm/Support/Casting.h
> @@ -18,6 +18,7 @@
>  #include "llvm/Support/Compiler.h"
>  #include "llvm/Support/type_traits.h"
>  #include <cassert>
> +#include <memory>
>  
>  namespace llvm {
>  
> @@ -47,6 +48,30 @@
>    }
>  };
>  
> +template<class T> struct simplify_type<std::unique_ptr<T>> {
> +  typedef T* SimpleType;
> +  static SimpleType getSimplifiedValue(std::unique_ptr<T> &Val) { return Val.get(); }
> +};
> +
> +template<class T> struct simplify_type<const std::unique_ptr<T>> {
> +  typedef /*const*/ T* SimpleType;
> +  static SimpleType getSimplifiedValue(const std::unique_ptr<T> &Val) {
> +    return Val.get();
> +  }
> +};
> +
> +template<class T> struct simplify_type<std::shared_ptr<T>> {
> +  typedef T* SimpleType;
> +  static SimpleType getSimplifiedValue(std::shared_ptr<T> &Val) { return Val.get(); }
> +};
> +
> +template<class T> struct simplify_type<const std::shared_ptr<T>> {
> +  typedef /*const*/ T* SimpleType;
> +  static SimpleType getSimplifiedValue(const std::shared_ptr<T> &Val) {
> +    return Val.get();
> +  }
> +};
> +
>  // The core of the implementation of isa<X> is here; To and From should be
>  // the names of classes.  This template can be specialized to customize the
>  // implementation of isa<> without rewriting it from scratch.
>


More information about the llvm-commits mailing list