diff options
Diffstat (limited to 'include/cps/ExceptionHandler.h')
| -rw-r--r-- | include/cps/ExceptionHandler.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/include/cps/ExceptionHandler.h b/include/cps/ExceptionHandler.h new file mode 100644 index 0000000..5c846ae --- /dev/null +++ b/include/cps/ExceptionHandler.h @@ -0,0 +1,48 @@ +#pragma once +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Module.h" +#include <map> +#include <vector> + +namespace cps { + +// C++ ABI exception emission. State is keyed by function because file helper +// bodies and user functions are emitted using the same builder as their caller. +class ExceptionHandler { + struct Handler { + llvm::BasicBlock *Target; + llvm::AllocaInst *Exception; + unsigned CatchDepth; + }; + struct FunctionState { + std::vector<Handler> Handlers; + unsigned CatchDepth = 0; + }; + + llvm::LLVMContext &Context; + llvm::IRBuilder<> &Builder; + llvm::Module &Module; + std::map<llvm::Function *, FunctionState> States; + llvm::FunctionCallee Allocate, Throw, BeginCatch, EndCatch, Personality; + llvm::GlobalVariable *IntTypeInfo = nullptr; + + void ensureRuntime(); + llvm::BasicBlock *emitUnwindDestination(); + +public: + ExceptionHandler(llvm::LLVMContext &C, llvm::IRBuilder<> &B, llvm::Module &M) + : Context(C), Builder(B), Module(M) {} + + void prepareFunction(llvm::Function *F); + void pushHandler(llvm::BasicBlock *Target); + llvm::AllocaInst *popHandler(); + void beginCatch(llvm::AllocaInst *Exception); + void endCatch(); + void emitReturnCleanup(); + + llvm::Value *emitCall(llvm::FunctionCallee Callee, llvm::ArrayRef<llvm::Value *> Args, + const llvm::Twine &Name = ""); + void emitThrow(); +}; + +} // namespace cps |
