[llvm] r324876 - [gtest] Support raw_ostream printing functions more comprehensively.

Galina Kistanova via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 12 13:53:59 PST 2018


Hello Sam,

This commit  broke the one of our builders:
http://lab.llvm.org:8011/builders/ubuntu-gcc7.1-werror/builds/5290

Please have a look?

Thanks

Galina

On Mon, Feb 12, 2018 at 2:20 AM, Sam McCall via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: sammccall
> Date: Mon Feb 12 02:20:09 2018
> New Revision: 324876
>
> URL: http://llvm.org/viewvc/llvm-project?rev=324876&view=rev
> Log:
> [gtest] Support raw_ostream printing functions more comprehensively.
>
> Summary:
> These are functions like operator<<(raw_ostream&, Foo).
>
> Previously these were only supported for messages. In the assertion
>   EXPECT_EQ(A, B) << C;
> the local modifications would explicitly try to use raw_ostream printing
> for C.
> However A and B would look for a std::ostream printing function, and often
> fall
> back to gtest's default "168 byte object <00 01 FE 42 ...>".
>
> This patch pulls out the raw_ostream support into a new header under
> `custom/`.
>
> I changed the mechanism: instead of a convertible stream, we wrap the
> printed
> value in a proxy object to allow it to be sent to a std::ostream.
> I think the new way is clearer.
>
> I also changed the policy: we prefer raw_ostream printers over std::ostream
> ones. This is because the fallback printers are defined using std::ostream,
> while all the raw_ostream printers should be "good".
>
> Reviewers: ilya-biryukov, chandlerc
>
> Subscribers: llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D43091
>
> Added:
>     llvm/trunk/utils/unittest/googletest/include/gtest/
> internal/custom/raw-ostream.h
> Modified:
>     llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h
>     llvm/trunk/utils/unittest/googletest/include/gtest/gtest-printers.h
>
> Modified: llvm/trunk/utils/unittest/googletest/include/gtest/
> gtest-message.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/
> unittest/googletest/include/gtest/gtest-message.h?rev=
> 324876&r1=324875&r2=324876&view=diff
> ============================================================
> ==================
> --- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h
> (original)
> +++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-message.h
> Mon Feb 12 02:20:09 2018
> @@ -49,36 +49,7 @@
>  #include <limits>
>
>  #include "gtest/internal/gtest-port.h"
> -
> -#if !GTEST_NO_LLVM_RAW_OSTREAM
> -#include "llvm/Support/raw_os_ostream.h"
> -
> -// LLVM INTERNAL CHANGE: To allow operator<< to work with both
> -// std::ostreams and LLVM's raw_ostreams, we define a special
> -// std::ostream with an implicit conversion to raw_ostream& and stream
> -// to that.  This causes the compiler to prefer std::ostream overloads
> -// but still find raw_ostream& overloads.
> -namespace llvm {
> -class convertible_fwd_ostream : public std::ostream {
> -  raw_os_ostream ros_;
> -
> -public:
> -  convertible_fwd_ostream(std::ostream& os)
> -    : std::ostream(os.rdbuf()), ros_(*this) {}
> -  operator raw_ostream&() { return ros_; }
> -};
> -}
> -template <typename T>
> -inline void GTestStreamToHelper(std::ostream& os, const T& val) {
> -  llvm::convertible_fwd_ostream cos(os);
> -  cos << val;
> -}
> -#else
> -template <typename T>
> -inline void GTestStreamToHelper(std::ostream& os, const T& val) {
> -  os << val;
> -}
> -#endif
> +#include "gtest/internal/custom/raw-ostream.h"
>
>  // Ensures that there is at least one operator<< in the global namespace.
>  // See Message& operator<<(...) below for why.
> @@ -157,12 +128,8 @@ class GTEST_API_ Message {
>      // from the global namespace.  With this using declaration,
>      // overloads of << defined in the global namespace and those
>      // visible via Koenig lookup are both exposed in this function.
> -#if GTEST_NO_LLVM_RAW_OSTREAM
>      using ::operator <<;
> -    *ss_ << val;
> -#else
> -    ::GTestStreamToHelper(*ss_, val);
> -#endif
> +    *ss_ << llvm_gtest::printable(val);
>      return *this;
>    }
>
> @@ -184,11 +151,7 @@ class GTEST_API_ Message {
>      if (pointer == NULL) {
>        *ss_ << "(null)";
>      } else {
> -#if GTEST_NO_LLVM_RAW_OSTREAM
> -      *ss_ << pointer;
> -#else
> -      ::GTestStreamToHelper(*ss_, pointer);
> -#endif
> +      *ss_ << llvm_gtest::printable(pointer);
>      }
>      return *this;
>    }
>
> Modified: llvm/trunk/utils/unittest/googletest/include/gtest/
> gtest-printers.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/
> unittest/googletest/include/gtest/gtest-printers.h?rev=
> 324876&r1=324875&r2=324876&view=diff
> ============================================================
> ==================
> --- llvm/trunk/utils/unittest/googletest/include/gtest/gtest-printers.h
> (original)
> +++ llvm/trunk/utils/unittest/googletest/include/gtest/gtest-printers.h
> Mon Feb 12 02:20:09 2018
> @@ -102,6 +102,7 @@
>  #include <vector>
>  #include "gtest/internal/gtest-port.h"
>  #include "gtest/internal/gtest-internal.h"
> +#include "gtest/internal/custom/raw-ostream.h"
>
>  #if GTEST_HAS_STD_TUPLE_
>  # include <tuple>
> @@ -246,7 +247,7 @@ void DefaultPrintNonContainerTo(const T&
>    // impossible to define #1 (e.g. when foo is ::std, defining
>    // anything in it is undefined behavior unless you are a compiler
>    // vendor.).
> -  *os << value;
> +  *os << ::llvm_gtest::printable(value);
>  }
>
>  }  // namespace testing_internal
>
> Added: llvm/trunk/utils/unittest/googletest/include/gtest/
> internal/custom/raw-ostream.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/
> unittest/googletest/include/gtest/internal/custom/raw-
> ostream.h?rev=324876&view=auto
> ============================================================
> ==================
> --- llvm/trunk/utils/unittest/googletest/include/gtest/internal/custom/raw-ostream.h
> (added)
> +++ llvm/trunk/utils/unittest/googletest/include/gtest/internal/custom/raw-ostream.h
> Mon Feb 12 02:20:09 2018
> @@ -0,0 +1,74 @@
> +//===-- raw-ostream.h - Support for printing using raw_ostream --*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===------------------------------------------------------
> ----------------===//
> +// 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>
> +auto printable(const T &V) -> decltype(StreamSwitch<T>::printable(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_RAW_OSTREAM
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Support/raw_os_ostream.h"
> +#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}; }
> +};
> +} // namespace llvm_gtest
> +#endif  // !GTEST_NO_LLVM_RAW_OSTREAM
> +
> +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_RAW_OSTREAM_H_
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180212/9c63bbf3/attachment.html>


More information about the llvm-commits mailing list