LLVM 14 C++ API错误处理实现方法示例咨询
LLVM 14 C++ API 错误处理实现示例
LLVM 14的C++ API错误处理核心围绕Expected<T>、Error以及ErrorInfo这几个类型展开,下面直接上不同场景的实现示例:
1. 处理返回Expected<T>的API
很多LLVM操作会返回Expected<T>表示可能失败(比如加载IR模块),可以通过takeError()提取错误,再用handleAllErrors处理:
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/Error.h" using namespace llvm; int main() { LLVMContext Context; SMDiagnostic Err; // 加载模块,返回Expected<std::unique_ptr<Module>> Expected<std::unique_ptr<Module>> ModOrErr = parseIRFile("test.ll", Err, Context); // 检查是否有错误 if (!ModOrErr) { // 提取错误对象 Error Err = ModOrErr.takeError(); // 处理错误:打印错误信息并销毁错误对象 handleAllErrors(std::move(Err), [](const ErrorInfoBase& EI) { errs() << "Error loading module: " << EI.message() << "\n"; }); return 1; } // 成功拿到模块,正常处理 std::unique_ptr<Module> Mod = std::move(*ModOrErr); errs() << "Loaded module: " << Mod->getName() << "\n"; return 0; }
2. 返回自定义错误类型
如果你的代码需要抛出自定义错误,可以继承ErrorInfo实现自己的错误类型:
#include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include <string> using namespace llvm; // 自定义错误类型,继承ErrorInfo struct MyCustomError : public ErrorInfo<MyCustomError> { static char ID; // 必须定义唯一ID std::string Msg; MyCustomError(std::string Msg) : Msg(std::move(Msg)) {} void log(raw_ostream& OS) const override { OS << "Custom error: " << Msg << "\n"; } std::error_code convertToErrorCode() const override { // 可以返回标准错误码,或者自定义的 return llvm::inconvertibleErrorCode(); } }; char MyCustomError::ID = 0; // 模拟一个可能失败的函数 Error doSomethingRisky(bool ShouldFail) { if (ShouldFail) { return make_error<MyCustomError>("Operation failed due to invalid input"); } return Error::success(); } int main() { Error Err = doSomethingRisky(true); if (Err) { handleAllErrors(std::move(Err), [](const MyCustomError& CE) { errs() << CE.Msg << "\n"; }, [](const ErrorInfoBase& EI) { // 处理其他类型的错误 errs() << "Unknown error: " << EI.message() << "\n"; }); } return 0; }
3. 使用cantFail处理确定不会失败的场景
如果绝对确定某个Expected<T>或Error不会失败,可以用cantFail,但要谨慎使用——如果实际出错,程序会直接终止:
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/Type.h" #include "llvm/Support/Error.h" using namespace llvm; int main() { LLVMContext Context; // 获取i32类型,这个操作绝对不会失败 Expected<Type*> I32TypeOrErr = Type::getInt32Ty(Context); Type* I32Type = cantFail(std::move(I32TypeOrErr)); errs() << "Type: " << *I32Type << "\n"; return 0; }
关键注意事项
- 所有
Error和Expected<T>必须被处理(要么提取错误处理,要么用cantFail/ignoreError,但ignoreError会泄漏错误对象,不推荐) handleAllErrors会自动销毁错误对象,不需要手动释放- 自定义错误类型必须提供唯一的
ID,并且实现log和convertToErrorCode方法
内容的提问来源于stack exchange,提问作者user15807286
相关产品推荐
相关产品推荐

