| //===- MachineInstrBundleIteratorTest.cpp ---------------------------------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/CodeGen/MachineInstrBundleIterator.h" | |
| #include "llvm/ADT/ilist_node.h" | |
| #include "gtest/gtest.h" | |
| using namespace llvm; | |
| namespace { | |
| struct MyBundledInstr | |
| : public ilist_node<MyBundledInstr, ilist_sentinel_tracking<true>> { | |
| bool isBundledWithPred() const { return true; } | |
| bool isBundledWithSucc() const { return true; } | |
| }; | |
| typedef MachineInstrBundleIterator<MyBundledInstr> bundled_iterator; | |
| typedef MachineInstrBundleIterator<const MyBundledInstr> const_bundled_iterator; | |
| typedef MachineInstrBundleIterator<MyBundledInstr, true> | |
| reverse_bundled_iterator; | |
| typedef MachineInstrBundleIterator<const MyBundledInstr, true> | |
| const_reverse_bundled_iterator; | |
| #ifdef GTEST_HAS_DEATH_TEST | |
| #ifndef NDEBUG | |
| TEST(MachineInstrBundleIteratorTest, CheckForBundles) { | |
| MyBundledInstr MBI; | |
| auto I = MBI.getIterator(); | |
| auto RI = I.getReverse(); | |
| // Confirm that MBI is always considered bundled. | |
| EXPECT_TRUE(MBI.isBundledWithPred()); | |
| EXPECT_TRUE(MBI.isBundledWithSucc()); | |
| // Confirm that iterators check in their constructor for bundled iterators. | |
| EXPECT_DEATH((void)static_cast<bundled_iterator>(I), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<bundled_iterator>(MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<bundled_iterator>(&MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<const_bundled_iterator>(I), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<const_bundled_iterator>(MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<const_bundled_iterator>(&MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<reverse_bundled_iterator>(RI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<reverse_bundled_iterator>(MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<reverse_bundled_iterator>(&MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<const_reverse_bundled_iterator>(RI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<const_reverse_bundled_iterator>(MBI), | |
| "not legal to initialize"); | |
| EXPECT_DEATH((void)static_cast<const_reverse_bundled_iterator>(&MBI), | |
| "not legal to initialize"); | |
| } | |
| #endif | |
| #endif | |
| TEST(MachineInstrBundleIteratorTest, CompareToBundledMI) { | |
| MyBundledInstr MBI; | |
| const MyBundledInstr &CMBI = MBI; | |
| bundled_iterator I; | |
| const_bundled_iterator CI; | |
| // Confirm that MBI is always considered bundled. | |
| EXPECT_TRUE(MBI.isBundledWithPred()); | |
| EXPECT_TRUE(MBI.isBundledWithSucc()); | |
| // These invocations will crash when !NDEBUG if a conversion is taking place. | |
| // These checks confirm that comparison operators don't use any conversion | |
| // operators. | |
| ASSERT_FALSE(MBI == I); | |
| ASSERT_FALSE(&MBI == I); | |
| ASSERT_FALSE(CMBI == I); | |
| ASSERT_FALSE(&CMBI == I); | |
| ASSERT_FALSE(I == MBI); | |
| ASSERT_FALSE(I == &MBI); | |
| ASSERT_FALSE(I == CMBI); | |
| ASSERT_FALSE(I == &CMBI); | |
| ASSERT_FALSE(MBI == CI); | |
| ASSERT_FALSE(&MBI == CI); | |
| ASSERT_FALSE(CMBI == CI); | |
| ASSERT_FALSE(&CMBI == CI); | |
| ASSERT_FALSE(CI == MBI); | |
| ASSERT_FALSE(CI == &MBI); | |
| ASSERT_FALSE(CI == CMBI); | |
| ASSERT_FALSE(CI == &CMBI); | |
| ASSERT_FALSE(MBI.getIterator() == I); | |
| ASSERT_FALSE(CMBI.getIterator() == I); | |
| ASSERT_FALSE(I == MBI.getIterator()); | |
| ASSERT_FALSE(I == CMBI.getIterator()); | |
| ASSERT_FALSE(MBI.getIterator() == CI); | |
| ASSERT_FALSE(CMBI.getIterator() == CI); | |
| ASSERT_FALSE(CI == MBI.getIterator()); | |
| ASSERT_FALSE(CI == CMBI.getIterator()); | |
| ASSERT_TRUE(MBI != I); | |
| ASSERT_TRUE(&MBI != I); | |
| ASSERT_TRUE(CMBI != I); | |
| ASSERT_TRUE(&CMBI != I); | |
| ASSERT_TRUE(I != MBI); | |
| ASSERT_TRUE(I != &MBI); | |
| ASSERT_TRUE(I != CMBI); | |
| ASSERT_TRUE(I != &CMBI); | |
| ASSERT_TRUE(MBI != CI); | |
| ASSERT_TRUE(&MBI != CI); | |
| ASSERT_TRUE(CMBI != CI); | |
| ASSERT_TRUE(&CMBI != CI); | |
| ASSERT_TRUE(CI != MBI); | |
| ASSERT_TRUE(CI != &MBI); | |
| ASSERT_TRUE(CI != CMBI); | |
| ASSERT_TRUE(CI != &CMBI); | |
| ASSERT_TRUE(MBI.getIterator() != I); | |
| ASSERT_TRUE(CMBI.getIterator() != I); | |
| ASSERT_TRUE(I != MBI.getIterator()); | |
| ASSERT_TRUE(I != CMBI.getIterator()); | |
| ASSERT_TRUE(MBI.getIterator() != CI); | |
| ASSERT_TRUE(CMBI.getIterator() != CI); | |
| ASSERT_TRUE(CI != MBI.getIterator()); | |
| ASSERT_TRUE(CI != CMBI.getIterator()); | |
| } | |
| struct MyUnbundledInstr | |
| : ilist_node<MyUnbundledInstr, ilist_sentinel_tracking<true>> { | |
| bool isBundledWithPred() const { return false; } | |
| bool isBundledWithSucc() const { return false; } | |
| }; | |
| typedef MachineInstrBundleIterator<MyUnbundledInstr> unbundled_iterator; | |
| typedef MachineInstrBundleIterator<const MyUnbundledInstr> | |
| const_unbundled_iterator; | |
| typedef MachineInstrBundleIterator<MyUnbundledInstr, true> | |
| reverse_unbundled_iterator; | |
| typedef MachineInstrBundleIterator<const MyUnbundledInstr, true> | |
| const_reverse_unbundled_iterator; | |
| TEST(MachineInstrBundleIteratorTest, ReverseConstructor) { | |
| simple_ilist<MyUnbundledInstr, ilist_sentinel_tracking<true>> L; | |
| const auto &CL = L; | |
| MyUnbundledInstr A, B; | |
| L.insert(L.end(), A); | |
| L.insert(L.end(), B); | |
| // Save typing. | |
| typedef MachineInstrBundleIterator<MyUnbundledInstr> iterator; | |
| typedef MachineInstrBundleIterator<MyUnbundledInstr, true> reverse_iterator; | |
| typedef MachineInstrBundleIterator<const MyUnbundledInstr> const_iterator; | |
| typedef MachineInstrBundleIterator<const MyUnbundledInstr, true> | |
| const_reverse_iterator; | |
| // Convert to bundle iterators. | |
| auto begin = [&]() -> iterator { return L.begin(); }; | |
| auto end = [&]() -> iterator { return L.end(); }; | |
| auto rbegin = [&]() -> reverse_iterator { return L.rbegin(); }; | |
| auto rend = [&]() -> reverse_iterator { return L.rend(); }; | |
| auto cbegin = [&]() -> const_iterator { return CL.begin(); }; | |
| auto cend = [&]() -> const_iterator { return CL.end(); }; | |
| auto crbegin = [&]() -> const_reverse_iterator { return CL.rbegin(); }; | |
| auto crend = [&]() -> const_reverse_iterator { return CL.rend(); }; | |
| // Check conversion values. | |
| EXPECT_EQ(begin(), iterator(rend())); | |
| EXPECT_EQ(++begin(), iterator(++rbegin())); | |
| EXPECT_EQ(end(), iterator(rbegin())); | |
| EXPECT_EQ(rbegin(), reverse_iterator(end())); | |
| EXPECT_EQ(++rbegin(), reverse_iterator(++begin())); | |
| EXPECT_EQ(rend(), reverse_iterator(begin())); | |
| // Check const iterator constructors. | |
| EXPECT_EQ(cbegin(), const_iterator(rend())); | |
| EXPECT_EQ(cbegin(), const_iterator(crend())); | |
| EXPECT_EQ(crbegin(), const_reverse_iterator(end())); | |
| EXPECT_EQ(crbegin(), const_reverse_iterator(cend())); | |
| // Confirm lack of implicit conversions. | |
| static_assert(!std::is_convertible<iterator, reverse_iterator>::value, | |
| "unexpected implicit conversion"); | |
| static_assert(!std::is_convertible<reverse_iterator, iterator>::value, | |
| "unexpected implicit conversion"); | |
| static_assert( | |
| !std::is_convertible<const_iterator, const_reverse_iterator>::value, | |
| "unexpected implicit conversion"); | |
| static_assert( | |
| !std::is_convertible<const_reverse_iterator, const_iterator>::value, | |
| "unexpected implicit conversion"); | |
| } | |
| } // end namespace |