llvm-project/llvm/unittests/ADT/BitmaskEnumTest.cpp
Serge Pavlov 7f81dd4dd6 [NFC] Make FPClassTest a bitmask enumeration
This is recommit of 2e416cdd52, fixed to be accepatble by GCC.
The original commit message is below.

With this change bitwise operations are allowed for FPClassTest
enumeration, it must simplify using this type. Also some functions
changed to get argument of type FPClassTest instead of unsigned.

Differential Revision: https://reviews.llvm.org/D144241
2023-02-24 15:12:16 +07:00

212 lines
4.1 KiB
C++

//===- llvm/unittest/ADT/BitmaskEnumTest.cpp - BitmaskEnum unit tests -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/BitmaskEnum.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
enum Flags {
F0 = 0,
F1 = 1,
F2 = 2,
F3 = 4,
F4 = 8,
LLVM_MARK_AS_BITMASK_ENUM(F4)
};
static_assert(is_bitmask_enum<Flags>::value != 0);
static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
enum Flags2 { V0 = 0, V1 = 1, V2 = 2, V3 = 4, V4 = 8 };
} // namespace
namespace llvm {
LLVM_DECLARE_ENUM_AS_BITMASK(Flags2, V4);
}
static_assert(is_bitmask_enum<Flags>::value != 0);
static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
namespace {
TEST(BitmaskEnumTest, BitwiseOr) {
Flags f = F1 | F2;
EXPECT_EQ(3, f);
f = f | F3;
EXPECT_EQ(7, f);
Flags2 f2 = V1 | V2;
EXPECT_EQ(3, f2);
f2 = f2 | V3;
EXPECT_EQ(7, f2);
}
TEST(BitmaskEnumTest, BitwiseOrEquals) {
Flags f = F1;
f |= F3;
EXPECT_EQ(5, f);
// |= should return a reference to the LHS.
f = F2;
(f |= F3) = F1;
EXPECT_EQ(F1, f);
Flags2 f2 = V1;
f2 |= V3;
EXPECT_EQ(5, f2);
f2 = V2;
(f2 |= V3) = V1;
EXPECT_EQ(V1, f2);
}
TEST(BitmaskEnumTest, BitwiseAnd) {
Flags f = static_cast<Flags>(3) & F2;
EXPECT_EQ(F2, f);
f = (f | F3) & (F1 | F2 | F3);
EXPECT_EQ(6, f);
Flags2 f2 = static_cast<Flags2>(3) & V2;
EXPECT_EQ(V2, f2);
f2 = (f2 | V3) & (V1 | V2 | V3);
EXPECT_EQ(6, f2);
}
TEST(BitmaskEnumTest, BitwiseAndEquals) {
Flags f = F1 | F2 | F3;
f &= F1 | F2;
EXPECT_EQ(3, f);
// &= should return a reference to the LHS.
(f &= F1) = F3;
EXPECT_EQ(F3, f);
Flags2 f2 = V1 | V2 | V3;
f2 &= V1 | V2;
EXPECT_EQ(3, f2);
(f2 &= V1) = V3;
EXPECT_EQ(V3, f2);
}
TEST(BitmaskEnumTest, BitwiseXor) {
Flags f = (F1 | F2) ^ (F2 | F3);
EXPECT_EQ(5, f);
f = f ^ F1;
EXPECT_EQ(4, f);
Flags2 f2 = (V1 | V2) ^ (V2 | V3);
EXPECT_EQ(5, f2);
f2 = f2 ^ V1;
EXPECT_EQ(4, f2);
}
TEST(BitmaskEnumTest, BitwiseXorEquals) {
Flags f = (F1 | F2);
f ^= (F2 | F4);
EXPECT_EQ(9, f);
// ^= should return a reference to the LHS.
(f ^= F4) = F3;
EXPECT_EQ(F3, f);
Flags2 f2 = (V1 | V2);
f2 ^= (V2 | V4);
EXPECT_EQ(9, f2);
(f2 ^= V4) = V3;
EXPECT_EQ(V3, f2);
}
TEST(BitmaskEnumTest, ConstantExpression) {
constexpr Flags f1 = ~F1;
constexpr Flags f2 = F1 | F2;
constexpr Flags f3 = F1 & F2;
constexpr Flags f4 = F1 ^ F2;
EXPECT_EQ(f1, ~F1);
EXPECT_EQ(f2, F1 | F2);
EXPECT_EQ(f3, F1 & F2);
EXPECT_EQ(f4, F1 ^ F2);
constexpr Flags2 f21 = ~V1;
constexpr Flags2 f22 = V1 | V2;
constexpr Flags2 f23 = V1 & V2;
constexpr Flags2 f24 = V1 ^ V2;
EXPECT_EQ(f21, ~V1);
EXPECT_EQ(f22, V1 | V2);
EXPECT_EQ(f23, V1 & V2);
EXPECT_EQ(f24, V1 ^ V2);
}
TEST(BitmaskEnumTest, BitwiseNot) {
Flags f = ~F1;
EXPECT_EQ(14, f); // Largest value for f is 15.
EXPECT_EQ(15, ~F0);
Flags2 f2 = ~V1;
EXPECT_EQ(14, f2);
EXPECT_EQ(15, ~V0);
}
enum class FlagsClass {
F0 = 0,
F1 = 1,
F2 = 2,
F3 = 4,
LLVM_MARK_AS_BITMASK_ENUM(F3)
};
TEST(BitmaskEnumTest, ScopedEnum) {
FlagsClass f = (FlagsClass::F1 & ~FlagsClass::F0) | FlagsClass::F2;
f |= FlagsClass::F3;
EXPECT_EQ(7, static_cast<int>(f));
}
struct Container {
enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, LLVM_MARK_AS_BITMASK_ENUM(F3) };
static Flags getFlags() {
Flags f = F0 | F1;
f |= F2;
return f;
}
};
TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); }
} // namespace
namespace foo {
namespace bar {
namespace {
enum FlagsInNamespace {
F0 = 0,
F1 = 1,
F2 = 2,
F3 = 4,
LLVM_MARK_AS_BITMASK_ENUM(F3)
};
} // namespace
} // namespace foo
} // namespace bar
namespace {
TEST(BitmaskEnumTest, EnumInNamespace) {
foo::bar::FlagsInNamespace f = ~foo::bar::F0 & (foo::bar::F1 | foo::bar::F2);
f |= foo::bar::F3;
EXPECT_EQ(7, f);
}
} // namespace