feat(compiler): Add class StreamStringError with a stream interface for llvm::Error

Composing error messages for `llvm::Error` is either done by using
`llvm::createStringError()` with an appropriate format string and
arguments or by writing to a `std::string`-backed
`llvm::raw_string_ostream` and passing the result to
`llvm::make_error<llvm::StringError>()` verbatim.

The new class `StreamStringError` encapsulates the latter solution
into a class with an appropriate stream operator and implicit cast
operators to `llvm::Error` and `llvm::Expected`.

Example usage:

   llvm::Error foo(int i, size_t s, ...) {
      ...
      if(...) {
        return StreamStringError()
               << "Some error message with an integer: "
               << i << " and a size_t: " << s;
      }
      ...
   }
This commit is contained in:
Andi Drebes
2021-10-18 11:20:29 +02:00
parent b12be45143
commit e76aee7e10
3 changed files with 66 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
#ifndef ZAMALANG_SUPPORT_STRING_ERROR_H
#define ZAMALANG_SUPPORT_STRING_ERROR_H
#include <llvm/Support/Error.h>
namespace mlir {
namespace zamalang {
// Internal error class that allows for composing `llvm::Error`s
// similar to `llvm::createStringError()`, but using stream-like
// composition with `operator<<`.
//
// Example:
//
// llvm::Error foo(int i, size_t s, ...) {
// ...
// if(...) {
// return StreamStringError()
// << "Some error message with an integer: "
// << i << " and a size_t: " << s;
// }
// ...
// }
class StreamStringError {
public:
StreamStringError(const llvm::StringRef &s) : buffer(s.str()), os(buffer){};
StreamStringError() : buffer(""), os(buffer){};
template <typename T> StreamStringError &operator<<(const T &v) {
this->os << v;
return *this;
}
operator llvm::Error() {
return llvm::make_error<llvm::StringError>(os.str(),
llvm::inconvertibleErrorCode());
}
template <typename T> operator llvm::Expected<T>() {
return this->operator llvm::Error();
}
protected:
std::string buffer;
llvm::raw_string_ostream os;
};
StreamStringError &operator<<(StreamStringError &se, llvm::Error &err);
} // namespace zamalang
} // namespace mlir
#endif