Index: llvm/include/llvm/Support/Casting.h =================================================================== --- llvm/include/llvm/Support/Casting.h +++ llvm/include/llvm/Support/Casting.h @@ -18,6 +18,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" #include +#include namespace llvm { @@ -161,6 +162,17 @@ typedef const To* ret_type; // Constant pointer arg case, return const Ty* }; +struct bar; + +template +struct cast_retty_impl> { +private: + typedef typename cast_retty_impl::ret_type PointerType; + typedef typename std::remove_pointer::type ResultType; + +public: + typedef std::unique_ptr ret_type; +}; template struct cast_retty_wrap { @@ -298,6 +310,15 @@ return isa(Val) ? cast(Val) : nullptr; } +template +LLVM_NODISCARD inline typename cast_retty>::ret_type +dyn_cast(std::unique_ptr &Val) { + if (!isa(Val.get())) + return nullptr; + typedef typename cast_retty>::ret_type ret_type; + return ret_type(cast(Val.release())); +} + // dyn_cast_or_null - Functionally identical to dyn_cast, except that a null // value is accepted. // @@ -323,6 +344,14 @@ return (Val && isa(Val)) ? cast(Val) : nullptr; } +template +LLVM_NODISCARD inline typename cast_retty>::ret_type +dyn_cast_or_null(std::unique_ptr &Val) { + if (!Val) + return nullptr; + return dyn_cast(Val); +} + } // End llvm namespace #endif Index: llvm/unittests/Support/Casting.cpp =================================================================== --- llvm/unittests/Support/Casting.cpp +++ llvm/unittests/Support/Casting.cpp @@ -150,6 +150,11 @@ // EXPECT_EQ(F4, null_foo); foo *F5 = B1.daz(); EXPECT_NE(F5, null_foo); + + std::unique_ptr BP(B2); + std::unique_ptr FP = dyn_cast(BP); + EXPECT_NE(FP.get(), null_foo); + FP.release(); } TEST(CastingTest, dyn_cast_or_null) { @@ -163,6 +168,10 @@ EXPECT_EQ(F4, null_foo); foo *F5 = B1.naz(); EXPECT_NE(F5, null_foo); + + std::unique_ptr BP(fub()); + std::unique_ptr FP = dyn_cast_or_null(BP); + EXPECT_EQ(FP.get(), null_foo); } // These lines are errors...