mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
Support: Add *cast_or_null<> for pointer wrappers
Fill in omission of `cast_or_null<>` and `dyn_cast_or_null<>` for types that wrap pointers (e.g., smart pointers). Type traits need to be slightly stricter than for `cast<>` and `dyn_cast<>` to resolve ambiguities with simple types. There didn't seem to be any unit tests for pointer wrappers, so I tested `isa<>`, `cast<>`, and `dyn_cast<>` while I was in there. This only supports pointer wrappers with a conversion to `bool` to check for null. If in the future it's useful to support wrappers without such a conversion, it should be a straightforward incremental step to use the `simplify_type` machinery for the null check. In that case, the unit tests should be updated to remove the `operator bool()` from the `pointer_wrappers::PTy`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222644 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -232,3 +232,99 @@ namespace TemporaryCast {
|
||||
struct pod {};
|
||||
IllegalCast *testIllegalCast() { return cast<foo>(pod()); }
|
||||
}
|
||||
|
||||
namespace {
|
||||
namespace pointer_wrappers {
|
||||
|
||||
struct Base {
|
||||
bool IsDerived;
|
||||
Base(bool IsDerived = false) : IsDerived(IsDerived) {}
|
||||
};
|
||||
|
||||
struct Derived : Base {
|
||||
Derived() : Base(true) {}
|
||||
static bool classof(const Base *B) { return B->IsDerived; }
|
||||
};
|
||||
|
||||
class PTy {
|
||||
Base *B;
|
||||
public:
|
||||
PTy(Base *B) : B(B) {}
|
||||
LLVM_EXPLICIT operator bool() const { return get(); }
|
||||
Base *get() const { return B; }
|
||||
};
|
||||
|
||||
} // end namespace pointer_wrappers
|
||||
} // end namespace
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <> struct simplify_type<pointer_wrappers::PTy> {
|
||||
typedef pointer_wrappers::Base *SimpleType;
|
||||
static SimpleType getSimplifiedValue(pointer_wrappers::PTy &P) {
|
||||
return P.get();
|
||||
}
|
||||
};
|
||||
template <> struct simplify_type<const pointer_wrappers::PTy> {
|
||||
typedef pointer_wrappers::Base *SimpleType;
|
||||
static SimpleType getSimplifiedValue(const pointer_wrappers::PTy &P) {
|
||||
return P.get();
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
namespace pointer_wrappers {
|
||||
|
||||
// Some objects.
|
||||
pointer_wrappers::Base B;
|
||||
pointer_wrappers::Derived D;
|
||||
|
||||
// Mutable "smart" pointers.
|
||||
pointer_wrappers::PTy MN(nullptr);
|
||||
pointer_wrappers::PTy MB(&B);
|
||||
pointer_wrappers::PTy MD(&D);
|
||||
|
||||
// Const "smart" pointers.
|
||||
const pointer_wrappers::PTy CN(nullptr);
|
||||
const pointer_wrappers::PTy CB(&B);
|
||||
const pointer_wrappers::PTy CD(&D);
|
||||
|
||||
TEST(CastingTest, smart_isa) {
|
||||
EXPECT_TRUE(!isa<pointer_wrappers::Derived>(MB));
|
||||
EXPECT_TRUE(!isa<pointer_wrappers::Derived>(CB));
|
||||
EXPECT_TRUE(isa<pointer_wrappers::Derived>(MD));
|
||||
EXPECT_TRUE(isa<pointer_wrappers::Derived>(CD));
|
||||
}
|
||||
|
||||
TEST(CastingTest, smart_cast) {
|
||||
EXPECT_TRUE(cast<pointer_wrappers::Derived>(MD) == &D);
|
||||
EXPECT_TRUE(cast<pointer_wrappers::Derived>(CD) == &D);
|
||||
}
|
||||
|
||||
TEST(CastingTest, smart_cast_or_null) {
|
||||
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
|
||||
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
|
||||
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(MD) == &D);
|
||||
EXPECT_TRUE(cast_or_null<pointer_wrappers::Derived>(CD) == &D);
|
||||
}
|
||||
|
||||
TEST(CastingTest, smart_dyn_cast) {
|
||||
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MB) == nullptr);
|
||||
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CB) == nullptr);
|
||||
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(MD) == &D);
|
||||
EXPECT_TRUE(dyn_cast<pointer_wrappers::Derived>(CD) == &D);
|
||||
}
|
||||
|
||||
TEST(CastingTest, smart_dyn_cast_or_null) {
|
||||
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MN) == nullptr);
|
||||
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CN) == nullptr);
|
||||
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MB) == nullptr);
|
||||
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CB) == nullptr);
|
||||
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(MD) == &D);
|
||||
EXPECT_TRUE(dyn_cast_or_null<pointer_wrappers::Derived>(CD) == &D);
|
||||
}
|
||||
|
||||
} // end namespace pointer_wrappers
|
||||
} // end namespace
|
||||
|
Reference in New Issue
Block a user