Index: include/llvm/Support/Error.h =================================================================== --- include/llvm/Support/Error.h +++ 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,16 @@ 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); +} + /// Helper for check-and-exit error handling. /// /// For tool use only. NOT FOR USE IN LIBRARY CODE. Index: unittests/Support/ErrorTest.cpp =================================================================== --- unittests/Support/ErrorTest.cpp +++ unittests/Support/ErrorTest.cpp @@ -443,6 +443,23 @@ << "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(); + 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;