
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
212 lines
4.1 KiB
C++
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
|