blob: 01583e43e29b472ff2dfb4cd35737b9f1449a507 [file] [log] [blame]
Gabor Greifb3c90d92010-07-20 19:35:55 +00001//===---------- llvm/unittest/Support/Casting.cpp - Casting tests ---------===//
Gabor Greifee57dae2010-07-20 16:32:20 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Gabor Greifee57dae2010-07-20 16:32:20 +000010#include "llvm/Support/Casting.h"
Gabor Greifb3c90d92010-07-20 19:35:55 +000011#include "llvm/Support/Debug.h"
12#include "llvm/Support/raw_ostream.h"
Gabor Greifee57dae2010-07-20 16:32:20 +000013#include "gtest/gtest.h"
14#include <cstdlib>
15
Gabor Greife8950972010-07-20 17:06:28 +000016namespace llvm {
17
18// set up two example classes
19// with conversion facility
20//
21struct bar {
22 bar() {}
Gabor Greifd1594672010-07-22 15:24:48 +000023 struct foo *baz();
24 struct foo *caz();
Gabor Greiff06eb372010-07-22 15:37:20 +000025 struct foo *daz();
26 struct foo *naz();
Gabor Greife8950972010-07-20 17:06:28 +000027private:
28 bar(const bar &);
29};
30struct foo {
31 void ext() const;
32 /* static bool classof(const bar *X) {
33 cerr << "Classof: " << X << "\n";
34 return true;
35 }*/
36};
37
Gabor Greiff06eb372010-07-22 15:37:20 +000038template <> struct isa_impl<foo, bar> {
Gabor Greife8950972010-07-20 17:06:28 +000039 static inline bool doit(const bar &Val) {
40 dbgs() << "Classof: " << &Val << "\n";
41 return true;
42 }
43};
44
Gabor Greifd1594672010-07-22 15:24:48 +000045foo *bar::baz() {
Gabor Greife8950972010-07-20 17:06:28 +000046 return cast<foo>(this);
Gabor Greifd1594672010-07-22 15:24:48 +000047}
48
49foo *bar::caz() {
50 return cast_or_null<foo>(this);
51}
52
Gabor Greiff06eb372010-07-22 15:37:20 +000053foo *bar::daz() {
Gabor Greifd1594672010-07-22 15:24:48 +000054 return dyn_cast<foo>(this);
Gabor Greiff06eb372010-07-22 15:37:20 +000055}
56
57foo *bar::naz() {
58 return dyn_cast_or_null<foo>(this);
59}
Gabor Greife8950972010-07-20 17:06:28 +000060
61
62bar *fub();
63} // End llvm namespace
64
Gabor Greifee57dae2010-07-20 16:32:20 +000065using namespace llvm;
66
67namespace {
68
Gabor Greif08993c02010-07-20 16:51:18 +000069const foo *null_foo = NULL;
70
NAKAMURA Takumi2a535772012-01-22 12:14:35 +000071bar B;
Gabor Greifee57dae2010-07-20 16:32:20 +000072extern bar &B1;
NAKAMURA Takumi2a535772012-01-22 12:14:35 +000073bar &B1 = B;
Gabor Greifee57dae2010-07-20 16:32:20 +000074extern const bar *B2;
Gabor Greif08993c02010-07-20 16:51:18 +000075// test various configurations of const
76const bar &B3 = B1;
77const bar *const B4 = B2;
Gabor Greifee57dae2010-07-20 16:32:20 +000078
Gabor Greifaf8e2ef2010-07-20 16:38:12 +000079TEST(CastingTest, isa) {
Gabor Greifee57dae2010-07-20 16:32:20 +000080 EXPECT_TRUE(isa<foo>(B1));
Gabor Greifaf8e2ef2010-07-20 16:38:12 +000081 EXPECT_TRUE(isa<foo>(B2));
82 EXPECT_TRUE(isa<foo>(B3));
83 EXPECT_TRUE(isa<foo>(B4));
Gabor Greifee57dae2010-07-20 16:32:20 +000084}
85
Gabor Greif08993c02010-07-20 16:51:18 +000086TEST(CastingTest, cast) {
87 foo &F1 = cast<foo>(B1);
88 EXPECT_NE(&F1, null_foo);
89 const foo *F3 = cast<foo>(B2);
90 EXPECT_NE(F3, null_foo);
91 const foo *F4 = cast<foo>(B2);
92 EXPECT_NE(F4, null_foo);
Gabor Greife8950972010-07-20 17:06:28 +000093 const foo &F5 = cast<foo>(B3);
94 EXPECT_NE(&F5, null_foo);
95 const foo *F6 = cast<foo>(B4);
96 EXPECT_NE(F6, null_foo);
Richard Smith79b59a22012-08-21 20:39:25 +000097 // Can't pass null pointer to cast<>.
98 // foo *F7 = cast<foo>(fub());
99 // EXPECT_EQ(F7, null_foo);
Gabor Greifd1594672010-07-22 15:24:48 +0000100 foo *F8 = B1.baz();
101 EXPECT_NE(F8, null_foo);
Gabor Greif08993c02010-07-20 16:51:18 +0000102}
103
104TEST(CastingTest, cast_or_null) {
105 const foo *F11 = cast_or_null<foo>(B2);
106 EXPECT_NE(F11, null_foo);
107 const foo *F12 = cast_or_null<foo>(B2);
108 EXPECT_NE(F12, null_foo);
109 const foo *F13 = cast_or_null<foo>(B4);
110 EXPECT_NE(F13, null_foo);
111 const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
112 EXPECT_EQ(F14, null_foo);
Gabor Greifd1594672010-07-22 15:24:48 +0000113 foo *F15 = B1.caz();
114 EXPECT_NE(F15, null_foo);
115}
116
117TEST(CastingTest, dyn_cast) {
Gabor Greif46a35012010-07-22 15:28:30 +0000118 const foo *F1 = dyn_cast<foo>(B2);
119 EXPECT_NE(F1, null_foo);
120 const foo *F2 = dyn_cast<foo>(B2);
121 EXPECT_NE(F2, null_foo);
122 const foo *F3 = dyn_cast<foo>(B4);
Gabor Greifd1594672010-07-22 15:24:48 +0000123 EXPECT_NE(F3, null_foo);
Richard Smith79b59a22012-08-21 20:39:25 +0000124 // Can't pass null pointer to dyn_cast<>.
125 // foo *F4 = dyn_cast<foo>(fub());
Gabor Greiff06eb372010-07-22 15:37:20 +0000126 // EXPECT_EQ(F4, null_foo);
127 foo *F5 = B1.daz();
128 EXPECT_NE(F5, null_foo);
129}
130
131TEST(CastingTest, dyn_cast_or_null) {
132 const foo *F1 = dyn_cast_or_null<foo>(B2);
133 EXPECT_NE(F1, null_foo);
134 const foo *F2 = dyn_cast_or_null<foo>(B2);
135 EXPECT_NE(F2, null_foo);
136 const foo *F3 = dyn_cast_or_null<foo>(B4);
137 EXPECT_NE(F3, null_foo);
138 foo *F4 = dyn_cast_or_null<foo>(fub());
Gabor Greif46a35012010-07-22 15:28:30 +0000139 EXPECT_EQ(F4, null_foo);
Gabor Greiff06eb372010-07-22 15:37:20 +0000140 foo *F5 = B1.naz();
141 EXPECT_NE(F5, null_foo);
Gabor Greif08993c02010-07-20 16:51:18 +0000142}
143
Gabor Greife8950972010-07-20 17:06:28 +0000144// These lines are errors...
145//foo *F20 = cast<foo>(B2); // Yields const foo*
146//foo &F21 = cast<foo>(B3); // Yields const foo&
147//foo *F22 = cast<foo>(B4); // Yields const foo*
148//foo &F23 = cast_or_null<foo>(B1);
149//const foo &F24 = cast_or_null<foo>(B3);
150
Gabor Greifee57dae2010-07-20 16:32:20 +0000151const bar *B2 = &B;
152} // anonymous namespace
Gabor Greife8950972010-07-20 17:06:28 +0000153
154bar *llvm::fub() { return 0; }
Sean Silva8b8fa7b2012-10-11 23:30:40 +0000155
156namespace {
157namespace inferred_upcasting {
158// This test case verifies correct behavior of inferred upcasts when the
159// types are statically known to be OK to upcast. This is the case when,
160// for example, Derived inherits from Base, and we do `isa<Base>(Derived)`.
161
162// Note: This test will actually fail to compile without inferred
163// upcasting.
164
165class Base {
166public:
167 // No classof. We are testing that the upcast is inferred.
168 Base() {}
169};
170
171class Derived : public Base {
172public:
173 Derived() {}
174};
175
176// Even with no explicit classof() in Base, we should still be able to cast
177// Derived to its base class.
178TEST(CastingTest, UpcastIsInferred) {
179 Derived D;
180 EXPECT_TRUE(isa<Base>(D));
181 Base *BP = dyn_cast<Base>(&D);
182 EXPECT_TRUE(BP != NULL);
183}
184
185
186// This test verifies that the inferred upcast takes precedence over an
187// explicitly written one. This is important because it verifies that the
188// dynamic check gets optimized away.
189class UseInferredUpcast {
190public:
191 int Dummy;
192 static bool classof(const UseInferredUpcast *) {
193 return false;
194 }
195};
196
197TEST(CastingTest, InferredUpcastTakesPrecedence) {
198 UseInferredUpcast UIU;
199 // Since the explicit classof() returns false, this will fail if the
200 // explicit one is used.
201 EXPECT_TRUE(isa<UseInferredUpcast>(&UIU));
202}
203
204} // end namespace inferred_upcasting
205} // end anonymous namespace