1 //===- llvm/unittest/ADT/BitmaskEnumTest.cpp - BitmaskEnum unit tests -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ADT/BitmaskEnum.h" 10 #include "gtest/gtest.h" 11 12 using namespace llvm; 13 14 namespace { 15 enum Flags { 16 F0 = 0, 17 F1 = 1, 18 F2 = 2, 19 F3 = 4, 20 F4 = 8, 21 LLVM_MARK_AS_BITMASK_ENUM(F4) 22 }; 23 24 TEST(BitmaskEnumTest, BitwiseOr) { 25 Flags f = F1 | F2; 26 EXPECT_EQ(3, f); 27 28 f = f | F3; 29 EXPECT_EQ(7, f); 30 } 31 32 TEST(BitmaskEnumTest, BitwiseOrEquals) { 33 Flags f = F1; 34 f |= F3; 35 EXPECT_EQ(5, f); 36 37 // |= should return a reference to the LHS. 38 f = F2; 39 (f |= F3) = F1; 40 EXPECT_EQ(F1, f); 41 } 42 43 TEST(BitmaskEnumTest, BitwiseAnd) { 44 Flags f = static_cast<Flags>(3) & F2; 45 EXPECT_EQ(F2, f); 46 47 f = (f | F3) & (F1 | F2 | F3); 48 EXPECT_EQ(6, f); 49 } 50 51 TEST(BitmaskEnumTest, BitwiseAndEquals) { 52 Flags f = F1 | F2 | F3; 53 f &= F1 | F2; 54 EXPECT_EQ(3, f); 55 56 // &= should return a reference to the LHS. 57 (f &= F1) = F3; 58 EXPECT_EQ(F3, f); 59 } 60 61 TEST(BitmaskEnumTest, BitwiseXor) { 62 Flags f = (F1 | F2) ^ (F2 | F3); 63 EXPECT_EQ(5, f); 64 65 f = f ^ F1; 66 EXPECT_EQ(4, f); 67 } 68 69 TEST(BitmaskEnumTest, BitwiseXorEquals) { 70 Flags f = (F1 | F2); 71 f ^= (F2 | F4); 72 EXPECT_EQ(9, f); 73 74 // ^= should return a reference to the LHS. 75 (f ^= F4) = F3; 76 EXPECT_EQ(F3, f); 77 } 78 79 TEST(BitmaskEnumTest, ConstantExpression) { 80 constexpr Flags f1 = ~F1; 81 constexpr Flags f2 = F1 | F2; 82 constexpr Flags f3 = F1 & F2; 83 constexpr Flags f4 = F1 ^ F2; 84 EXPECT_EQ(f1, ~F1); 85 EXPECT_EQ(f2, F1 | F2); 86 EXPECT_EQ(f3, F1 & F2); 87 EXPECT_EQ(f4, F1 ^ F2); 88 } 89 90 TEST(BitmaskEnumTest, BitwiseNot) { 91 Flags f = ~F1; 92 EXPECT_EQ(14, f); // Largest value for f is 15. 93 EXPECT_EQ(15, ~F0); 94 } 95 96 enum class FlagsClass { 97 F0 = 0, 98 F1 = 1, 99 F2 = 2, 100 F3 = 4, 101 LLVM_MARK_AS_BITMASK_ENUM(F3) 102 }; 103 104 TEST(BitmaskEnumTest, ScopedEnum) { 105 FlagsClass f = (FlagsClass::F1 & ~FlagsClass::F0) | FlagsClass::F2; 106 f |= FlagsClass::F3; 107 EXPECT_EQ(7, static_cast<int>(f)); 108 } 109 110 struct Container { 111 enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, LLVM_MARK_AS_BITMASK_ENUM(F3) }; 112 113 static Flags getFlags() { 114 Flags f = F0 | F1; 115 f |= F2; 116 return f; 117 } 118 }; 119 120 TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); } 121 122 } // namespace 123 124 namespace foo { 125 namespace bar { 126 namespace { 127 enum FlagsInNamespace { 128 F0 = 0, 129 F1 = 1, 130 F2 = 2, 131 F3 = 4, 132 LLVM_MARK_AS_BITMASK_ENUM(F3) 133 }; 134 } // namespace 135 } // namespace foo 136 } // namespace bar 137 138 namespace { 139 TEST(BitmaskEnumTest, EnumInNamespace) { 140 foo::bar::FlagsInNamespace f = ~foo::bar::F0 & (foo::bar::F1 | foo::bar::F2); 141 f |= foo::bar::F3; 142 EXPECT_EQ(7, f); 143 } 144 } // namespace 145