diff --git a/llvm/include/llvm/ADT/PointerUnion.h b/llvm/include/llvm/ADT/PointerUnion.h --- a/llvm/include/llvm/ADT/PointerUnion.h +++ b/llvm/include/llvm/ADT/PointerUnion.h @@ -160,7 +160,7 @@ /// Returns the current pointer if it is of the specified pointer type, /// otherwise returns null. template inline T dyn_cast() const { - return llvm::dyn_cast(*this); + return llvm::dyn_cast_if_present(*this); } /// If the union is set to the first pointer type get an address pointing to diff --git a/llvm/include/llvm/Support/Casting.h b/llvm/include/llvm/Support/Casting.h --- a/llvm/include/llvm/Support/Casting.h +++ b/llvm/include/llvm/Support/Casting.h @@ -585,47 +585,18 @@ return CastInfo>::doCast(std::move(Val)); } -/// dyn_cast - Return the argument parameter cast to the specified type. This -/// casting operator returns null if the argument is of the wrong type, so it -/// can be used to test for a type as well as cast if successful. The value -/// passed in must be present, if not, use dyn_cast_if_present. This should be -/// used in the context of an if statement like this: -/// -/// if (const Instruction *I = dyn_cast(myVal)) { ... } - -template -[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) { - return CastInfo::doCastIfPossible(Val); -} - -template -[[nodiscard]] inline decltype(auto) dyn_cast(From &Val) { - return CastInfo::doCastIfPossible(Val); -} - -template -[[nodiscard]] inline decltype(auto) dyn_cast(From *Val) { - return CastInfo::doCastIfPossible(Val); -} - -template -[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr &&Val) { - return CastInfo>::doCastIfPossible(std::move(Val)); -} - //===----------------------------------------------------------------------===// // ValueIsPresent //===----------------------------------------------------------------------===// template -constexpr bool IsNullable = std::is_pointer::value || - std::is_constructible::value; +constexpr bool IsNullable = + std::is_pointer_v || std::is_constructible_v; /// ValueIsPresent provides a way to check if a value is, well, present. For -/// pointers, this is the equivalent of checking against nullptr, for -/// Optionals this is the equivalent of checking hasValue(). It also -/// provides a method for unwrapping a value (think dereferencing a -/// pointer). +/// pointers, this is the equivalent of checking against nullptr, for Optionals +/// this is the equivalent of checking hasValue(). It also provides a method for +/// unwrapping a value (think calling .value() on an optional). // Generic values can't *not* be present. template struct ValueIsPresent { @@ -646,7 +617,7 @@ template struct ValueIsPresent>> { using UnwrappedType = T; - static inline bool isPresent(const T &t) { return t != nullptr; } + static inline bool isPresent(const T &t) { return t != T(nullptr); } static inline decltype(auto) unwrapValue(T &t) { return t; } }; @@ -664,6 +635,39 @@ } } // namespace detail +/// dyn_cast - Return the argument parameter cast to the specified type. This +/// casting operator returns null if the argument is of the wrong type, so it +/// can be used to test for a type as well as cast if successful. The value +/// passed in must be present, if not, use dyn_cast_if_present. This should be +/// used in the context of an if statement like this: +/// +/// if (const Instruction *I = dyn_cast(myVal)) { ... } + +template +[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo::doCastIfPossible(Val); +} + +template +[[nodiscard]] inline decltype(auto) dyn_cast(From &Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo::doCastIfPossible(Val); +} + +template +[[nodiscard]] inline decltype(auto) dyn_cast(From *Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo::doCastIfPossible(Val); +} + +template +[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr &&Val) { + assert(detail::isPresent(Val) && "dyn_cast on a non-existent value"); + return CastInfo>::doCastIfPossible( + std::forward &&>(Val)); +} + /// isa_and_present - Functionally identical to isa, except that a null value /// is accepted. template diff --git a/llvm/unittests/ADT/PointerUnionTest.cpp b/llvm/unittests/ADT/PointerUnionTest.cpp --- a/llvm/unittests/ADT/PointerUnionTest.cpp +++ b/llvm/unittests/ADT/PointerUnionTest.cpp @@ -227,8 +227,8 @@ EXPECT_EQ(dyn_cast(b), nullptr); EXPECT_EQ(dyn_cast(c), &i); EXPECT_EQ(dyn_cast(c), nullptr); - EXPECT_EQ(dyn_cast(n), nullptr); - EXPECT_EQ(dyn_cast(n), nullptr); + EXPECT_EQ(dyn_cast_if_present(n), nullptr); + EXPECT_EQ(dyn_cast_if_present(n), nullptr); EXPECT_EQ(dyn_cast(i3), &i); EXPECT_EQ(dyn_cast(i3), nullptr); EXPECT_EQ(dyn_cast(i3), nullptr); @@ -254,22 +254,22 @@ EXPECT_EQ(dyn_cast(d4), nullptr); EXPECT_EQ(dyn_cast(d4), nullptr); EXPECT_EQ(dyn_cast(d4), &d); - EXPECT_EQ(dyn_cast(i4null), nullptr); - EXPECT_EQ(dyn_cast(i4null), nullptr); - EXPECT_EQ(dyn_cast(i4null), nullptr); - EXPECT_EQ(dyn_cast(i4null), nullptr); - EXPECT_EQ(dyn_cast(f4null), nullptr); - EXPECT_EQ(dyn_cast(f4null), nullptr); - EXPECT_EQ(dyn_cast(f4null), nullptr); - EXPECT_EQ(dyn_cast(f4null), nullptr); - EXPECT_EQ(dyn_cast(l4null), nullptr); - EXPECT_EQ(dyn_cast(l4null), nullptr); - EXPECT_EQ(dyn_cast(l4null), nullptr); - EXPECT_EQ(dyn_cast(l4null), nullptr); - EXPECT_EQ(dyn_cast(d4null), nullptr); - EXPECT_EQ(dyn_cast(d4null), nullptr); - EXPECT_EQ(dyn_cast(d4null), nullptr); - EXPECT_EQ(dyn_cast(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(i4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(f4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(l4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); + EXPECT_EQ(dyn_cast_if_present(d4null), nullptr); // test for const const PU4 constd4(&d);