Index: include/llvm/Support/Error.h =================================================================== --- include/llvm/Support/Error.h +++ include/llvm/Support/Error.h @@ -302,6 +302,14 @@ return Tmp; } + friend raw_ostream &operator<<(raw_ostream &OS, const Error &E) { + if (auto P = E.getPtr()) + P->log(OS); + else + OS << "success"; + return OS; + } + ErrorInfoBase *Payload = nullptr; }; Index: include/llvm/Support/FormatProviders.h =================================================================== --- include/llvm/Support/FormatProviders.h +++ include/llvm/Support/FormatProviders.h @@ -418,6 +418,12 @@ } } }; -} + +class Error; +template <> struct llvm::format_provider { + static void format(const llvm::Error &, llvm::raw_ostream &, StringRef Style); +}; + +} // namespace llvm #endif Index: include/llvm/Support/FormatVariadic.h =================================================================== --- include/llvm/Support/FormatVariadic.h +++ include/llvm/Support/FormatVariadic.h @@ -261,7 +261,14 @@ // Allow a formatv_object to be formatted (no options supported). template struct format_provider> { static void format(const formatv_object &V, raw_ostream &OS, StringRef) { - OS << V; + V.format(OS); + } +}; + +// Allow a formatv_object to be formatted (no options supported). +template <> struct format_provider { + static void format(const formatv_object_base &V, raw_ostream &OS, StringRef) { + V.format(OS); } }; Index: lib/Support/CMakeLists.txt =================================================================== --- lib/Support/CMakeLists.txt +++ lib/Support/CMakeLists.txt @@ -75,6 +75,7 @@ FileOutputBuffer.cpp FoldingSet.cpp FormattedStream.cpp + FormatProviders.cpp FormatVariadic.cpp GlobPattern.cpp GraphWriter.cpp Index: lib/Support/FormatProviders.cpp =================================================================== --- /dev/null +++ lib/Support/FormatProviders.cpp @@ -0,0 +1,19 @@ +//===- FormatProviders.cpp - Formatters for common LLVM types -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/FormatProviders.h" +#include "llvm/Support/Error.h" + +namespace llvm { +void format_provider::format(const llvm::Error &Err, + llvm::raw_ostream &OS, + StringRef Style) { + OS << Err; +} +} // namespace llvm Index: unittests/Support/FormatVariadicTest.cpp =================================================================== --- unittests/Support/FormatVariadicTest.cpp +++ unittests/Support/FormatVariadicTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FormatAdapters.h" #include "gtest/gtest.h" @@ -646,6 +647,16 @@ EXPECT_EQ("[ ! ]", formatv("[{0,+5}]", formatv("{0,-2}", "!")).str()); } +TEST(FormatVariadicTest, FormatError) { + Error Bad = make_error("oh no!", inconvertibleErrorCode()); + Error OK = Error::success(); + EXPECT_EQ("oh no!", formatv("{0}", Bad).str()); + EXPECT_EQ("success", formatv("{0}", OK).str()); + // formatv takes a const Error&, and does not consume it. + consumeError(std::move(Bad)); + consumeError(std::move(OK)); +} + namespace { struct Recorder { int Copied = 0, Moved = 0;