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,BitwiseNot)79 TEST(BitmaskEnumTest, BitwiseNot) {
80   Flags f = ~F1;
81   EXPECT_EQ(14, f); // Largest value for f is 15.
82   EXPECT_EQ(15, ~F0);
83 }
84 
85 enum class FlagsClass {
86   F0 = 0,
87   F1 = 1,
88   F2 = 2,
89   F3 = 4,
90   LLVM_MARK_AS_BITMASK_ENUM(F3)
91 };
92 
TEST(BitmaskEnumTest,ScopedEnum)93 TEST(BitmaskEnumTest, ScopedEnum) {
94   FlagsClass f = (FlagsClass::F1 & ~FlagsClass::F0) | FlagsClass::F2;
95   f |= FlagsClass::F3;
96   EXPECT_EQ(7, static_cast<int>(f));
97 }
98 
99 struct Container {
100   enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, LLVM_MARK_AS_BITMASK_ENUM(F3) };
101 
getFlags__anonc18841dc0111::Container102   static Flags getFlags() {
103     Flags f = F0 | F1;
104     f |= F2;
105     return f;
106   }
107 };
108 
TEST(BitmaskEnumTest,EnumInStruct)109 TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); }
110 
111 } // namespace
112 
113 namespace foo {
114 namespace bar {
115 namespace {
116 enum FlagsInNamespace {
117   F0 = 0,
118   F1 = 1,
119   F2 = 2,
120   F3 = 4,
121   LLVM_MARK_AS_BITMASK_ENUM(F3)
122 };
123 } // namespace
124 } // namespace foo
125 } // namespace bar
126 
127 namespace {
TEST(BitmaskEnumTest,EnumInNamespace)128 TEST(BitmaskEnumTest, EnumInNamespace) {
129   foo::bar::FlagsInNamespace f = ~foo::bar::F0 & (foo::bar::F1 | foo::bar::F2);
130   f |= foo::bar::F3;
131   EXPECT_EQ(7, f);
132 }
133 } // namespace
134