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