Index: llvm/trunk/include/llvm/Support/Error.h =================================================================== --- llvm/trunk/include/llvm/Support/Error.h +++ llvm/trunk/include/llvm/Support/Error.h @@ -16,6 +16,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/raw_ostream.h" @@ -35,6 +36,14 @@ /// Print an error message to an output stream. virtual void log(raw_ostream &OS) const = 0; + /// Return the error message as a string. + virtual std::string message() const { + std::string Msg; + raw_string_ostream OS(Msg); + log(OS); + return Msg; + } + /// Convert this error to a std::error_code. /// /// This is a temporary crutch to enable interaction with code still @@ -537,6 +546,16 @@ }); } +/// Write all error messages (if any) in E to a string. The newline character +/// is used to separate error messages. +inline std::string toString(Error E) { + SmallVector Errors; + handleAllErrors(std::move(E), [&Errors](const ErrorInfoBase &EI) { + Errors.push_back(EI.message()); + }); + return join(Errors.begin(), Errors.end(), "\n"); +} + /// Consume a Error without doing anything. This method should be used /// only where an error can be considered a reasonable and expected return /// value. Index: llvm/trunk/unittests/Support/ErrorTest.cpp =================================================================== --- llvm/trunk/unittests/Support/ErrorTest.cpp +++ llvm/trunk/unittests/Support/ErrorTest.cpp @@ -544,4 +544,23 @@ } } +// Test that error messages work. +TEST(Error, ErrorMessage) { + EXPECT_EQ(toString(Error::success()).compare(""), 0); + + Error E1 = make_error(0); + EXPECT_EQ(toString(std::move(E1)).compare("CustomError { 0}"), 0); + + Error E2 = make_error(0); + handleAllErrors(std::move(E2), [](const CustomError &CE) { + EXPECT_EQ(CE.message().compare("CustomError { 0}"), 0); + }); + + Error E3 = joinErrors(make_error(0), make_error(1)); + EXPECT_EQ(toString(std::move(E3)) + .compare("CustomError { 0}\n" + "CustomError { 1}"), + 0); +} + } // end anon namespace