diff --git a/llvm/include/llvm/Testing/ADT/StringMap.h b/llvm/include/llvm/Testing/ADT/StringMap.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Testing/ADT/StringMap.h @@ -0,0 +1,46 @@ +//===- llvm/Testing/ADT/StringMap.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 LLVM_TESTING_ADT_STRINGMAP_H_ +#define LLVM_TESTING_ADT_STRINGMAP_H_ + +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Testing/ADT/StringMapEntry.h" +#include +#include + +namespace llvm { + +/// Support for printing to std::ostream, for use with e.g. producing more +/// useful error messages with Google Test. +template +std::ostream &operator<<(std::ostream &OS, const StringMap &M) { + if (M.empty()) { + return OS << "{ }"; + } + + std::vector Lines; + for (const auto &E : M) { + std::ostringstream SS; + SS << E << ","; + Lines.push_back(SS.str()); + } + llvm::sort(Lines); + Lines.insert(Lines.begin(), "{"); + Lines.insert(Lines.end(), "}"); + + return OS << llvm::formatv("{0:$[\n]}", + make_range(Lines.begin(), Lines.end())) + .str(); +} + +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/Testing/ADT/StringMapEntry.h b/llvm/include/llvm/Testing/ADT/StringMapEntry.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Testing/ADT/StringMapEntry.h @@ -0,0 +1,44 @@ +//===- llvm/Testing/ADT/StringMapEntry.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 LLVM_TESTING_ADT_STRINGMAPENTRY_H_ +#define LLVM_TESTING_ADT_STRINGMAPENTRY_H_ + +#include "llvm/ADT/StringMapEntry.h" +#include +#include + +namespace llvm { +namespace detail { + +template > +struct CanOutputToOStream : std::false_type {}; + +template +struct CanOutputToOStream() + << std::declval())>> + : std::true_type {}; + +} // namespace detail + +/// Support for printing to std::ostream, for use with e.g. producing more +/// useful error messages with Google Test. +template +std::ostream &operator<<(std::ostream &OS, const StringMapEntry &E) { + OS << "{\"" << E.getKey().data() << "\": "; + if constexpr (detail::CanOutputToOStream::value) { + OS << E.getValue(); + } else { + OS << "non-printable value"; + } + return OS << "}"; +} + +} // namespace llvm + +#endif diff --git a/llvm/unittests/Testing/ADT/CMakeLists.txt b/llvm/unittests/Testing/ADT/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/llvm/unittests/Testing/ADT/CMakeLists.txt @@ -0,0 +1,7 @@ +set(LLVM_LINK_COMPONENTS + Support + ) + +add_llvm_unittest(TestingADTTests + StringMapTest.cpp + ) diff --git a/llvm/unittests/Testing/ADT/StringMapTest.cpp b/llvm/unittests/Testing/ADT/StringMapTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Testing/ADT/StringMapTest.cpp @@ -0,0 +1,55 @@ +//===- StringMapTest.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 "llvm/Testing/ADT/StringMap.h" +#include "llvm/ADT/StringMap.h" + +#include "gtest/gtest.h" +#include + +namespace llvm { +namespace { + +TEST(StringMapTest, StringMapStream) { + std::ostringstream OS; + StringMap Map; + Map["A"] = 42; + Map["Z"] = 35; + Map["B"] = 7; + OS << Map; + + EXPECT_EQ(OS.str(), R"({ +{"A": 42}, +{"B": 7}, +{"Z": 35}, +})"); +} + +TEST(StringMapTest, NestedStringMapStream) { + std::ostringstream OS; + StringMap> Map; + Map["Z"]; + Map["A"]["Apple"] = 5; + Map["B"]["Bee"] = 3; + Map["A"]["Axe"] = 3; + OS << Map; + + EXPECT_EQ(OS.str(), R"({ +{"A": { +{"Apple": 5}, +{"Axe": 3}, +}}, +{"B": { +{"Bee": 3}, +}}, +{"Z": { }}, +})"); +} + +} // namespace +} // namespace llvm diff --git a/llvm/unittests/Testing/CMakeLists.txt b/llvm/unittests/Testing/CMakeLists.txt --- a/llvm/unittests/Testing/CMakeLists.txt +++ b/llvm/unittests/Testing/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory(ADT) add_subdirectory(Support) diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -4181,6 +4181,16 @@ srcs = ["utils/lit/lit.py"] + glob(["utils/lit/lit/**/*.py"]), ) +cc_library( + name = "TestingADT", + testonly = True, + hdrs = glob([ + "include/llvm/Testing/ADT/*.h", + ]), + copts = llvm_copts, + deps = [":Support"], +) + cc_library( name = "TestingSupport", testonly = True, diff --git a/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/unittests/BUILD.bazel @@ -644,6 +644,23 @@ ], ) +cc_test( + name = "testing_adt_tests", + size = "small", + srcs = glob( + [ + "Testing/ADT/*.cpp", + ], + allow_empty = False, + ), + deps = [ + "//llvm:Support", + "//llvm:TestingADT", + "//llvm:gtest", + "//llvm:gtest_main", + ], +) + cc_test( name = "transforms_tests", size = "small",