-
-
Save zeroomega/fb24b1d1c4252b852200e15fda29384d to your computer and use it in GitHub Desktop.
LLVM's patch over GoogleTest v1.14.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/CMakeLists.txt b/CMakeLists.txt | |
index 089ac987..74a523b6 100644 | |
--- a/CMakeLists.txt | |
+++ b/CMakeLists.txt | |
@@ -1,27 +1,112 @@ | |
-# Note: CMake support is community-based. The maintainers do not use CMake | |
-# internally. | |
+######################################################################## | |
+# Experimental CMake build script for Google Test. | |
+# | |
+# Consider this a prototype. It will change drastically. For now, | |
+# this is only for people on the cutting edge. | |
+# | |
+# To run the tests for Google Test itself on Linux, use 'make test' or | |
+# ctest. You can select which tests to run using 'ctest -R regex'. | |
+# For more options, run 'ctest --help'. | |
+######################################################################## | |
+# | |
+# Project-wide settings | |
-cmake_minimum_required(VERSION 3.13) | |
+if(WIN32) | |
+ add_definitions(-DGTEST_OS_WINDOWS=1) | |
+endif() | |
+ | |
+# Google Test requires headers which need _ALL_SOURCE to build on AIX | |
+if (UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "AIX") | |
+ remove_definitions("-D_XOPEN_SOURCE=700") | |
+ add_definitions("-D_ALL_SOURCE") | |
+endif() | |
+ | |
+if(SUPPORTS_VARIADIC_MACROS_FLAG) | |
+ add_definitions("-Wno-variadic-macros") | |
+endif() | |
+if(SUPPORTS_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS_FLAG) | |
+ add_definitions("-Wno-gnu-zero-variadic-macro-arguments") | |
+endif() | |
+if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG) | |
+ add_definitions("-Wno-covered-switch-default") | |
+endif() | |
+ | |
+set(LLVM_REQUIRES_RTTI 1) | |
+add_definitions( -DGTEST_HAS_RTTI=0 ) | |
+ | |
+if (HAVE_LIBPTHREAD) | |
+ list(APPEND LIBS pthread) | |
+endif() | |
+ | |
+# Do not build unittest libraries automatically, they will be pulled in | |
+# by unittests if these are built. | |
+ | |
+set(BUILDTREE_ONLY BUILDTREE_ONLY) | |
+set(EXCLUDE_FROM_ALL ON) | |
+if (LLVM_INSTALL_GTEST) | |
+ set(EXCLUDE_FROM_ALL OFF) | |
+ set(BUILDTREE_ONLY "") | |
+endif () | |
+ | |
+add_llvm_library(llvm_gtest | |
+ googletest/src/gtest-all.cc | |
+ googlemock/src/gmock-all.cc | |
+ | |
+ LINK_LIBS | |
+ ${LIBS} | |
-project(googletest-distribution) | |
-set(GOOGLETEST_VERSION 1.14.0) | |
+ LINK_COMPONENTS | |
+ Support # Depends on llvm::raw_ostream | |
-if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) | |
- set(CMAKE_CXX_EXTENSIONS OFF) | |
+ # This is a library meant only for the build tree. | |
+ ${BUILDTREE_ONLY} | |
+) | |
+ | |
+# The googletest and googlemock sources don't presently use the 'override' | |
+# keyword, which leads to lots of warnings from -Wsuggest-override. Disable | |
+# that warning here for any targets that link to gtest. | |
+if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG) | |
+ add_definitions("-Wno-suggest-override") | |
+ set_target_properties(llvm_gtest PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override") | |
endif() | |
-enable_testing() | |
+if (NOT LLVM_ENABLE_THREADS) | |
+ target_compile_definitions(llvm_gtest PUBLIC GTEST_HAS_PTHREAD=0) | |
+endif () | |
-include(CMakeDependentOption) | |
-include(GNUInstallDirs) | |
+target_include_directories(llvm_gtest | |
+ PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/googletest/include> | |
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/googlemock/include> | |
+ $<INSTALL_INTERFACE:include/llvm-gtest/> | |
+ $<INSTALL_INTERFACE:include/llvm-gmock/> | |
+ PRIVATE googletest googlemock | |
+ ) | |
-#Note that googlemock target already builds googletest | |
-option(BUILD_GMOCK "Builds the googlemock subproject" ON) | |
-option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) | |
-option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF) | |
+add_subdirectory(UnitTestMain) | |
-if(BUILD_GMOCK) | |
- add_subdirectory( googlemock ) | |
-else() | |
- add_subdirectory( googletest ) | |
+if (LLVM_INSTALL_GTEST) | |
+ install(TARGETS llvm_gtest llvm_gtest_main LLVMTestingSupport LLVMTestingAnnotations | |
+ ARCHIVE DESTINATION "lib${LLVM_LIBDIR_SUFFIX}" COMPONENT llvm_gtest) | |
+ install(DIRECTORY googletest/include/gtest/ DESTINATION include/llvm-gtest/gtest/ COMPONENT llvm_gtest) | |
+ install(DIRECTORY googlemock/include/gmock/ DESTINATION include/llvm-gmock/gmock/ COMPONENT llvm_gtest) | |
endif() | |
+ | |
+# When LLVM_LINK_LLVM_DYLIB is enabled, libLLVM.so is added to the interface | |
+# link libraries for gtest and gtest_main. This means that any target, like | |
+# unittests for example, that links against gtest will be forced to link | |
+# against libLLVM.so. In some cases we may want to statically unittests if they | |
+# need access to symbols that are marked private in libLLVM.so. The only | |
+# way we can make this work is to remove libLLVM.so from the list of interface | |
+# link libraries for gtest and then make gtest users responsible for explicitly | |
+# adding libLLVM.so to their targets link libraries if they need it. | |
+ | |
+function (gtest_remove_dylib_from_link_interface target) | |
+ get_target_property(interface_libs ${target} INTERFACE_LINK_LIBRARIES) | |
+ if (interface_libs) | |
+ list(REMOVE_ITEM interface_libs LLVM) | |
+ set_target_properties(${target} PROPERTIES INTERFACE_LINK_LIBRARIES "${interface_libs}") | |
+ endif() | |
+endfunction() | |
+ | |
+gtest_remove_dylib_from_link_interface(llvm_gtest) | |
+gtest_remove_dylib_from_link_interface(llvm_gtest_main) | |
diff --git a/UnitTestMain/CMakeLists.txt b/UnitTestMain/CMakeLists.txt | |
new file mode 100644 | |
index 00000000..729ea7e3 | |
--- /dev/null | |
+++ b/UnitTestMain/CMakeLists.txt | |
@@ -0,0 +1,16 @@ | |
+set(BUILDTREE_ONLY BUILDTREE_ONLY) | |
+if (LLVM_INSTALL_GTEST) | |
+ set(BUILDTREE_ONLY "") | |
+endif () | |
+ | |
+add_llvm_library(llvm_gtest_main | |
+ TestMain.cpp | |
+ | |
+ LINK_LIBS | |
+ llvm_gtest | |
+ | |
+ LINK_COMPONENTS | |
+ Support # Depends on llvm::cl | |
+ | |
+ ${BUILDTREE_ONLY} | |
+ ) | |
diff --git a/UnitTestMain/TestMain.cpp b/UnitTestMain/TestMain.cpp | |
new file mode 100644 | |
index 00000000..35ba72ba | |
--- /dev/null | |
+++ b/UnitTestMain/TestMain.cpp | |
@@ -0,0 +1,56 @@ | |
+//===--- utils/unittest/UnitTestMain/TestMain.cpp - unittest driver -------===// | |
+// | |
+// 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/Support/CommandLine.h" | |
+#include "llvm/Support/Signals.h" | |
+#include "gmock/gmock.h" | |
+#include "gtest/gtest.h" | |
+#include <stdlib.h> | |
+ | |
+#if defined(_WIN32) | |
+# include <windows.h> | |
+# if defined(_MSC_VER) | |
+# include <crtdbg.h> | |
+# endif | |
+#endif | |
+ | |
+const char *TestMainArgv0; | |
+ | |
+int main(int argc, char **argv) { | |
+ // Skip setting up signal handlers for tests that need to test things without | |
+ // them configured. | |
+ if (!getenv("LLVM_PROGRAM_TEST_NO_STACKTRACE_HANDLER")) { | |
+ llvm::sys::PrintStackTraceOnErrorSignal(argv[0], | |
+ true /* Disable crash reporting */); | |
+ } | |
+ | |
+ // Initialize both gmock and gtest. | |
+ testing::InitGoogleMock(&argc, argv); | |
+ | |
+ llvm::cl::ParseCommandLineOptions(argc, argv); | |
+ | |
+ // Make it easy for a test to re-execute itself by saving argv[0]. | |
+ TestMainArgv0 = argv[0]; | |
+ | |
+# if defined(_WIN32) | |
+ // Disable all of the possible ways Windows conspires to make automated | |
+ // testing impossible. | |
+ ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); | |
+# if defined(_MSC_VER) | |
+ ::_set_error_mode(_OUT_TO_STDERR); | |
+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); | |
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); | |
+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); | |
+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); | |
+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); | |
+ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); | |
+# endif | |
+# endif | |
+ | |
+ return RUN_ALL_TESTS(); | |
+} | |
diff --git a/LICENSE b/googlemock/LICENSE.txt | |
similarity index 100% | |
rename from LICENSE | |
rename to googlemock/LICENSE.txt | |
diff --git a/googlemock/README.LLVM b/googlemock/README.LLVM | |
new file mode 100644 | |
index 00000000..48ac7766 | |
--- /dev/null | |
+++ b/googlemock/README.LLVM | |
@@ -0,0 +1,19 @@ | |
+LLVM notes | |
+---------- | |
+ | |
+This directory contains the 'googlemock' component of Google Test 1.14.0, with | |
+all elements removed except for the actual source code, to minimize the | |
+addition to the LLVM distribution. | |
+ | |
+Cleaned up as follows: | |
+ | |
+# Remove all the unnecessary files and directories | |
+$ rm -f CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README README.md .gitignore | |
+$ rm -rf build-aux make msvc scripts test docs | |
+$ rm -f src/gmock_main.cc | |
+ | |
+# Put the license in the consistent place for LLVM. | |
+$ mv LICENSE LICENSE.TXT | |
+ | |
+Modified as follows: | |
+* Support for std::begin/std::end in gmock-matchers.h | |
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h | |
index 0f677137..a9e7cd19 100644 | |
--- a/googlemock/include/gmock/gmock-matchers.h | |
+++ b/googlemock/include/gmock/gmock-matchers.h | |
@@ -2356,12 +2356,20 @@ class BeginEndDistanceIsMatcher { | |
template <typename Container> | |
class Impl : public MatcherInterface<Container> { | |
public: | |
- typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_( | |
- Container)> | |
- ContainerView; | |
+ typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; | |
+ typedef internal::StlContainerView<RawContainer> View; | |
+ typedef typename View::type StlContainer; | |
+ typedef typename View::const_reference StlContainerReference; | |
+ typedef decltype(std::begin( | |
+ std::declval<StlContainerReference>())) StlContainerConstIterator; | |
typedef typename std::iterator_traits< | |
- typename ContainerView::type::const_iterator>::difference_type | |
- DistanceType; | |
+ StlContainerConstIterator>::difference_type DistanceType; | |
+ // typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_( | |
+ // Container)> | |
+ // ContainerView; | |
+ // typedef typename std::iterator_traits< | |
+ // typename ContainerView::type::const_iterator>::difference_type | |
+ // DistanceType; | |
explicit Impl(const DistanceMatcher& distance_matcher) | |
: distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {} | |
@@ -3370,7 +3378,11 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { | |
typedef internal::StlContainerView<RawContainer> View; | |
typedef typename View::type StlContainer; | |
typedef typename View::const_reference StlContainerReference; | |
- typedef typename StlContainer::value_type Element; | |
+ typedef decltype(std::begin( | |
+ std::declval<StlContainerReference>())) StlContainerConstIterator; | |
+ typedef typename std::remove_reference< | |
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element; | |
+ //typedef typename StlContainer::value_type Element; | |
// Constructs the matcher from a sequence of element values or | |
// element matchers. | |
@@ -3427,7 +3439,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { | |
// explanations[i] is the explanation of the element at index i. | |
::std::vector<std::string> explanations(count()); | |
StlContainerReference stl_container = View::ConstReference(container); | |
- auto it = stl_container.begin(); | |
+ StlContainerConstIterator it = stl_container.begin(); | |
size_t exam_pos = 0; | |
bool mismatch_found = false; // Have we found a mismatched element yet? | |
@@ -3616,7 +3628,11 @@ class UnorderedElementsAreMatcherImpl | |
typedef internal::StlContainerView<RawContainer> View; | |
typedef typename View::type StlContainer; | |
typedef typename View::const_reference StlContainerReference; | |
- typedef typename StlContainer::value_type Element; | |
+ typedef decltype(std::begin( | |
+ std::declval<StlContainerReference>())) StlContainerConstIterator; | |
+ typedef typename std::remove_reference< | |
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element; | |
+ //typedef typename StlContainer::value_type Element; | |
template <typename InputIter> | |
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, | |
@@ -3704,8 +3720,15 @@ class UnorderedElementsAreMatcher { | |
template <typename Container> | |
operator Matcher<Container>() const { | |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; | |
- typedef typename internal::StlContainerView<RawContainer>::type View; | |
- typedef typename View::value_type Element; | |
+ | |
+ typedef internal::StlContainerView<RawContainer> View; | |
+ typedef typename View::const_reference StlContainerReference; | |
+ typedef decltype(std::begin( | |
+ std::declval<StlContainerReference>())) StlContainerConstIterator; | |
+ typedef typename std::remove_reference< | |
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element; | |
+ // typedef typename internal::StlContainerView<RawContainer>::type View; | |
+ // typedef typename View::value_type Element; | |
typedef ::std::vector<Matcher<const Element&>> MatcherVec; | |
MatcherVec matchers; | |
matchers.reserve(::std::tuple_size<MatcherTuple>::value); | |
@@ -3735,8 +3758,14 @@ class ElementsAreMatcher { | |
"use UnorderedElementsAre with hash tables"); | |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; | |
- typedef typename internal::StlContainerView<RawContainer>::type View; | |
- typedef typename View::value_type Element; | |
+ typedef internal::StlContainerView<RawContainer> View; | |
+ typedef typename View::const_reference StlContainerReference; | |
+ typedef decltype(std::begin( | |
+ std::declval<StlContainerReference>())) StlContainerConstIterator; | |
+ typedef typename std::remove_reference< | |
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element; | |
+ // typedef typename internal::StlContainerView<RawContainer>::type View; | |
+ // typedef typename View::value_type Element; | |
typedef ::std::vector<Matcher<const Element&>> MatcherVec; | |
MatcherVec matchers; | |
matchers.reserve(::std::tuple_size<MatcherTuple>::value); | |
diff --git a/googletest/LICENSE.txt b/googletest/LICENSE.txt | |
new file mode 100644 | |
index 00000000..1941a11f | |
--- /dev/null | |
+++ b/googletest/LICENSE.txt | |
@@ -0,0 +1,28 @@ | |
+Copyright 2008, Google Inc. | |
+All rights reserved. | |
+ | |
+Redistribution and use in source and binary forms, with or without | |
+modification, are permitted provided that the following conditions are | |
+met: | |
+ | |
+ * Redistributions of source code must retain the above copyright | |
+notice, this list of conditions and the following disclaimer. | |
+ * Redistributions in binary form must reproduce the above | |
+copyright notice, this list of conditions and the following disclaimer | |
+in the documentation and/or other materials provided with the | |
+distribution. | |
+ * Neither the name of Google Inc. nor the names of its | |
+contributors may be used to endorse or promote products derived from | |
+this software without specific prior written permission. | |
+ | |
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
diff --git a/googletest/README.LLVM b/googletest/README.LLVM | |
new file mode 100644 | |
index 00000000..7a8ae859 | |
--- /dev/null | |
+++ b/googletest/README.LLVM | |
@@ -0,0 +1,21 @@ | |
+LLVM notes | |
+---------- | |
+ | |
+This directory contains Google Test 1.14.0, | |
+revision `f8d7d77c06936315286eb55f8de22cd23c188571`, with all elements removed | |
+except for the actual source code, to minimize the addition to the LLVM | |
+distribution. | |
+ | |
+Cleaned up as follows: | |
+ | |
+# Remove all the unnecessary files and directories | |
+$ rm -f CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README README.md .gitignore | |
+$ rm -rf build-aux cmake codegear m4 make msvc samples scripts test xcode docs | |
+$ rm -f src/gtest_main.cc | |
+ | |
+# Put the license in the consistent place for LLVM. | |
+$ mv LICENSE LICENSE.TXT | |
+ | |
+Modified as follows: | |
+* Added raw_os_ostream support to include/gtest/internal/custom/gtest-printers.h. | |
+* Added StringRef support to include/gtest/internal/custom/gtest-printers.h. | |
diff --git a/googletest/include/gtest/gtest-message.h b/googletest/include/gtest/gtest-message.h | |
index 59b805e4..833e227a 100644 | |
--- a/googletest/include/gtest/gtest-message.h | |
+++ b/googletest/include/gtest/gtest-message.h | |
@@ -145,7 +145,7 @@ class GTEST_API_ Message { | |
// overloads of << defined in the global namespace and those | |
// visible via Koenig lookup are both exposed in this function. | |
using ::operator<<; | |
- *ss_ << val; | |
+ *ss_ << llvm_gtest::printable(val); | |
return *this; | |
} | |
@@ -183,7 +183,7 @@ class GTEST_API_ Message { | |
if (pointer == nullptr) { | |
*ss_ << "(null)"; | |
} else { | |
- *ss_ << pointer; | |
+ *ss_ << llvm_gtest::printable(pointer); | |
} | |
return *this; | |
} | |
diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h | |
index d1766e64..39841923 100644 | |
--- a/googletest/include/gtest/gtest-printers.h | |
+++ b/googletest/include/gtest/gtest-printers.h | |
@@ -222,7 +222,7 @@ struct StreamPrinter { | |
-> decltype((void)(*os << value)) { | |
// Call streaming operator found by ADL, possibly with implicit conversions | |
// of the arguments. | |
- *os << value; | |
+ *os << ::llvm_gtest::printable(value); | |
} | |
}; | |
diff --git a/googletest/include/gtest/internal/custom/gtest-port.h b/googletest/include/gtest/internal/custom/gtest-port.h | |
index db02881c..57d16fca 100644 | |
--- a/googletest/include/gtest/internal/custom/gtest-port.h | |
+++ b/googletest/include/gtest/internal/custom/gtest-port.h | |
@@ -34,4 +34,5 @@ | |
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ | |
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ | |
+#include "gtest/internal/custom/raw-ostream.h" | |
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ | |
diff --git a/googletest/include/gtest/internal/custom/gtest-printers.h b/googletest/include/gtest/internal/custom/gtest-printers.h | |
index b9495d83..06f85f89 100644 | |
--- a/googletest/include/gtest/internal/custom/gtest-printers.h | |
+++ b/googletest/include/gtest/internal/custom/gtest-printers.h | |
@@ -39,4 +39,43 @@ | |
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ | |
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ | |
+#if !GTEST_NO_LLVM_SUPPORT | |
+#include "llvm/ADT/DenseMap.h" | |
+#include "llvm/ADT/SmallString.h" | |
+#include "llvm/ADT/StringRef.h" | |
+#include <ostream> | |
+// Printing of llvm String types. | |
+// gtest sees these as containers of char (they have nested iterator types), | |
+// so their operator<< is never considered unless we provide PrintTo(). | |
+// PrintStringTo provides quotes and escaping, at the cost of a copy. | |
+namespace llvm { | |
+inline void PrintTo(llvm::StringRef S, std::ostream *OS) { | |
+ *OS << ::testing::PrintToString(S.str()); | |
+} | |
+// We need both SmallString<N> and SmallVectorImpl<char> overloads: | |
+// - the SmallString<N> template is needed as overload resolution will | |
+// instantiate generic PrintTo<T> rather than do derived-to-base conversion | |
+// - but SmallVectorImpl<char> is sometimes the actual static type, in code | |
+// that erases the small size | |
+template <unsigned N> | |
+inline void PrintTo(const SmallString<N> &S, std::ostream *OS) { | |
+ *OS << ::testing::PrintToString(std::string(S.data(), S.size())); | |
+} | |
+inline void PrintTo(const SmallVectorImpl<char> &S, std::ostream *OS) { | |
+ *OS << ::testing::PrintToString(std::string(S.data(), S.size())); | |
+} | |
+ | |
+// DenseMap's entries inherit from std::pair, and should act like pairs. | |
+// However gTest's provided `PrintTo(pair<K,V>)` template won't deduce K and V | |
+// because of the needed derived-to-base conversion. | |
+namespace detail { | |
+template <typename K, typename V> | |
+inline void PrintTo(const DenseMapPair<K, V> &Pair, std::ostream *OS) { | |
+ *OS << ::testing::PrintToString(static_cast<const std::pair<K, V> &>(Pair)); | |
+} | |
+} // namespace detail | |
+ | |
+} // namespace llvm | |
+#endif // !GTEST_NO_LLVM_SUPPORT | |
+ | |
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ | |
diff --git a/googletest/include/gtest/internal/custom/raw-ostream.h b/googletest/include/gtest/internal/custom/raw-ostream.h | |
new file mode 100644 | |
index 00000000..76dcdee4 | |
--- /dev/null | |
+++ b/googletest/include/gtest/internal/custom/raw-ostream.h | |
@@ -0,0 +1,85 @@ | |
+//===-- raw-ostream.h - Support for printing using raw_ostream --*- C++ -*-===// | |
+// | |
+// 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 not part of gtest, but extends it to support LLVM libraries. | |
+// This is not a public API for testing - it's a detail of LLVM's gtest. | |
+// | |
+// gtest allows providing printers for custom types by defining operator<<. | |
+// In LLVM, operator<< usually takes llvm:raw_ostream& instead of std::ostream&. | |
+// | |
+// This file defines a template printable(V), which returns a version of V that | |
+// can be streamed into a std::ostream. | |
+// | |
+// This interface is chosen so that in the default case (printable(V) is V), | |
+// the main gtest code calls operator<<(OS, V) itself. gtest-printers carefully | |
+// controls the lookup to enable fallback printing (see testing::internal2). | |
+//===----------------------------------------------------------------------===// | |
+ | |
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_ | |
+#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_ | |
+ | |
+namespace llvm_gtest { | |
+// StreamSwitch is a trait that tells us how to stream a T into a std::ostream. | |
+// By default, we just stream the T directly. We'll specialize this later. | |
+template <typename T, typename Enable = void> struct StreamSwitch { | |
+ static const T& printable(const T& V) { return V; } | |
+}; | |
+ | |
+// printable() returns a version of its argument that can be streamed into a | |
+// std::ostream. This may be the argument itself, or some other representation. | |
+template <typename T> decltype(auto) printable(const T &V) { | |
+ // We delegate to the trait, to allow partial specialization. | |
+ return StreamSwitch<T>::printable(V); | |
+} | |
+} // namespace llvm_gtest | |
+ | |
+// If raw_ostream support is enabled, we specialize for types with operator<< | |
+// that takes a raw_ostream. | |
+#if !GTEST_NO_LLVM_SUPPORT | |
+#include "llvm/Support/raw_os_ostream.h" | |
+#include "llvm/Support/raw_ostream.h" | |
+#include <optional> | |
+#include <ostream> | |
+namespace llvm_gtest { | |
+ | |
+// The printable() of a raw_ostream-enabled type T is a RawStreamProxy<T>. | |
+// It uses raw_os_ostream to write the wrapped value to a std::ostream. | |
+template <typename T> | |
+struct RawStreamProxy { | |
+ const T& V; | |
+ friend std::ostream &operator<<(std::ostream &S, const RawStreamProxy<T> &V) { | |
+ llvm::raw_os_ostream OS(S); | |
+ OS << V.V; | |
+ return S; | |
+ } | |
+}; | |
+ | |
+// We enable raw_ostream treatment if `(raw_ostream&) << (const T&)` is valid. | |
+// We don't want implicit conversions on the RHS (e.g. to bool!), so "consume" | |
+// the possible conversion by passing something convertible to const T& instead. | |
+template <typename T> struct ConvertibleTo { operator T(); }; | |
+template <typename T> | |
+struct StreamSwitch<T, decltype((void)(std::declval<llvm::raw_ostream &>() | |
+ << ConvertibleTo<const T &>()))> { | |
+ static const RawStreamProxy<T> printable(const T &V) { return {V}; } | |
+}; | |
+ | |
+// std::optional has a template operator<<, which means it will not accept any | |
+// implicit conversions, so we need to special-case it here. | |
+template <typename T> | |
+struct StreamSwitch<std::optional<T>, | |
+ decltype((void)(std::declval<llvm::raw_ostream &>() | |
+ << std::declval<std::optional<T>>()))> { | |
+ static const RawStreamProxy<std::optional<T>> | |
+ printable(const std::optional<T> &V) { | |
+ return {V}; | |
+ } | |
+}; | |
+} // namespace llvm_gtest | |
+#endif // !GTEST_NO_LLVM_SUPPORT | |
+ | |
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment