239 lines · cpp
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-exception6//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} // namespace29 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, BitwiseShift) {134 Flags f = (F1 << F1);135 EXPECT_EQ(f, F2);136 137 Flags f2 = F1;138 f2 <<= F1;139 EXPECT_EQ(f2, F2);140 141 Flags f3 = (F1 >> F1);142 EXPECT_EQ(f3, F0);143 144 Flags f4 = F1;145 f4 >>= F1;146 EXPECT_EQ(f4, F0);147}148 149TEST(BitmaskEnumTest, ConstantExpression) {150 constexpr Flags f1 = ~F1;151 constexpr Flags f2 = F1 | F2;152 constexpr Flags f3 = F1 & F2;153 constexpr Flags f4 = F1 ^ F2;154 EXPECT_EQ(f1, ~F1);155 EXPECT_EQ(f2, F1 | F2);156 EXPECT_EQ(f3, F1 & F2);157 EXPECT_EQ(f4, F1 ^ F2);158 159 constexpr Flags2 f21 = ~V1;160 constexpr Flags2 f22 = V1 | V2;161 constexpr Flags2 f23 = V1 & V2;162 constexpr Flags2 f24 = V1 ^ V2;163 EXPECT_EQ(f21, ~V1);164 EXPECT_EQ(f22, V1 | V2);165 EXPECT_EQ(f23, V1 & V2);166 EXPECT_EQ(f24, V1 ^ V2);167}168 169TEST(BitmaskEnumTest, BitwiseNot) {170 Flags f = ~F1;171 EXPECT_EQ(14, f); // Largest value for f is 15.172 EXPECT_EQ(15, ~F0);173 174 Flags2 f2 = ~V1;175 EXPECT_EQ(14, f2);176 EXPECT_EQ(15, ~V0);177}178 179TEST(BitmaskEnumTest, BooleanNot) {180 bool b0 = !F0;181 EXPECT_TRUE(b0);182 183 bool b1 = !(F1 & F2);184 EXPECT_TRUE(b1);185 186 bool b2 = !(F2 | F4);187 EXPECT_FALSE(b2);188}189 190enum class FlagsClass {191 F0 = 0,192 F1 = 1,193 F2 = 2,194 F3 = 4,195 LLVM_MARK_AS_BITMASK_ENUM(F3)196};197 198TEST(BitmaskEnumTest, ScopedEnum) {199 FlagsClass f = (FlagsClass::F1 & ~FlagsClass::F0) | FlagsClass::F2;200 f |= FlagsClass::F3;201 EXPECT_EQ(7, static_cast<int>(f));202}203 204struct Container {205 enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, LLVM_MARK_AS_BITMASK_ENUM(F3) };206 207 static Flags getFlags() {208 Flags f = F0 | F1;209 f |= F2;210 return f;211 }212};213 214TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); }215 216} // namespace217 218namespace foo {219namespace bar {220namespace {221enum FlagsInNamespace {222 F0 = 0,223 F1 = 1,224 F2 = 2,225 F3 = 4,226 LLVM_MARK_AS_BITMASK_ENUM(F3)227};228} // namespace229} // namespace foo230} // namespace bar231 232namespace {233TEST(BitmaskEnumTest, EnumInNamespace) {234 foo::bar::FlagsInNamespace f = ~foo::bar::F0 & (foo::bar::F1 | foo::bar::F2);235 f |= foo::bar::F3;236 EXPECT_EQ(7, f);237}238} // namespace239