//===- MachineInstrBundleIteratorTest.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineInstrBundleIterator.h" #include "llvm/ADT/ilist_node.h" #include "gtest/gtest.h" using namespace llvm; namespace { struct MyBundledInstr : public ilist_node> { bool isBundledWithPred() const { return true; } bool isBundledWithSucc() const { return true; } }; typedef MachineInstrBundleIterator bundled_iterator; typedef MachineInstrBundleIterator const_bundled_iterator; typedef MachineInstrBundleIterator reverse_bundled_iterator; typedef MachineInstrBundleIterator 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(I), "not legal to initialize"); EXPECT_DEATH((void)static_cast(MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(&MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(I), "not legal to initialize"); EXPECT_DEATH((void)static_cast(MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(&MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(RI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(&MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(RI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(MBI), "not legal to initialize"); EXPECT_DEATH((void)static_cast(&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> { bool isBundledWithPred() const { return false; } bool isBundledWithSucc() const { return false; } }; typedef MachineInstrBundleIterator unbundled_iterator; typedef MachineInstrBundleIterator const_unbundled_iterator; typedef MachineInstrBundleIterator reverse_unbundled_iterator; typedef MachineInstrBundleIterator const_reverse_unbundled_iterator; TEST(MachineInstrBundleIteratorTest, ReverseConstructor) { simple_ilist> L; const auto &CL = L; MyUnbundledInstr A, B; L.insert(L.end(), A); L.insert(L.end(), B); // Save typing. typedef MachineInstrBundleIterator iterator; typedef MachineInstrBundleIterator reverse_iterator; typedef MachineInstrBundleIterator const_iterator; typedef MachineInstrBundleIterator 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::value, "unexpected implicit conversion"); static_assert(!std::is_convertible::value, "unexpected implicit conversion"); static_assert( !std::is_convertible::value, "unexpected implicit conversion"); static_assert( !std::is_convertible::value, "unexpected implicit conversion"); } } // end namespace