[llvm] [Support] Introduce formatv variant of createStringError (PR #80493)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 2 12:55:19 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
Author: Alex Langford (bulbazord)
<details>
<summary>Changes</summary>
Many times I have found myself wanting to create a StringError with the ability to interpolate a StringRef into the error string. This can be achieved with:
StringRef Foo("...");
auto Err = createStringError(..., "Something went wrong: %s", Foo.str().c_str());
However, this requires us to construct a temporary std::string (which may perform a memory allocation if large enough).
I propose a new variant of `createStringError` called `createStringErrorv` which uses `formatv` under the hood. This allows the above example to become:
StringRef Foo("...");
auto Err = createStringError(..., "Something went wrong: {0}", Foo);
---
Full diff: https://github.com/llvm/llvm-project/pull/80493.diff
2 Files Affected:
- (modified) llvm/include/llvm/Support/Error.h (+10)
- (modified) llvm/unittests/Support/ErrorTest.cpp (+17)
``````````diff
diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index bb4f38f7ec355..e13543d1681c0 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -22,6 +22,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
@@ -1261,6 +1262,15 @@ inline Error createStringError(std::errc EC, char const *Fmt,
return createStringError(std::make_error_code(EC), Fmt, Vals...);
}
+template <typename... Ts>
+inline Error createStringErrorv(std::error_code EC, const char *Fmt,
+ const Ts &...Vals) {
+ std::string Buffer;
+ raw_string_ostream Stream(Buffer);
+ Stream << formatv(Fmt, Vals...);
+ return make_error<StringError>(Stream.str(), EC);
+}
+
/// This class wraps a filename and another Error.
///
/// In some cases, an error needs to live along a 'source' name, in order to
diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp
index 11f93203597bf..17de7aaf4c9c1 100644
--- a/llvm/unittests/Support/ErrorTest.cpp
+++ b/llvm/unittests/Support/ErrorTest.cpp
@@ -472,6 +472,23 @@ TEST(Error, createStringError) {
<< "Failed to convert createStringError() result to error_code.";
}
+TEST(Error, createStringErrorv) {
+ static llvm::StringRef Bar("bar");
+ static const std::error_code EC = errc::invalid_argument;
+ std::string Msg;
+ raw_string_ostream S(Msg);
+ logAllUnhandledErrors(createStringErrorv(EC, "foo{0}{1}{2:x}", Bar, 1, 0xff),
+ S);
+ EXPECT_EQ(S.str(), "foobar10xff\n")
+ << "Unexpected createStringErrorv() log result";
+
+ S.flush();
+ Msg.clear();
+ auto Res = errorToErrorCode(createStringErrorv(EC, "foo{0}", Bar));
+ EXPECT_EQ(Res, EC)
+ << "Failed to convert createStringErrorv() result to error_code.";
+}
+
// Test that the ExitOnError utility works as expected.
TEST(ErrorDeathTest, ExitOnError) {
ExitOnError ExitOnErr;
``````````
</details>
https://github.com/llvm/llvm-project/pull/80493
More information about the llvm-commits
mailing list