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
TEST(BitmaskEnumTest,BitwiseOr)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
TEST(BitmaskEnumTest,BitwiseOrEquals)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
TEST(BitmaskEnumTest,BitwiseAnd)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
TEST(BitmaskEnumTest,BitwiseAndEquals)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
TEST(BitmaskEnumTest,BitwiseXor)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
TEST(BitmaskEnumTest,BitwiseXorEquals)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
TEST(BitmaskEnumTest,ConstantExpression)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
TEST(BitmaskEnumTest,BitwiseNot)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
TEST(BitmaskEnumTest,ScopedEnum)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
getFlags__anon49895ee40111::Container113 static Flags getFlags() {
114 Flags f = F0 | F1;
115 f |= F2;
116 return f;
117 }
118 };
119
TEST(BitmaskEnumTest,EnumInStruct)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 {
TEST(BitmaskEnumTest,EnumInNamespace)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