aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/orc/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/orc/tests/unit')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/adt_test.cpp50
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/bitmask_enum_test.cpp143
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/c_api_test.cpp200
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/endian_test.cpp174
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/error_test.cpp295
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_address_test.cpp115
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_symbol_def_test.cpp19
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/extensible_rtti_test.cpp54
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_map_test.cpp204
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_set_test.cpp121
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/orc_unit_test_main.cpp18
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp184
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_utils.h34
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/string_pool_test.cpp66
-rw-r--r--contrib/llvm-project/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp184
15 files changed, 1861 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/adt_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/adt_test.cpp
new file mode 100644
index 000000000000..6625a590e363
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/adt_test.cpp
@@ -0,0 +1,50 @@
+//===-- adt_test.cpp ------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "adt.h"
+#include "gtest/gtest.h"
+
+#include <sstream>
+#include <string>
+
+using namespace __orc_rt;
+
+TEST(ADTTest, SpanDefaultConstruction) {
+ span<int> S;
+ EXPECT_TRUE(S.empty()) << "Default constructed span not empty";
+ EXPECT_EQ(S.size(), 0U) << "Default constructed span size not zero";
+ EXPECT_EQ(S.begin(), S.end()) << "Default constructed span begin != end";
+}
+
+TEST(ADTTest, SpanConstructFromFixedArray) {
+ int A[] = {1, 2, 3, 4, 5};
+ span<int> S(A);
+ EXPECT_FALSE(S.empty()) << "Span should be non-empty";
+ EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
+ EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
+ << "Unexpected iterator range size";
+ EXPECT_EQ(S.data(), &A[0]) << "Span data has unexpected value";
+ for (unsigned I = 0; I != S.size(); ++I)
+ EXPECT_EQ(S[I], A[I]) << "Unexpected span element value";
+}
+
+TEST(ADTTest, SpanConstructFromIteratorAndSize) {
+ int A[] = {1, 2, 3, 4, 5};
+ span<int> S(&A[0], 5);
+ EXPECT_FALSE(S.empty()) << "Span should be non-empty";
+ EXPECT_EQ(S.size(), 5U) << "Span has unexpected size";
+ EXPECT_EQ(std::distance(S.begin(), S.end()), 5U)
+ << "Unexpected iterator range size";
+ EXPECT_EQ(S.data(), &A[0]) << "Span data has unexpected value";
+ for (unsigned I = 0; I != S.size(); ++I)
+ EXPECT_EQ(S[I], A[I]) << "Unexpected span element value";
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/bitmask_enum_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/bitmask_enum_test.cpp
new file mode 100644
index 000000000000..4c27d54fb4a9
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/bitmask_enum_test.cpp
@@ -0,0 +1,143 @@
+//===-- adt_test.cpp ------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "bitmask_enum.h"
+#include "gtest/gtest.h"
+
+#include <sstream>
+#include <string>
+
+using namespace __orc_rt;
+
+namespace {
+
+enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, F4 = 8 };
+
+} // namespace
+
+namespace __orc_rt {
+ORC_RT_DECLARE_ENUM_AS_BITMASK(Flags, F4);
+} // namespace __orc_rt
+
+static_assert(is_bitmask_enum<Flags>::value != 0);
+static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
+
+namespace {
+
+static_assert(is_bitmask_enum<Flags>::value != 0);
+static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
+
+TEST(BitmaskEnumTest, BitwiseOr) {
+ Flags f = F1 | F2;
+ EXPECT_EQ(3, f);
+
+ f = f | F3;
+ EXPECT_EQ(7, f);
+}
+
+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);
+}
+
+TEST(BitmaskEnumTest, BitwiseAnd) {
+ Flags f = static_cast<Flags>(3) & F2;
+ EXPECT_EQ(F2, f);
+
+ f = (f | F3) & (F1 | F2 | F3);
+ EXPECT_EQ(6, f);
+}
+
+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);
+}
+
+TEST(BitmaskEnumTest, BitwiseXor) {
+ Flags f = (F1 | F2) ^ (F2 | F3);
+ EXPECT_EQ(5, f);
+
+ f = f ^ F1;
+ EXPECT_EQ(4, f);
+}
+
+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);
+}
+
+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);
+}
+
+TEST(BitmaskEnumTest, BitwiseNot) {
+ Flags f = ~F1;
+ EXPECT_EQ(14, f); // Largest value for f is 15.
+ EXPECT_EQ(15, ~F0);
+}
+
+enum class FlagsClass {
+ F0 = 0,
+ F1 = 1,
+ F2 = 2,
+ F3 = 4,
+ ORC_RT_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,
+ ORC_RT_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
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/c_api_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/c_api_test.cpp
new file mode 100644
index 000000000000..497cb937e2af
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/c_api_test.cpp
@@ -0,0 +1,200 @@
+//===-- c_api_test.cpp ----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "orc_rt/c_api.h"
+#include "gtest/gtest.h"
+
+TEST(CAPITest, CWrapperFunctionResultInit) {
+ orc_rt_CWrapperFunctionResult R;
+ orc_rt_CWrapperFunctionResultInit(&R);
+
+ EXPECT_EQ(R.Size, 0U);
+ EXPECT_EQ(R.Data.ValuePtr, nullptr);
+
+ // Check that this value isn't treated as an out-of-band error.
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultAllocSmall) {
+ constexpr size_t SmallAllocSize = sizeof(const char *);
+
+ auto R = orc_rt_CWrapperFunctionResultAllocate(SmallAllocSize);
+ char *DataPtr = orc_rt_CWrapperFunctionResultData(&R);
+
+ for (size_t I = 0; I != SmallAllocSize; ++I)
+ DataPtr[I] = 0x55 + I;
+
+ // Check that the inline storage in R.Data.Value contains the expected
+ // sequence.
+ EXPECT_EQ(R.Size, SmallAllocSize);
+ for (size_t I = 0; I != SmallAllocSize; ++I)
+ EXPECT_EQ(R.Data.Value[I], (char)(0x55 + I))
+ << "Unexpected value at index " << I;
+
+ // Check that this value isn't treated as an out-of-band error.
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
+
+ // Check that orc_rt_CWrapperFunctionResult(Data|Result|Size) and
+ // orc_rt_CWrapperFunctionResultGetOutOfBandError behave as expected.
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultData(&R), R.Data.Value);
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultSize(&R), SmallAllocSize);
+ EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(&R));
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultAllocLarge) {
+ constexpr size_t LargeAllocSize = sizeof(const char *) + 1;
+
+ auto R = orc_rt_CWrapperFunctionResultAllocate(LargeAllocSize);
+ char *DataPtr = orc_rt_CWrapperFunctionResultData(&R);
+
+ for (size_t I = 0; I != LargeAllocSize; ++I)
+ DataPtr[I] = 0x55 + I;
+
+ // Check that the inline storage in R.Data.Value contains the expected
+ // sequence.
+ EXPECT_EQ(R.Size, LargeAllocSize);
+ EXPECT_EQ(R.Data.ValuePtr, DataPtr);
+ for (size_t I = 0; I != LargeAllocSize; ++I)
+ EXPECT_EQ(R.Data.ValuePtr[I], (char)(0x55 + I))
+ << "Unexpected value at index " << I;
+
+ // Check that this value isn't treated as an out-of-band error.
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
+
+ // Check that orc_rt_CWrapperFunctionResult(Data|Result|Size) and
+ // orc_rt_CWrapperFunctionResultGetOutOfBandError behave as expected.
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultData(&R), R.Data.ValuePtr);
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultSize(&R), LargeAllocSize);
+ EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(&R));
+ EXPECT_EQ(orc_rt_CWrapperFunctionResultGetOutOfBandError(&R), nullptr);
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultFromRangeSmall) {
+ constexpr size_t SmallAllocSize = sizeof(const char *);
+
+ char Source[SmallAllocSize];
+ for (size_t I = 0; I != SmallAllocSize; ++I)
+ Source[I] = 0x55 + I;
+
+ orc_rt_CWrapperFunctionResult R =
+ orc_rt_CreateCWrapperFunctionResultFromRange(Source, SmallAllocSize);
+
+ // Check that the inline storage in R.Data.Value contains the expected
+ // sequence.
+ EXPECT_EQ(R.Size, SmallAllocSize);
+ for (size_t I = 0; I != SmallAllocSize; ++I)
+ EXPECT_EQ(R.Data.Value[I], (char)(0x55 + I))
+ << "Unexpected value at index " << I;
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultFromRangeLarge) {
+ constexpr size_t LargeAllocSize = sizeof(const char *) + 1;
+
+ char Source[LargeAllocSize];
+ for (size_t I = 0; I != LargeAllocSize; ++I)
+ Source[I] = 0x55 + I;
+
+ orc_rt_CWrapperFunctionResult R =
+ orc_rt_CreateCWrapperFunctionResultFromRange(Source, LargeAllocSize);
+
+ // Check that the inline storage in R.Data.Value contains the expected
+ // sequence.
+ EXPECT_EQ(R.Size, LargeAllocSize);
+ for (size_t I = 0; I != LargeAllocSize; ++I)
+ EXPECT_EQ(R.Data.ValuePtr[I], (char)(0x55 + I))
+ << "Unexpected value at index " << I;
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultFromStringSmall) {
+ constexpr size_t SmallAllocSize = sizeof(const char *);
+
+ char Source[SmallAllocSize];
+ for (size_t I = 0; I != SmallAllocSize - 1; ++I)
+ Source[I] = 'a' + I;
+ Source[SmallAllocSize - 1] = '\0';
+
+ orc_rt_CWrapperFunctionResult R =
+ orc_rt_CreateCWrapperFunctionResultFromString(Source);
+
+ // Check that the inline storage in R.Data.Value contains the expected
+ // sequence.
+ EXPECT_EQ(R.Size, SmallAllocSize);
+ for (size_t I = 0; I != SmallAllocSize - 1; ++I)
+ EXPECT_EQ(R.Data.Value[I], (char)('a' + I))
+ << "Unexpected value at index " << I;
+ EXPECT_EQ(R.Data.Value[SmallAllocSize - 1], '\0')
+ << "Unexpected value at index " << (SmallAllocSize - 1);
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultFromStringLarge) {
+ constexpr size_t LargeAllocSize = sizeof(const char *) + 1;
+
+ char Source[LargeAllocSize];
+ for (size_t I = 0; I != LargeAllocSize - 1; ++I)
+ Source[I] = 'a' + I;
+ Source[LargeAllocSize - 1] = '\0';
+
+ orc_rt_CWrapperFunctionResult R =
+ orc_rt_CreateCWrapperFunctionResultFromString(Source);
+
+ // Check that the inline storage in R.Data.Value contains the expected
+ // sequence.
+ EXPECT_EQ(R.Size, LargeAllocSize);
+ for (size_t I = 0; I != LargeAllocSize - 1; ++I)
+ EXPECT_EQ(R.Data.ValuePtr[I], (char)('a' + I))
+ << "Unexpected value at index " << I;
+ EXPECT_EQ(R.Data.ValuePtr[LargeAllocSize - 1], '\0')
+ << "Unexpected value at index " << (LargeAllocSize - 1);
+
+ // Check that we can dispose of the value.
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
+
+TEST(CAPITest, CWrapperFunctionResultFromOutOfBandError) {
+ constexpr const char *ErrMsg = "test error message";
+ orc_rt_CWrapperFunctionResult R =
+ orc_rt_CreateCWrapperFunctionResultFromOutOfBandError(ErrMsg);
+
+#ifndef NDEBUG
+ EXPECT_DEATH({ orc_rt_CWrapperFunctionResultData(&R); },
+ "Cannot get data for out-of-band error value");
+ EXPECT_DEATH({ orc_rt_CWrapperFunctionResultSize(&R); },
+ "Cannot get size for out-of-band error value");
+#endif
+
+ EXPECT_FALSE(orc_rt_CWrapperFunctionResultEmpty(&R));
+ const char *OOBErrMsg = orc_rt_CWrapperFunctionResultGetOutOfBandError(&R);
+ EXPECT_NE(OOBErrMsg, nullptr);
+ EXPECT_NE(OOBErrMsg, ErrMsg);
+ EXPECT_TRUE(strcmp(OOBErrMsg, ErrMsg) == 0);
+
+ orc_rt_DisposeCWrapperFunctionResult(&R);
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/endian_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/endian_test.cpp
new file mode 100644
index 000000000000..71b677af694c
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/endian_test.cpp
@@ -0,0 +1,174 @@
+//===- endian_test.cpp ------------------------- swap byte order test -----===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+// Adapted from the llvm/unittests/Support/SwapByteOrderTest.cpp LLVM unit test.
+//
+//===----------------------------------------------------------------------===//
+
+#include "endianness.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(Endian, ByteSwap_32) {
+ EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344));
+ EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD));
+}
+
+TEST(Endian, ByteSwap_64) {
+ EXPECT_EQ(0x8877665544332211ULL, ByteSwap_64(0x1122334455667788LL));
+ EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL));
+}
+
+// In these first two tests all of the original_uintx values are truncated
+// except for 64. We could avoid this, but there's really no point.
+TEST(Endian, getSwappedBytes_UnsignedRoundTrip) {
+ // The point of the bit twiddling of magic is to test with and without bits
+ // in every byte.
+ uint64_t value = 1;
+ for (std::size_t i = 0; i <= sizeof(value); ++i) {
+ uint8_t original_uint8 = static_cast<uint8_t>(value);
+ EXPECT_EQ(original_uint8, getSwappedBytes(getSwappedBytes(original_uint8)));
+
+ uint16_t original_uint16 = static_cast<uint16_t>(value);
+ EXPECT_EQ(original_uint16,
+ getSwappedBytes(getSwappedBytes(original_uint16)));
+
+ uint32_t original_uint32 = static_cast<uint32_t>(value);
+ EXPECT_EQ(original_uint32,
+ getSwappedBytes(getSwappedBytes(original_uint32)));
+
+ uint64_t original_uint64 = static_cast<uint64_t>(value);
+ EXPECT_EQ(original_uint64,
+ getSwappedBytes(getSwappedBytes(original_uint64)));
+
+ value = (value << 8) | 0x55; // binary 0101 0101.
+ }
+}
+
+TEST(Endian, getSwappedBytes_SignedRoundTrip) {
+ // The point of the bit twiddling of magic is to test with and without bits
+ // in every byte.
+ uint64_t value = 1;
+ for (std::size_t i = 0; i <= sizeof(value); ++i) {
+ int8_t original_int8 = static_cast<int8_t>(value);
+ EXPECT_EQ(original_int8, getSwappedBytes(getSwappedBytes(original_int8)));
+
+ int16_t original_int16 = static_cast<int16_t>(value);
+ EXPECT_EQ(original_int16, getSwappedBytes(getSwappedBytes(original_int16)));
+
+ int32_t original_int32 = static_cast<int32_t>(value);
+ EXPECT_EQ(original_int32, getSwappedBytes(getSwappedBytes(original_int32)));
+
+ int64_t original_int64 = static_cast<int64_t>(value);
+ EXPECT_EQ(original_int64, getSwappedBytes(getSwappedBytes(original_int64)));
+
+ // Test other sign.
+ value *= -1;
+
+ original_int8 = static_cast<int8_t>(value);
+ EXPECT_EQ(original_int8, getSwappedBytes(getSwappedBytes(original_int8)));
+
+ original_int16 = static_cast<int16_t>(value);
+ EXPECT_EQ(original_int16, getSwappedBytes(getSwappedBytes(original_int16)));
+
+ original_int32 = static_cast<int32_t>(value);
+ EXPECT_EQ(original_int32, getSwappedBytes(getSwappedBytes(original_int32)));
+
+ original_int64 = static_cast<int64_t>(value);
+ EXPECT_EQ(original_int64, getSwappedBytes(getSwappedBytes(original_int64)));
+
+ // Return to normal sign and twiddle.
+ value *= -1;
+ value = (value << 8) | 0x55; // binary 0101 0101.
+ }
+}
+
+TEST(Endian, getSwappedBytes_uint8_t) {
+ EXPECT_EQ(uint8_t(0x11), getSwappedBytes(uint8_t(0x11)));
+}
+
+TEST(Endian, getSwappedBytes_uint16_t) {
+ EXPECT_EQ(uint16_t(0x1122), getSwappedBytes(uint16_t(0x2211)));
+}
+
+TEST(Endian, getSwappedBytes_uint32_t) {
+ EXPECT_EQ(uint32_t(0x11223344), getSwappedBytes(uint32_t(0x44332211)));
+}
+
+TEST(Endian, getSwappedBytes_uint64_t) {
+ EXPECT_EQ(uint64_t(0x1122334455667788ULL),
+ getSwappedBytes(uint64_t(0x8877665544332211ULL)));
+}
+
+TEST(Endian, getSwappedBytes_int8_t) {
+ EXPECT_EQ(int8_t(0x11), getSwappedBytes(int8_t(0x11)));
+}
+
+TEST(Endian, getSwappedBytes_int16_t) {
+ EXPECT_EQ(int16_t(0x1122), getSwappedBytes(int16_t(0x2211)));
+}
+
+TEST(Endian, getSwappedBytes_int32_t) {
+ EXPECT_EQ(int32_t(0x11223344), getSwappedBytes(int32_t(0x44332211)));
+}
+
+TEST(Endian, getSwappedBytes_int64_t) {
+ EXPECT_EQ(int64_t(0x1122334455667788LL),
+ getSwappedBytes(int64_t(0x8877665544332211LL)));
+}
+
+TEST(Endian, swapByteOrder_uint8_t) {
+ uint8_t value = 0x11;
+ swapByteOrder(value);
+ EXPECT_EQ(uint8_t(0x11), value);
+}
+
+TEST(Endian, swapByteOrder_uint16_t) {
+ uint16_t value = 0x2211;
+ swapByteOrder(value);
+ EXPECT_EQ(uint16_t(0x1122), value);
+}
+
+TEST(Endian, swapByteOrder_uint32_t) {
+ uint32_t value = 0x44332211;
+ swapByteOrder(value);
+ EXPECT_EQ(uint32_t(0x11223344), value);
+}
+
+TEST(Endian, swapByteOrder_uint64_t) {
+ uint64_t value = 0x8877665544332211ULL;
+ swapByteOrder(value);
+ EXPECT_EQ(uint64_t(0x1122334455667788ULL), value);
+}
+
+TEST(Endian, swapByteOrder_int8_t) {
+ int8_t value = 0x11;
+ swapByteOrder(value);
+ EXPECT_EQ(int8_t(0x11), value);
+}
+
+TEST(Endian, swapByteOrder_int16_t) {
+ int16_t value = 0x2211;
+ swapByteOrder(value);
+ EXPECT_EQ(int16_t(0x1122), value);
+}
+
+TEST(Endian, swapByteOrder_int32_t) {
+ int32_t value = 0x44332211;
+ swapByteOrder(value);
+ EXPECT_EQ(int32_t(0x11223344), value);
+}
+
+TEST(Endian, swapByteOrder_int64_t) {
+ int64_t value = 0x8877665544332211LL;
+ swapByteOrder(value);
+ EXPECT_EQ(int64_t(0x1122334455667788LL), value);
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/error_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/error_test.cpp
new file mode 100644
index 000000000000..5251d788e01b
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/error_test.cpp
@@ -0,0 +1,295 @@
+//===-- error_test.cpp --sssssssss-----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+// Note:
+// This unit test was adapted from
+// llvm/unittests/Support/ExtensibleRTTITest.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#include "error.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+namespace {
+
+class CustomError : public RTTIExtends<CustomError, ErrorInfoBase> {
+public:
+ CustomError(int V1) : V1(V1) {}
+ std::string toString() const override {
+ return "CustomError V1 = " + std::to_string(V1);
+ }
+ int getV1() const { return V1; }
+
+protected:
+ int V1;
+};
+
+class CustomSubError : public RTTIExtends<CustomSubError, CustomError> {
+public:
+ CustomSubError(int V1, std::string V2)
+ : RTTIExtends<CustomSubError, CustomError>(V1), V2(std::move(V2)) {}
+ std::string toString() const override {
+ return "CustomSubError V1 = " + std::to_string(V1) + ", " + V2;
+ }
+ const std::string &getV2() const { return V2; }
+
+protected:
+ std::string V2;
+};
+
+} // end anonymous namespace
+
+// Test that a checked success value doesn't cause any issues.
+TEST(Error, CheckedSuccess) {
+ Error E = Error::success();
+ EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'";
+}
+
+// Check that a consumed success value doesn't cause any issues.
+TEST(Error, ConsumeSuccess) { consumeError(Error::success()); }
+
+TEST(Error, ConsumeError) {
+ Error E = make_error<CustomError>(42);
+ if (E) {
+ consumeError(std::move(E));
+ } else
+ ADD_FAILURE() << "Error failure value should convert to true";
+}
+
+// Test that unchecked success values cause an abort.
+TEST(Error, UncheckedSuccess) {
+ EXPECT_DEATH({ Error E = Error::success(); },
+ "Error must be checked prior to destruction")
+ << "Unchecked Error Succes value did not cause abort()";
+}
+
+// Test that a checked but unhandled error causes an abort.
+TEST(Error, CheckedButUnhandledError) {
+ auto DropUnhandledError = []() {
+ Error E = make_error<CustomError>(42);
+ (void)!E;
+ };
+ EXPECT_DEATH(DropUnhandledError(),
+ "Error must be checked prior to destruction")
+ << "Unhandled Error failure value did not cause an abort()";
+}
+
+// Test that error_cast works as expected.
+TEST(Error, BasicErrorCast) {
+ {
+ // Check casting base error value to base error type.
+ auto E = make_error<CustomError>(42);
+ if (auto CSE = error_cast<CustomSubError>(E)) {
+ ADD_FAILURE() << "Derived cast incorrectly matched base error";
+ } else if (auto CE = error_cast<CustomError>(E)) {
+ EXPECT_EQ(CE->getV1(), 42) << "Unexpected wrapped value";
+ } else
+ ADD_FAILURE() << "Unexpected error value";
+ }
+
+ {
+ // Check casting derived error value to base error type.
+ auto E = make_error<CustomSubError>(42, "foo");
+ if (auto CE = error_cast<CustomError>(E)) {
+ EXPECT_EQ(CE->getV1(), 42) << "Unexpected wrapped value";
+ } else
+ ADD_FAILURE() << "Unexpected error value";
+ }
+
+ {
+ // Check casting derived error value to derived error type.
+ auto E = make_error<CustomSubError>(42, "foo");
+ if (auto CSE = error_cast<CustomSubError>(E)) {
+ EXPECT_EQ(CSE->getV1(), 42) << "Unexpected wrapped value";
+ EXPECT_EQ(CSE->getV2(), "foo") << "Unexpected wrapped value";
+ } else
+ ADD_FAILURE() << "Unexpected error value";
+ }
+}
+
+// ErrorAsOutParameter tester.
+static void errAsOutParamHelper(Error &Err) {
+ ErrorAsOutParameter ErrAsOutParam(&Err);
+ // Verify that checked flag is raised - assignment should not crash.
+ Err = Error::success();
+ // Raise the checked bit manually - caller should still have to test the
+ // error.
+ (void)!!Err;
+}
+
+// Test that ErrorAsOutParameter sets the checked flag on construction.
+TEST(Error, ErrorAsOutParameterChecked) {
+ Error E = Error::success();
+ errAsOutParamHelper(E);
+ (void)!!E;
+}
+
+// Test that ErrorAsOutParameter clears the checked flag on destruction.
+TEST(Error, ErrorAsOutParameterUnchecked) {
+ EXPECT_DEATH(
+ {
+ Error E = Error::success();
+ errAsOutParamHelper(E);
+ },
+ "Error must be checked prior to destruction")
+ << "ErrorAsOutParameter did not clear the checked flag on destruction.";
+}
+
+// Check 'Error::isA<T>' method handling.
+TEST(Error, IsAHandling) {
+ // Check 'isA' handling.
+ Error E = make_error<CustomError>(42);
+ Error F = make_error<CustomSubError>(42, "foo");
+ Error G = Error::success();
+
+ EXPECT_TRUE(E.isA<CustomError>());
+ EXPECT_FALSE(E.isA<CustomSubError>());
+ EXPECT_TRUE(F.isA<CustomError>());
+ EXPECT_TRUE(F.isA<CustomSubError>());
+ EXPECT_FALSE(G.isA<CustomError>());
+
+ consumeError(std::move(E));
+ consumeError(std::move(F));
+ consumeError(std::move(G));
+}
+
+TEST(Error, StringError) {
+ auto E = make_error<StringError>("foo");
+ if (auto SE = error_cast<StringError>(E)) {
+ EXPECT_EQ(SE->toString(), "foo") << "Unexpected StringError value";
+ } else
+ ADD_FAILURE() << "Expected StringError value";
+}
+
+// Test Checked Expected<T> in success mode.
+TEST(Error, CheckedExpectedInSuccessMode) {
+ Expected<int> A = 7;
+ EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'";
+ // Access is safe in second test, since we checked the error in the first.
+ EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value";
+}
+
+// Test Expected with reference type.
+TEST(Error, ExpectedWithReferenceType) {
+ int A = 7;
+ Expected<int &> B = A;
+ // 'Check' B.
+ (void)!!B;
+ int &C = *B;
+ EXPECT_EQ(&A, &C) << "Expected failed to propagate reference";
+}
+
+// Test Unchecked Expected<T> in success mode.
+// We expect this to blow up the same way Error would.
+// Test runs in debug mode only.
+TEST(Error, UncheckedExpectedInSuccessModeDestruction) {
+ EXPECT_DEATH({ Expected<int> A = 7; },
+ "Expected<T> must be checked before access or destruction.")
+ << "Unchecekd Expected<T> success value did not cause an abort().";
+}
+
+// Test Unchecked Expected<T> in success mode.
+// We expect this to blow up the same way Error would.
+// Test runs in debug mode only.
+TEST(Error, UncheckedExpectedInSuccessModeAccess) {
+ EXPECT_DEATH(
+ {
+ Expected<int> A = 7;
+ *A;
+ },
+ "Expected<T> must be checked before access or destruction.")
+ << "Unchecekd Expected<T> success value did not cause an abort().";
+}
+
+// Test Unchecked Expected<T> in success mode.
+// We expect this to blow up the same way Error would.
+// Test runs in debug mode only.
+TEST(Error, UncheckedExpectedInSuccessModeAssignment) {
+ EXPECT_DEATH(
+ {
+ Expected<int> A = 7;
+ A = 7;
+ },
+ "Expected<T> must be checked before access or destruction.")
+ << "Unchecekd Expected<T> success value did not cause an abort().";
+}
+
+// Test Expected<T> in failure mode.
+TEST(Error, ExpectedInFailureMode) {
+ Expected<int> A = make_error<CustomError>(42);
+ EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'";
+ Error E = A.takeError();
+ EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value";
+ consumeError(std::move(E));
+}
+
+// Check that an Expected instance with an error value doesn't allow access to
+// operator*.
+// Test runs in debug mode only.
+TEST(Error, AccessExpectedInFailureMode) {
+ Expected<int> A = make_error<CustomError>(42);
+ EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.")
+ << "Incorrect Expected error value";
+ consumeError(A.takeError());
+}
+
+// Check that an Expected instance with an error triggers an abort if
+// unhandled.
+// Test runs in debug mode only.
+TEST(Error, UnhandledExpectedInFailureMode) {
+ EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); },
+ "Expected<T> must be checked before access or destruction.")
+ << "Unchecked Expected<T> failure value did not cause an abort()";
+}
+
+// Test covariance of Expected.
+TEST(Error, ExpectedCovariance) {
+ class B {};
+ class D : public B {};
+
+ Expected<B *> A1(Expected<D *>(nullptr));
+ // Check A1 by converting to bool before assigning to it.
+ (void)!!A1;
+ A1 = Expected<D *>(nullptr);
+ // Check A1 again before destruction.
+ (void)!!A1;
+
+ Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr));
+ // Check A2 by converting to bool before assigning to it.
+ (void)!!A2;
+ A2 = Expected<std::unique_ptr<D>>(nullptr);
+ // Check A2 again before destruction.
+ (void)!!A2;
+}
+
+// Test that the ExitOnError utility works as expected.
+TEST(Error, CantFailSuccess) {
+ cantFail(Error::success());
+
+ int X = cantFail(Expected<int>(42));
+ EXPECT_EQ(X, 42) << "Expected value modified by cantFail";
+
+ int Dummy = 42;
+ int &Y = cantFail(Expected<int &>(Dummy));
+ EXPECT_EQ(&Dummy, &Y) << "Reference mangled by cantFail";
+}
+
+// Test that cantFail results in a crash if you pass it a failure value.
+TEST(Error, CantFailDeath) {
+ EXPECT_DEATH(cantFail(make_error<StringError>("foo")),
+ "cantFail called on failure value")
+ << "cantFail(Error) did not cause an abort for failure value";
+
+ EXPECT_DEATH(cantFail(Expected<int>(make_error<StringError>("foo"))),
+ "cantFail called on failure value")
+ << "cantFail(Expected<int>) did not cause an abort for failure value";
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_address_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_address_test.cpp
new file mode 100644
index 000000000000..05b91f3f8609
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_address_test.cpp
@@ -0,0 +1,115 @@
+//===-- executor_address_test.cpp -----------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+// Note:
+// This unit test was adapted from
+// llvm/unittests/Support/ExecutorAddressTest.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#include "executor_address.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(ExecutorAddrTest, DefaultAndNull) {
+ // Check that default constructed values and isNull behave as expected.
+
+ ExecutorAddr Default;
+ ExecutorAddr Null(0);
+ ExecutorAddr NonNull(1);
+
+ EXPECT_TRUE(Null.isNull());
+ EXPECT_EQ(Default, Null);
+
+ EXPECT_FALSE(NonNull.isNull());
+ EXPECT_NE(Default, NonNull);
+}
+
+TEST(ExecutorAddrTest, Ordering) {
+ // Check that ordering operations.
+ ExecutorAddr A1(1), A2(2);
+
+ EXPECT_LE(A1, A1);
+ EXPECT_LT(A1, A2);
+ EXPECT_GT(A2, A1);
+ EXPECT_GE(A2, A2);
+}
+
+TEST(ExecutorAddrTest, PtrConversion) {
+ // Test toPtr / fromPtr round-tripping.
+ int X = 0;
+ auto XAddr = ExecutorAddr::fromPtr(&X);
+ int *XPtr = XAddr.toPtr<int *>();
+
+ EXPECT_EQ(XPtr, &X);
+}
+
+static void F() {}
+
+TEST(ExecutorAddrTest, PtrConversionWithFunctionType) {
+ // Test that function types (as opposed to function pointer types) can be
+ // used with toPtr.
+ auto FAddr = ExecutorAddr::fromPtr(F);
+ void (*FPtr)() = FAddr.toPtr<void()>();
+
+ EXPECT_EQ(FPtr, &F);
+}
+
+TEST(ExecutorAddrTest, WrappingAndUnwrapping) {
+ constexpr uintptr_t RawAddr = 0x123456;
+ int *RawPtr = (int *)RawAddr;
+
+ constexpr uintptr_t TagOffset = 8 * (sizeof(uintptr_t) - 1);
+ uintptr_t TagVal = 0xA5;
+ uintptr_t TagBits = TagVal << TagOffset;
+ void *TaggedPtr = (void *)((uintptr_t)RawPtr | TagBits);
+
+ ExecutorAddr EA =
+ ExecutorAddr::fromPtr(TaggedPtr, ExecutorAddr::Untag(8, TagOffset));
+
+ EXPECT_EQ(EA.getValue(), RawAddr);
+
+ void *ReconstitutedTaggedPtr =
+ EA.toPtr<void *>(ExecutorAddr::Tag(TagVal, TagOffset));
+
+ EXPECT_EQ(TaggedPtr, ReconstitutedTaggedPtr);
+}
+
+TEST(ExecutorAddrTest, AddrRanges) {
+ ExecutorAddr A0(0), A1(1), A2(2), A3(3);
+ ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3);
+ // 012
+ // R0: # -- Before R1
+ // R1: # --
+ // R2: # -- After R1
+ // R3: ## -- Overlaps R1 start
+ // R4: ## -- Overlaps R1 end
+
+ EXPECT_EQ(R1, ExecutorAddrRange(A1, A2));
+ EXPECT_EQ(R1, ExecutorAddrRange(A1, ExecutorAddrDiff(1)));
+ EXPECT_NE(R1, R2);
+
+ EXPECT_TRUE(R1.contains(A1));
+ EXPECT_FALSE(R1.contains(A0));
+ EXPECT_FALSE(R1.contains(A2));
+
+ EXPECT_FALSE(R1.overlaps(R0));
+ EXPECT_FALSE(R1.overlaps(R2));
+ EXPECT_TRUE(R1.overlaps(R3));
+ EXPECT_TRUE(R1.overlaps(R4));
+}
+
+TEST(ExecutorAddrTest, Hashable) {
+ uint64_t RawAddr = 0x1234567890ABCDEF;
+ ExecutorAddr Addr(RawAddr);
+
+ EXPECT_EQ(std::hash<uint64_t>()(RawAddr), std::hash<ExecutorAddr>()(Addr));
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_symbol_def_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_symbol_def_test.cpp
new file mode 100644
index 000000000000..181091ca1e60
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/executor_symbol_def_test.cpp
@@ -0,0 +1,19 @@
+//===-- executor_symbol_def_test.cpp --------------------------------------===//
+//
+// 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 "executor_symbol_def.h"
+#include "simple_packed_serialization_utils.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(ExecutorSymbolDefTest, Serialization) {
+ blobSerializationRoundTrip<SPSExecutorSymbolDef>(ExecutorSymbolDef{});
+ blobSerializationRoundTrip<SPSExecutorSymbolDef>(
+ ExecutorSymbolDef{ExecutorAddr{0x70}, {JITSymbolFlags::Callable, 9}});
+} \ No newline at end of file
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/extensible_rtti_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/extensible_rtti_test.cpp
new file mode 100644
index 000000000000..feca1ec1d18c
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/extensible_rtti_test.cpp
@@ -0,0 +1,54 @@
+//===-- extensible_rtti_test.cpp ------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+// Note:
+// This unit test was adapted from
+// llvm/unittests/Support/ExtensibleRTTITest.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#include "extensible_rtti.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+namespace {
+
+class MyBase : public RTTIExtends<MyBase, RTTIRoot> {};
+
+class MyDerivedA : public RTTIExtends<MyDerivedA, MyBase> {};
+
+class MyDerivedB : public RTTIExtends<MyDerivedB, MyBase> {};
+
+} // end anonymous namespace
+
+TEST(ExtensibleRTTITest, BaseCheck) {
+ MyBase MB;
+ MyDerivedA MDA;
+ MyDerivedB MDB;
+
+ // Check MB properties.
+ EXPECT_TRUE(isa<RTTIRoot>(MB));
+ EXPECT_TRUE(isa<MyBase>(MB));
+ EXPECT_FALSE(isa<MyDerivedA>(MB));
+ EXPECT_FALSE(isa<MyDerivedB>(MB));
+
+ // Check MDA properties.
+ EXPECT_TRUE(isa<RTTIRoot>(MDA));
+ EXPECT_TRUE(isa<MyBase>(MDA));
+ EXPECT_TRUE(isa<MyDerivedA>(MDA));
+ EXPECT_FALSE(isa<MyDerivedB>(MDA));
+
+ // Check MDB properties.
+ EXPECT_TRUE(isa<RTTIRoot>(MDB));
+ EXPECT_TRUE(isa<MyBase>(MDB));
+ EXPECT_FALSE(isa<MyDerivedA>(MDB));
+ EXPECT_TRUE(isa<MyDerivedB>(MDB));
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_map_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_map_test.cpp
new file mode 100644
index 000000000000..a1c6958fcd52
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_map_test.cpp
@@ -0,0 +1,204 @@
+//===-- interval_map_test.cpp ---------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "interval_map.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(IntervalMapTest, DefaultConstructed) {
+ // Check that a default-constructed IntervalMap behaves as expected.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
+
+ EXPECT_TRUE(M.empty());
+ EXPECT_TRUE(M.begin() == M.end());
+ EXPECT_TRUE(M.find(0) == M.end());
+}
+
+TEST(IntervalMapTest, InsertSingleElement) {
+ // Check that a map with a single element inserted behaves as expected.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
+
+ M.insert(7, 8, 42);
+
+ EXPECT_FALSE(M.empty());
+ EXPECT_EQ(std::next(M.begin()), M.end());
+ EXPECT_EQ(M.find(7), M.begin());
+ EXPECT_EQ(M.find(8), M.end());
+ EXPECT_EQ(M.lookup(7), 42U);
+ EXPECT_EQ(M.lookup(8), 0U); // 8 not present, so should return unsigned().
+}
+
+TEST(IntervalMapTest, InsertCoalesceWithPrevious) {
+ // Check that insertions coalesce with previous ranges that share the same
+ // value. Also check that they _don't_ coalesce if the values are different.
+
+ // Check that insertion coalesces with previous range when values are equal.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
+
+ M1.insert(7, 8, 42);
+ M1.insert(8, 9, 42);
+
+ EXPECT_FALSE(M1.empty());
+ EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
+ EXPECT_EQ(M1.find(7), M1.find(8)); // 7 and 8 should point to same range.
+ EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
+
+ // Check that insertion does not coalesce with previous range when values are
+ // not equal.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
+
+ M2.insert(7, 8, 42);
+ M2.insert(8, 9, 7);
+
+ EXPECT_FALSE(M2.empty());
+ EXPECT_EQ(std::next(std::next(M2.begin())), M2.end()); // Expect two ranges.
+ EXPECT_NE(M2.find(7), M2.find(8)); // 7 and 8 should be different ranges.
+ EXPECT_EQ(M2.lookup(7), 42U); // Keys 7 and 8 should map to different values.
+ EXPECT_EQ(M2.lookup(8), 7U);
+}
+
+TEST(IntervalMapTest, InsertCoalesceWithFollowing) {
+ // Check that insertions coalesce with following ranges that share the same
+ // value. Also check that they _don't_ coalesce if the values are different.
+
+ // Check that insertion coalesces with following range when values are equal.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
+
+ M1.insert(8, 9, 42);
+ M1.insert(7, 8, 42);
+
+ EXPECT_FALSE(M1.empty());
+ EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
+ EXPECT_EQ(M1.find(7), M1.find(8)); // 7 and 8 should point to same range.
+ EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
+
+ // Check that insertion does not coalesce with previous range when values are
+ // not equal.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
+
+ M2.insert(8, 9, 42);
+ M2.insert(7, 8, 7);
+
+ EXPECT_FALSE(M2.empty());
+ EXPECT_EQ(std::next(std::next(M2.begin())), M2.end()); // Expect two ranges.
+ EXPECT_EQ(M2.lookup(7), 7U); // Keys 7 and 8 should map to different values.
+ EXPECT_EQ(M2.lookup(8), 42U);
+}
+
+TEST(IntervalMapTest, InsertCoalesceBoth) {
+ // Check that insertions coalesce with ranges on both sides where posssible.
+ // Also check that they _don't_ coalesce if the values are different.
+
+ // Check that insertion coalesces with both previous and following ranges
+ // when values are equal.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
+
+ M1.insert(7, 8, 42);
+ M1.insert(9, 10, 42);
+
+ // Check no coalescing yet.
+ EXPECT_NE(M1.find(7), M1.find(9));
+
+ // Insert a 3rd range to trigger coalescing on both sides.
+ M1.insert(8, 9, 42);
+
+ EXPECT_FALSE(M1.empty());
+ EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
+ EXPECT_EQ(M1.find(7), M1.find(8)); // 7, 8, and 9 should point to same range.
+ EXPECT_EQ(M1.find(8), M1.find(9));
+ EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
+
+ // Check that insertion does not coalesce with previous range when values are
+ // not equal.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
+
+ M2.insert(7, 8, 42);
+ M2.insert(8, 9, 7);
+ M2.insert(9, 10, 42);
+
+ EXPECT_FALSE(M2.empty());
+ // Expect three ranges.
+ EXPECT_EQ(std::next(std::next(std::next(M2.begin()))), M2.end());
+ EXPECT_NE(M2.find(7), M2.find(8)); // All keys should map to different ranges.
+ EXPECT_NE(M2.find(8), M2.find(9));
+ EXPECT_EQ(M2.lookup(7), 42U); // Key 7, 8, and 9 should map to different vals.
+ EXPECT_EQ(M2.lookup(8), 7U);
+ EXPECT_EQ(M2.lookup(9), 42U);
+}
+
+TEST(IntervalMapTest, EraseSingleElement) {
+ // Check that we can insert and then remove a single range.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
+
+ M.insert(7, 10, 42);
+ EXPECT_FALSE(M.empty());
+ M.erase(7, 10);
+ EXPECT_TRUE(M.empty());
+}
+
+TEST(IntervalMapTest, EraseSplittingLeft) {
+ // Check that removal of a trailing subrange succeeds, but leaves the
+ // residual range in-place.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
+
+ M.insert(7, 10, 42);
+ EXPECT_FALSE(M.empty());
+ M.erase(9, 10);
+ EXPECT_EQ(std::next(M.begin()), M.end());
+ EXPECT_EQ(M.begin()->first.first, 7U);
+ EXPECT_EQ(M.begin()->first.second, 9U);
+}
+
+TEST(IntervalMapTest, EraseSplittingRight) {
+ // Check that removal of a leading subrange succeeds, but leaves the
+ // residual range in-place.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
+
+ M.insert(7, 10, 42);
+ EXPECT_FALSE(M.empty());
+ M.erase(7, 8);
+ EXPECT_EQ(std::next(M.begin()), M.end());
+ EXPECT_EQ(M.begin()->first.first, 8U);
+ EXPECT_EQ(M.begin()->first.second, 10U);
+}
+
+TEST(IntervalMapTest, EraseSplittingBoth) {
+ // Check that removal of an interior subrange leaves both the leading and
+ // trailing residual subranges in-place.
+ IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
+
+ M.insert(7, 10, 42);
+ EXPECT_FALSE(M.empty());
+ M.erase(8, 9);
+ EXPECT_EQ(std::next(std::next(M.begin())), M.end());
+ EXPECT_EQ(M.begin()->first.first, 7U);
+ EXPECT_EQ(M.begin()->first.second, 8U);
+ EXPECT_EQ(std::next(M.begin())->first.first, 9U);
+ EXPECT_EQ(std::next(M.begin())->first.second, 10U);
+}
+
+TEST(IntervalMapTest, NonCoalescingMapPermitsNonComparableKeys) {
+ // Test that values that can't be equality-compared are still usable when
+ // coalescing is disabled and behave as expected.
+
+ struct S {}; // Struct with no equality comparison.
+
+ IntervalMap<unsigned, S, IntervalCoalescing::Disabled> M;
+
+ M.insert(7, 8, S());
+
+ EXPECT_FALSE(M.empty());
+ EXPECT_EQ(std::next(M.begin()), M.end());
+ EXPECT_EQ(M.find(7), M.begin());
+ EXPECT_EQ(M.find(8), M.end());
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_set_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_set_test.cpp
new file mode 100644
index 000000000000..7971a55f271f
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/interval_set_test.cpp
@@ -0,0 +1,121 @@
+//===-- interval_set_test.cpp ---------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "interval_set.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(IntervalSetTest, DefaultConstructed) {
+ // Check that a default-constructed IntervalSet behaves as expected.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ EXPECT_TRUE(S.empty());
+ EXPECT_TRUE(S.begin() == S.end());
+ EXPECT_TRUE(S.find(0) == S.end());
+}
+
+TEST(IntervalSetTest, InsertSingleElement) {
+ // Check that a set with a single element inserted behaves as expected.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(7, 8);
+
+ EXPECT_FALSE(S.empty());
+ EXPECT_EQ(std::next(S.begin()), S.end());
+ EXPECT_EQ(S.find(7), S.begin());
+ EXPECT_EQ(S.find(8), S.end());
+}
+
+TEST(IntervalSetTest, InsertCoalesceWithPrevious) {
+ // Check that insertions coalesce with previous ranges.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(7, 8);
+ S.insert(8, 9);
+
+ EXPECT_FALSE(S.empty());
+ EXPECT_EQ(std::next(S.begin()), S.end()); // Should see just one range.
+ EXPECT_EQ(S.find(7), S.find(8)); // 7 and 8 should point to same range.
+}
+
+TEST(IntervalSetTest, InsertCoalesceWithFollowing) {
+ // Check that insertions coalesce with following ranges.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(8, 9);
+ S.insert(7, 8);
+
+ EXPECT_FALSE(S.empty());
+ EXPECT_EQ(std::next(S.begin()), S.end()); // Should see just one range.
+ EXPECT_EQ(S.find(7), S.find(8)); // 7 and 8 should point to same range.
+}
+
+TEST(IntervalSetTest, InsertCoalesceBoth) {
+ // Check that insertions coalesce with ranges on both sides.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(7, 8);
+ S.insert(9, 10);
+
+ // Check no coalescing yet.
+ EXPECT_NE(S.find(7), S.find(9));
+
+ // Insert a 3rd range to trigger coalescing on both sides.
+ S.insert(8, 9);
+
+ EXPECT_FALSE(S.empty());
+ EXPECT_EQ(std::next(S.begin()), S.end()); // Should see just one range.
+ EXPECT_EQ(S.find(7), S.find(8)); // 7, 8, and 9 should point to same range.
+ EXPECT_EQ(S.find(8), S.find(9));
+}
+
+TEST(IntervalSetTest, EraseSplittingLeft) {
+ // Check that removal of a trailing subrange succeeds, but leaves the
+ // residual range in-place.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(7, 10);
+ EXPECT_FALSE(S.empty());
+ S.erase(9, 10);
+ EXPECT_EQ(std::next(S.begin()), S.end());
+ EXPECT_EQ(S.begin()->first, 7U);
+ EXPECT_EQ(S.begin()->second, 9U);
+}
+
+TEST(IntervalSetTest, EraseSplittingRight) {
+ // Check that removal of a leading subrange succeeds, but leaves the
+ // residual range in-place.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(7, 10);
+ EXPECT_FALSE(S.empty());
+ S.erase(7, 8);
+ EXPECT_EQ(std::next(S.begin()), S.end());
+ EXPECT_EQ(S.begin()->first, 8U);
+ EXPECT_EQ(S.begin()->second, 10U);
+}
+
+TEST(IntervalSetTest, EraseSplittingBoth) {
+ // Check that removal of an interior subrange leaves both the leading and
+ // trailing residual subranges in-place.
+ IntervalSet<unsigned, IntervalCoalescing::Enabled> S;
+
+ S.insert(7, 10);
+ EXPECT_FALSE(S.empty());
+ S.erase(8, 9);
+ EXPECT_EQ(std::next(std::next(S.begin())), S.end());
+ EXPECT_EQ(S.begin()->first, 7U);
+ EXPECT_EQ(S.begin()->second, 8U);
+ EXPECT_EQ(std::next(S.begin())->first, 9U);
+ EXPECT_EQ(std::next(S.begin())->second, 10U);
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/orc_unit_test_main.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/orc_unit_test_main.cpp
new file mode 100644
index 000000000000..d02101704d65
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/orc_unit_test_main.cpp
@@ -0,0 +1,18 @@
+//===-- orc_unit_test_main.cpp --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+#include "gtest/gtest.h"
+
+int main(int argc, char **argv) {
+ testing::GTEST_FLAG(death_test_style) = "threadsafe";
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp
new file mode 100644
index 000000000000..397114b4017e
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_test.cpp
@@ -0,0 +1,184 @@
+//===-- simple_packed_serialization_test.cpp ------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "simple_packed_serialization.h"
+#include "simple_packed_serialization_utils.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+TEST(SimplePackedSerializationTest, SPSOutputBuffer) {
+ constexpr unsigned NumBytes = 8;
+ char Buffer[NumBytes];
+ char Zero = 0;
+ SPSOutputBuffer OB(Buffer, NumBytes);
+
+ // Expect that we can write NumBytes of content.
+ for (unsigned I = 0; I != NumBytes; ++I) {
+ char C = I;
+ EXPECT_TRUE(OB.write(&C, 1));
+ }
+
+ // Expect an error when we attempt to write an extra byte.
+ EXPECT_FALSE(OB.write(&Zero, 1));
+
+ // Check that the buffer contains the expected content.
+ for (unsigned I = 0; I != NumBytes; ++I)
+ EXPECT_EQ(Buffer[I], (char)I);
+}
+
+TEST(SimplePackedSerializationTest, SPSInputBuffer) {
+ char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+ SPSInputBuffer IB(Buffer, sizeof(Buffer));
+
+ char C;
+ for (unsigned I = 0; I != sizeof(Buffer); ++I) {
+ EXPECT_TRUE(IB.read(&C, 1));
+ EXPECT_EQ(C, (char)I);
+ }
+
+ EXPECT_FALSE(IB.read(&C, 1));
+}
+
+template <typename T> static void testFixedIntegralTypeSerialization() {
+ blobSerializationRoundTrip<T, T>(0);
+ blobSerializationRoundTrip<T, T>(static_cast<T>(1));
+ if (std::is_signed<T>::value) {
+ blobSerializationRoundTrip<T, T>(static_cast<T>(-1));
+ blobSerializationRoundTrip<T, T>(std::numeric_limits<T>::min());
+ }
+ blobSerializationRoundTrip<T, T>(std::numeric_limits<T>::max());
+}
+
+TEST(SimplePackedSerializationTest, BoolSerialization) {
+ blobSerializationRoundTrip<bool, bool>(true);
+ blobSerializationRoundTrip<bool, bool>(false);
+}
+
+TEST(SimplePackedSerializationTest, CharSerialization) {
+ blobSerializationRoundTrip<char, char>((char)0x00);
+ blobSerializationRoundTrip<char, char>((char)0xAA);
+ blobSerializationRoundTrip<char, char>((char)0xFF);
+}
+
+TEST(SimplePackedSerializationTest, Int8Serialization) {
+ testFixedIntegralTypeSerialization<int8_t>();
+}
+
+TEST(SimplePackedSerializationTest, UInt8Serialization) {
+ testFixedIntegralTypeSerialization<uint8_t>();
+}
+
+TEST(SimplePackedSerializationTest, Int16Serialization) {
+ testFixedIntegralTypeSerialization<int16_t>();
+}
+
+TEST(SimplePackedSerializationTest, UInt16Serialization) {
+ testFixedIntegralTypeSerialization<uint16_t>();
+}
+
+TEST(SimplePackedSerializationTest, Int32Serialization) {
+ testFixedIntegralTypeSerialization<int32_t>();
+}
+
+TEST(SimplePackedSerializationTest, UInt32Serialization) {
+ testFixedIntegralTypeSerialization<uint32_t>();
+}
+
+TEST(SimplePackedSerializationTest, Int64Serialization) {
+ testFixedIntegralTypeSerialization<int64_t>();
+}
+
+TEST(SimplePackedSerializationTest, UInt64Serialization) {
+ testFixedIntegralTypeSerialization<uint64_t>();
+}
+
+TEST(SimplePackedSerializationTest, SequenceSerialization) {
+ std::vector<int32_t> V({1, 2, -47, 139});
+ blobSerializationRoundTrip<SPSSequence<int32_t>, std::vector<int32_t>>(V);
+}
+
+TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) {
+ const char *HW = "Hello, world!";
+ blobSerializationRoundTrip<SPSString, std::string_view>(std::string_view(HW));
+}
+
+TEST(SimplePackedSerializationTest, SpanSerialization) {
+ const char Data[] = {3, 2, 1, 0, 1, 2, 3}; // Span should handle nulls.
+ span<const char> OutS(Data, sizeof(Data));
+
+ size_t Size = SPSArgList<SPSSequence<char>>::size(OutS);
+ auto Buffer = std::make_unique<char[]>(Size);
+ SPSOutputBuffer OB(Buffer.get(), Size);
+
+ EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, OutS));
+
+ SPSInputBuffer IB(Buffer.get(), Size);
+
+ span<const char> InS;
+
+ EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, InS));
+
+ // Check that the serialized and deserialized values match.
+ EXPECT_EQ(InS.size(), OutS.size());
+ EXPECT_EQ(memcmp(OutS.data(), InS.data(), InS.size()), 0);
+
+ // Check that the span points directly to the input buffer.
+ EXPECT_EQ(InS.data(), Buffer.get() + sizeof(uint64_t));
+}
+
+TEST(SimplePackedSerializationTest, StdTupleSerialization) {
+ std::tuple<int32_t, std::string, bool> P(42, "foo", true);
+ blobSerializationRoundTrip<SPSTuple<int32_t, SPSString, bool>>(P);
+}
+
+TEST(SimplePackedSerializationTest, StdPairSerialization) {
+ std::pair<int32_t, std::string> P(42, "foo");
+ blobSerializationRoundTrip<SPSTuple<int32_t, SPSString>,
+ std::pair<int32_t, std::string>>(P);
+}
+
+TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) {
+ std::optional<int64_t> NoValue;
+ blobSerializationRoundTrip<SPSOptional<int64_t>>(NoValue);
+}
+
+TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
+ std::optional<int64_t> Value(42);
+ blobSerializationRoundTrip<SPSOptional<int64_t>>(Value);
+}
+
+TEST(SimplePackedSerializationTest, ArgListSerialization) {
+ using BAL = SPSArgList<bool, int32_t, SPSString>;
+
+ bool Arg1 = true;
+ int32_t Arg2 = 42;
+ std::string Arg3 = "foo";
+
+ size_t Size = BAL::size(Arg1, Arg2, Arg3);
+ auto Buffer = std::make_unique<char[]>(Size);
+ SPSOutputBuffer OB(Buffer.get(), Size);
+
+ EXPECT_TRUE(BAL::serialize(OB, Arg1, Arg2, Arg3));
+
+ SPSInputBuffer IB(Buffer.get(), Size);
+
+ bool ArgOut1;
+ int32_t ArgOut2;
+ std::string ArgOut3;
+
+ EXPECT_TRUE(BAL::deserialize(IB, ArgOut1, ArgOut2, ArgOut3));
+
+ EXPECT_EQ(Arg1, ArgOut1);
+ EXPECT_EQ(Arg2, ArgOut2);
+ EXPECT_EQ(Arg3, ArgOut3);
+}
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_utils.h b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_utils.h
new file mode 100644
index 000000000000..746be43d250b
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/simple_packed_serialization_utils.h
@@ -0,0 +1,34 @@
+//===-- simple_packed_serialization_utils.h -------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ORC_RT_TEST_SIMPLE_PACKED_SERIALIZATION_UTILS_H
+#define ORC_RT_TEST_SIMPLE_PACKED_SERIALIZATION_UTILS_H
+
+#include "simple_packed_serialization.h"
+#include "gtest/gtest.h"
+
+template <typename SPSTagT, typename T>
+static void blobSerializationRoundTrip(const T &Value) {
+ using BST = __orc_rt::SPSSerializationTraits<SPSTagT, T>;
+
+ size_t Size = BST::size(Value);
+ auto Buffer = std::make_unique<char[]>(Size);
+ __orc_rt::SPSOutputBuffer OB(Buffer.get(), Size);
+
+ EXPECT_TRUE(BST::serialize(OB, Value));
+
+ __orc_rt::SPSInputBuffer IB(Buffer.get(), Size);
+
+ T DSValue;
+ EXPECT_TRUE(BST::deserialize(IB, DSValue));
+
+ EXPECT_EQ(Value, DSValue)
+ << "Incorrect value after serialization/deserialization round-trip";
+}
+
+#endif // ORC_RT_TEST_SIMPLE_PACKED_SERIALIZATION_UTILS_H \ No newline at end of file
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/string_pool_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/string_pool_test.cpp
new file mode 100644
index 000000000000..15ee2ce7d24d
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/string_pool_test.cpp
@@ -0,0 +1,66 @@
+//===---------- string_pool_test.cpp - Unit tests for StringPool ----------===//
+//
+// 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 "string_pool.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+namespace {
+
+TEST(StringPool, UniquingAndComparisons) {
+ StringPool SP;
+ auto P1 = SP.intern("hello");
+
+ std::string S("hel");
+ S += "lo";
+ auto P2 = SP.intern(S);
+
+ auto P3 = SP.intern("goodbye");
+
+ EXPECT_EQ(P1, P2) << "Failed to unique entries";
+ EXPECT_NE(P1, P3) << "Unequal pooled strings comparing equal";
+
+ // We want to test that less-than comparison of PooledStringPtrs compiles,
+ // however we can't test the actual result as this is a pointer comparison and
+ // PooledStringPtr doesn't expose the underlying address of the string.
+ (void)(P1 < P3);
+}
+
+TEST(StringPool, Dereference) {
+ StringPool SP;
+ auto Foo = SP.intern("foo");
+ EXPECT_EQ(*Foo, "foo") << "Equality on dereferenced string failed";
+}
+
+TEST(StringPool, ClearDeadEntries) {
+ StringPool SP;
+ {
+ auto P1 = SP.intern("s1");
+ SP.clearDeadEntries();
+ EXPECT_FALSE(SP.empty()) << "\"s1\" entry in pool should still be retained";
+ }
+ SP.clearDeadEntries();
+ EXPECT_TRUE(SP.empty()) << "pool should be empty";
+}
+
+TEST(StringPool, NullPtr) {
+ // Make sure that we can default construct and then destroy a null
+ // PooledStringPtr.
+ PooledStringPtr Null;
+}
+
+TEST(StringPool, Hashable) {
+ StringPool SP;
+ PooledStringPtr P1 = SP.intern("s1");
+ PooledStringPtr Null;
+ EXPECT_NE(std::hash<PooledStringPtr>()(P1),
+ std::hash<PooledStringPtr>()(Null));
+}
+
+} // end anonymous namespace
diff --git a/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp
new file mode 100644
index 000000000000..f10c5093046d
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/orc/tests/unit/wrapper_function_utils_test.cpp
@@ -0,0 +1,184 @@
+//===-- wrapper_function_utils_test.cpp -----------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of the ORC runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "wrapper_function_utils.h"
+#include "gtest/gtest.h"
+
+using namespace __orc_rt;
+
+namespace {
+constexpr const char *TestString = "test string";
+} // end anonymous namespace
+
+TEST(WrapperFunctionUtilsTest, DefaultWrapperFunctionResult) {
+ WrapperFunctionResult R;
+ EXPECT_TRUE(R.empty());
+ EXPECT_EQ(R.size(), 0U);
+ EXPECT_EQ(R.getOutOfBandError(), nullptr);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromCStruct) {
+ orc_rt_CWrapperFunctionResult CR =
+ orc_rt_CreateCWrapperFunctionResultFromString(TestString);
+ WrapperFunctionResult R(CR);
+ EXPECT_EQ(R.size(), strlen(TestString) + 1);
+ EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
+ EXPECT_FALSE(R.empty());
+ EXPECT_EQ(R.getOutOfBandError(), nullptr);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromRange) {
+ auto R = WrapperFunctionResult::copyFrom(TestString, strlen(TestString) + 1);
+ EXPECT_EQ(R.size(), strlen(TestString) + 1);
+ EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
+ EXPECT_FALSE(R.empty());
+ EXPECT_EQ(R.getOutOfBandError(), nullptr);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromCString) {
+ auto R = WrapperFunctionResult::copyFrom(TestString);
+ EXPECT_EQ(R.size(), strlen(TestString) + 1);
+ EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
+ EXPECT_FALSE(R.empty());
+ EXPECT_EQ(R.getOutOfBandError(), nullptr);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromStdString) {
+ auto R = WrapperFunctionResult::copyFrom(std::string(TestString));
+ EXPECT_EQ(R.size(), strlen(TestString) + 1);
+ EXPECT_TRUE(strcmp(R.data(), TestString) == 0);
+ EXPECT_FALSE(R.empty());
+ EXPECT_EQ(R.getOutOfBandError(), nullptr);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionResultFromOutOfBandError) {
+ auto R = WrapperFunctionResult::createOutOfBandError(TestString);
+ EXPECT_FALSE(R.empty());
+ EXPECT_TRUE(strcmp(R.getOutOfBandError(), TestString) == 0);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionCCallCreateEmpty) {
+ EXPECT_TRUE(!!WrapperFunctionCall::Create<SPSArgList<>>(ExecutorAddr()));
+}
+
+static void voidNoop() {}
+
+static orc_rt_CWrapperFunctionResult voidNoopWrapper(const char *ArgData,
+ size_t ArgSize) {
+ return WrapperFunction<void()>::handle(ArgData, ArgSize, voidNoop).release();
+}
+
+static orc_rt_CWrapperFunctionResult addWrapper(const char *ArgData,
+ size_t ArgSize) {
+ return WrapperFunction<int32_t(int32_t, int32_t)>::handle(
+ ArgData, ArgSize,
+ [](int32_t X, int32_t Y) -> int32_t { return X + Y; })
+ .release();
+}
+
+extern "C" __orc_rt_Opaque __orc_rt_jit_dispatch_ctx{};
+
+extern "C" orc_rt_CWrapperFunctionResult
+__orc_rt_jit_dispatch(__orc_rt_Opaque *Ctx, const void *FnTag,
+ const char *ArgData, size_t ArgSize) {
+ using WrapperFunctionType =
+ orc_rt_CWrapperFunctionResult (*)(const char *, size_t);
+
+ return reinterpret_cast<WrapperFunctionType>(const_cast<void *>(FnTag))(
+ ArgData, ArgSize);
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionCallVoidNoopAndHandle) {
+ EXPECT_FALSE(!!WrapperFunction<void()>::call((void *)&voidNoopWrapper));
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionCallAddWrapperAndHandle) {
+ int32_t Result;
+ EXPECT_FALSE(!!WrapperFunction<int32_t(int32_t, int32_t)>::call(
+ (void *)&addWrapper, Result, 1, 2));
+ EXPECT_EQ(Result, (int32_t)3);
+}
+
+class AddClass {
+public:
+ AddClass(int32_t X) : X(X) {}
+ int32_t addMethod(int32_t Y) { return X + Y; }
+
+private:
+ int32_t X;
+};
+
+static orc_rt_CWrapperFunctionResult addMethodWrapper(const char *ArgData,
+ size_t ArgSize) {
+ return WrapperFunction<int32_t(SPSExecutorAddr, int32_t)>::handle(
+ ArgData, ArgSize, makeMethodWrapperHandler(&AddClass::addMethod))
+ .release();
+}
+
+TEST(WrapperFunctionUtilsTest, WrapperFunctionMethodCallAndHandleRet) {
+ int32_t Result;
+ AddClass AddObj(1);
+ EXPECT_FALSE(!!WrapperFunction<int32_t(SPSExecutorAddr, int32_t)>::call(
+ (void *)&addMethodWrapper, Result, ExecutorAddr::fromPtr(&AddObj), 2));
+ EXPECT_EQ(Result, (int32_t)3);
+}
+
+static orc_rt_CWrapperFunctionResult sumArrayWrapper(const char *ArgData,
+ size_t ArgSize) {
+ return WrapperFunction<int8_t(SPSExecutorAddrRange)>::handle(
+ ArgData, ArgSize,
+ [](ExecutorAddrRange R) {
+ int8_t Sum = 0;
+ for (char C : R.toSpan<char>())
+ Sum += C;
+ return Sum;
+ })
+ .release();
+}
+
+TEST(WrapperFunctionUtilsTest, SerializedWrapperFunctionCallTest) {
+ {
+ // Check wrapper function calls.
+ char A[] = {1, 2, 3, 4};
+
+ auto WFC =
+ cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
+ ExecutorAddr::fromPtr(sumArrayWrapper),
+ ExecutorAddrRange(ExecutorAddr::fromPtr(A),
+ ExecutorAddrDiff(sizeof(A)))));
+
+ WrapperFunctionResult WFR(WFC.run());
+ EXPECT_EQ(WFR.size(), 1U);
+ EXPECT_EQ(WFR.data()[0], 10);
+ }
+
+ {
+ // Check calls to void functions.
+ auto WFC =
+ cantFail(WrapperFunctionCall::Create<SPSArgList<SPSExecutorAddrRange>>(
+ ExecutorAddr::fromPtr(voidNoopWrapper), ExecutorAddrRange()));
+ auto Err = WFC.runWithSPSRet<void>();
+ EXPECT_FALSE(!!Err);
+ }
+
+ {
+ // Check calls with arguments and return values.
+ auto WFC =
+ cantFail(WrapperFunctionCall::Create<SPSArgList<int32_t, int32_t>>(
+ ExecutorAddr::fromPtr(addWrapper), 2, 4));
+
+ int32_t Result = 0;
+ auto Err = WFC.runWithSPSRet<int32_t>(Result);
+ EXPECT_FALSE(!!Err);
+ EXPECT_EQ(Result, 6);
+ }
+}