Index: llvm/trunk/include/llvm/Support/Error.h =================================================================== --- llvm/trunk/include/llvm/Support/Error.h +++ llvm/trunk/include/llvm/Support/Error.h @@ -24,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -1121,6 +1122,18 @@ std::error_code EC; }; +/// Create formatted StringError object. +template +Error createStringError(std::error_code EC, char const *Fmt, + const Ts &... Vals) { + std::string Buffer; + raw_string_ostream Stream(Buffer); + Stream << format(Fmt, Vals...); + return make_error(Stream.str(), EC); +} + +Error createStringError(std::error_code EC, char const *Msg); + /// Helper for check-and-exit error handling. /// /// For tool use only. NOT FOR USE IN LIBRARY CODE. Index: llvm/trunk/lib/Support/Error.cpp =================================================================== --- llvm/trunk/lib/Support/Error.cpp +++ llvm/trunk/lib/Support/Error.cpp @@ -112,6 +112,10 @@ return EC; } +Error createStringError(std::error_code EC, char const *Msg) { + return make_error(Msg, EC); +} + void report_fatal_error(Error Err, bool GenCrashDiag) { assert(Err && "report_fatal_error called with success value"); std::string ErrMsg; Index: llvm/trunk/unittests/Support/ErrorTest.cpp =================================================================== --- llvm/trunk/unittests/Support/ErrorTest.cpp +++ llvm/trunk/unittests/Support/ErrorTest.cpp @@ -443,6 +443,29 @@ << "Failed to convert StringError to error_code."; } +TEST(Error, createStringError) { + static const char *Bar = "bar"; + static const std::error_code EC = errc::invalid_argument; + std::string Msg; + raw_string_ostream S(Msg); + logAllUnhandledErrors(createStringError(EC, "foo%s%d0x%" PRIx8, Bar, 1, 0xff), + S, ""); + EXPECT_EQ(S.str(), "foobar10xff\n") + << "Unexpected createStringError() log result"; + + S.flush(); + Msg.clear(); + logAllUnhandledErrors(createStringError(EC, Bar), S, ""); + EXPECT_EQ(S.str(), "bar\n") + << "Unexpected createStringError() (overloaded) log result"; + + S.flush(); + Msg.clear(); + auto Res = errorToErrorCode(createStringError(EC, "foo%s", Bar)); + EXPECT_EQ(Res, EC) + << "Failed to convert createStringError() result to error_code."; +} + // Test that the ExitOnError utility works as expected. TEST(Error, ExitOnError) { ExitOnError ExitOnErr;