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
12using namespace llvm;
13
14namespace {
15enum 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
24static_assert(is_bitmask_enum<Flags>::value != 0);
25static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
26
27enum Flags2 { V0 = 0, V1 = 1, V2 = 2, V3 = 4, V4 = 8 };
28} // namespace
29
30namespace llvm {
31LLVM_DECLARE_ENUM_AS_BITMASK(Flags2, V4);
32}
33
34static_assert(is_bitmask_enum<Flags>::value != 0);
35static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
36
37namespace {
38TEST(BitmaskEnumTest, BitwiseOr) {
39 Flags f = F1 | F2;
40 EXPECT_EQ(3, f);
41
42 f = f | F3;
43 EXPECT_EQ(7, f);
44
45 Flags2 f2 = V1 | V2;
46 EXPECT_EQ(3, f2);
47
48 f2 = f2 | V3;
49 EXPECT_EQ(7, f2);
50}
51
52TEST(BitmaskEnumTest, BitwiseOrEquals) {
53 Flags f = F1;
54 f |= F3;
55 EXPECT_EQ(5, f);
56
57 // |= should return a reference to the LHS.
58 f = F2;
59 (f |= F3) = F1;
60 EXPECT_EQ(F1, f);
61
62 Flags2 f2 = V1;
63 f2 |= V3;
64 EXPECT_EQ(5, f2);
65
66 f2 = V2;
67 (f2 |= V3) = V1;
68 EXPECT_EQ(V1, f2);
69}
70
71TEST(BitmaskEnumTest, BitwiseAnd) {
72 Flags f = static_cast<Flags>(3) & F2;
73 EXPECT_EQ(F2, f);
74
75 f = (f | F3) & (F1 | F2 | F3);
76 EXPECT_EQ(6, f);
77
78 Flags2 f2 = static_cast<Flags2>(3) & V2;
79 EXPECT_EQ(V2, f2);
80
81 f2 = (f2 | V3) & (V1 | V2 | V3);
82 EXPECT_EQ(6, f2);
83}
84
85TEST(BitmaskEnumTest, BitwiseAndEquals) {
86 Flags f = F1 | F2 | F3;
87 f &= F1 | F2;
88 EXPECT_EQ(3, f);
89
90 // &= should return a reference to the LHS.
91 (f &= F1) = F3;
92 EXPECT_EQ(F3, f);
93
94 Flags2 f2 = V1 | V2 | V3;
95 f2 &= V1 | V2;
96 EXPECT_EQ(3, f2);
97
98 (f2 &= V1) = V3;
99 EXPECT_EQ(V3, f2);
100}
101
102TEST(BitmaskEnumTest, BitwiseXor) {
103 Flags f = (F1 | F2) ^ (F2 | F3);
104 EXPECT_EQ(5, f);
105
106 f = f ^ F1;
107 EXPECT_EQ(4, f);
108
109 Flags2 f2 = (V1 | V2) ^ (V2 | V3);
110 EXPECT_EQ(5, f2);
111
112 f2 = f2 ^ V1;
113 EXPECT_EQ(4, f2);
114}
115
116TEST(BitmaskEnumTest, BitwiseXorEquals) {
117 Flags f = (F1 | F2);
118 f ^= (F2 | F4);
119 EXPECT_EQ(9, f);
120
121 // ^= should return a reference to the LHS.
122 (f ^= F4) = F3;
123 EXPECT_EQ(F3, f);
124
125 Flags2 f2 = (V1 | V2);
126 f2 ^= (V2 | V4);
127 EXPECT_EQ(9, f2);
128
129 (f2 ^= V4) = V3;
130 EXPECT_EQ(V3, f2);
131}
132
133TEST(BitmaskEnumTest, ConstantExpression) {
134 constexpr Flags f1 = ~F1;
135 constexpr Flags f2 = F1 | F2;
136 constexpr Flags f3 = F1 & F2;
137 constexpr Flags f4 = F1 ^ F2;
138 EXPECT_EQ(f1, ~F1);
139 EXPECT_EQ(f2, F1 | F2);
140 EXPECT_EQ(f3, F1 & F2);
141 EXPECT_EQ(f4, F1 ^ F2);
142
143 constexpr Flags2 f21 = ~V1;
144 constexpr Flags2 f22 = V1 | V2;
145 constexpr Flags2 f23 = V1 & V2;
146 constexpr Flags2 f24 = V1 ^ V2;
147 EXPECT_EQ(f21, ~V1);
148 EXPECT_EQ(f22, V1 | V2);
149 EXPECT_EQ(f23, V1 & V2);
150 EXPECT_EQ(f24, V1 ^ V2);
151}
152
153TEST(BitmaskEnumTest, BitwiseNot) {
154 Flags f = ~F1;
155 EXPECT_EQ(14, f); // Largest value for f is 15.
156 EXPECT_EQ(15, ~F0);
157
158 Flags2 f2 = ~V1;
159 EXPECT_EQ(14, f2);
160 EXPECT_EQ(15, ~V0);
161}
162
163enum class FlagsClass {
164 F0 = 0,
165 F1 = 1,
166 F2 = 2,
167 F3 = 4,
168 LLVM_MARK_AS_BITMASK_ENUM(F3)
169};
170
171TEST(BitmaskEnumTest, ScopedEnum) {
172 FlagsClass f = (FlagsClass::F1 & ~FlagsClass::F0) | FlagsClass::F2;
173 f |= FlagsClass::F3;
174 EXPECT_EQ(7, static_cast<int>(f));
175}
176
177struct Container {
178 enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, LLVM_MARK_AS_BITMASK_ENUM(F3) };
179
180 static Flags getFlags() {
181 Flags f = F0 | F1;
182 f |= F2;
183 return f;
184 }
185};
186
187TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); }
188
189} // namespace
190
191namespace foo {
192namespace bar {
193namespace {
194enum FlagsInNamespace {
195 F0 = 0,
196 F1 = 1,
197 F2 = 2,
198 F3 = 4,
199 LLVM_MARK_AS_BITMASK_ENUM(F3)
200};
201} // namespace
202} // namespace foo
203} // namespace bar
204
205namespace {
206TEST(BitmaskEnumTest, EnumInNamespace) {
207 foo::bar::FlagsInNamespace f = ~foo::bar::F0 & (foo::bar::F1 | foo::bar::F2);
208 f |= foo::bar::F3;
209 EXPECT_EQ(7, f);
210}
211} // namespace
212

source code of llvm/unittests/ADT/BitmaskEnumTest.cpp