Index: include/llvm-c/Core.h =================================================================== --- include/llvm-c/Core.h +++ include/llvm-c/Core.h @@ -1476,6 +1476,16 @@ LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty); /** + * Obtain the constant token "none", used in SEH instructions. + */ +LLVMValueRef LLVMConstTokenNone(void); + +/** + * Same as LLVMConstTokenNone, but takes an additional context argument. + */ +LLVMValueRef LLVMConstTokenNoneInContext(LLVMContextRef C); + +/** * @defgroup LLVMCCoreValueConstantScalar Scalar constants * * Functions in this group model LLVMValueRef instances that correspond @@ -2827,9 +2837,27 @@ LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name); +LLVMValueRef LLVMBuildInvokeInPad(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, + LLVMValueRef Pad, const char *Name); LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef PersFn, unsigned NumClauses, const char *Name); +LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, LLVMValueRef ParentPad, + LLVMBasicBlockRef UnwindBB, unsigned NumHandlers, + const char *Name); +void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef HandlerVal); +LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad, + LLVMValueRef *Args, unsigned NumArgs, + const char *Name); +LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, LLVMValueRef ParentPad, + LLVMValueRef *Args, unsigned NumArgs, + const char *Name); +LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, LLVMValueRef CatchPad, + LLVMBasicBlockRef BB); +LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, LLVMValueRef CleanupPad, + LLVMBasicBlockRef UnwindBB); LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn); LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef); @@ -3002,6 +3030,9 @@ LLVMValueRef LLVMBuildCall(LLVMBuilderRef, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, const char *Name); +LLVMValueRef LLVMBuildCallInPad(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMValueRef Pad, const char *Name); LLVMValueRef LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, const char *Name); Index: lib/IR/Core.cpp =================================================================== --- lib/IR/Core.cpp +++ lib/IR/Core.cpp @@ -820,6 +820,15 @@ return wrap(ConstantPointerNull::get(unwrap(Ty))); } +LLVMValueRef LLVMConstTokenNone(void) { + return wrap(ConstantTokenNone::get(*unwrap(LLVMGetGlobalContext()))); +} + +LLVMValueRef LLVMConstTokenNoneInContext(LLVMContextRef C) { + LLVMContext &Context = *unwrap(C); + return wrap(ConstantTokenNone::get(Context)); +} + /*--.. Operations on metadata nodes ........................................--*/ LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, @@ -2461,6 +2470,18 @@ Name)); } +LLVMValueRef LLVMBuildInvokeInPad(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMBasicBlockRef Then, + LLVMBasicBlockRef Catch, + LLVMValueRef Pad, const char *Name) { + SmallVector BundleList; + BundleList.emplace_back("funclet", unwrap(Pad)); + return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch), + makeArrayRef(unwrap(Args), NumArgs), + BundleList, Name)); +} + LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef PersFn, unsigned NumClauses, const char *Name) { @@ -2477,6 +2498,50 @@ return wrap(unwrap(B)->CreateResume(unwrap(Exn))); } +LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, + LLVMValueRef ParentPad, + LLVMBasicBlockRef UnwindBB, + unsigned NumHandlers, + const char *Name) { + return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(UnwindBB), + NumHandlers, Name)); +} + +void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef handler) { + unwrap(CatchSwitch)->addHandler(unwrap(handler)); +} + +LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, + LLVMValueRef ParentPad, + LLVMValueRef *Args, + unsigned NumArgs, + const char *Name) { + ArrayRef ArgList(unwrap(Args), NumArgs); + return wrap(unwrap(B)->CreateCatchPad(unwrap(ParentPad), ArgList, Name)); +} + +LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, + LLVMValueRef ParentPad, + LLVMValueRef *Args, + unsigned NumArgs, + const char *Name) { + ArrayRef ArgList(unwrap(Args), NumArgs); + return wrap(unwrap(B)->CreateCleanupPad(unwrap(ParentPad), ArgList, Name)); +} + +LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, + LLVMValueRef CatchPad, + LLVMBasicBlockRef BB) { + return wrap(unwrap(B)->CreateCatchRet(unwrap(CatchPad), unwrap(BB))); +} + +LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, + LLVMValueRef CleanupPad, + LLVMBasicBlockRef UnwindBB) { + return wrap(unwrap(B)->CreateCleanupRet(unwrap(CleanupPad), unwrap(UnwindBB))); +} + + LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) { return wrap(unwrap(B)->CreateUnreachable()); } @@ -2961,6 +3026,17 @@ Name)); } +LLVMValueRef LLVMBuildCallInPad(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMValueRef Pad, const char *Name) { + SmallVector BundleList; + BundleList.emplace_back("funclet", unwrap(Pad)); + return wrap(unwrap(B)->CreateCall(unwrap(Fn), + makeArrayRef(unwrap(Args), NumArgs), + BundleList, + Name)); +} + LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, const char *Name) { Index: test/Bindings/llvm-c/seh.ll =================================================================== --- /dev/null +++ test/Bindings/llvm-c/seh.ll @@ -0,0 +1,41 @@ +; RUN: llvm-as < %s | llvm-dis > %t.orig +; RUN: llvm-as < %s | llvm-c-test --echo > %t.echo +; RUN: diff -w %t.orig %t.echo +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc18.0.0" + +define void @g() { + ret void +} + +define void @f2() personality i32 (...)* @__CxxFrameHandler3 { +entry: + %b = alloca i32 + invoke void @g() to label %invoke.cont unwind label %ehcleanup + +invoke.cont: ; preds = %entry + br label %try.cont + +ehcleanup: ; preds = %entry + %0 = cleanuppad within none [] + cleanupret from %0 unwind label %catch.dispatch + +catch.dispatch: ; preds = %ehcleanup + %cs1 = catchswitch within none [label %catch] unwind label %ehcleanup.1 + +catch: ; preds = %catch.dispatch + %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null] + catchret from %1 to label %catchret.dest + +catchret.dest: ; preds = %catch + br label %try.cont + +try.cont: ; preds = %catchret.dest, %invoke.cont + ret void + +ehcleanup.1: + %2 = cleanuppad within none [] + cleanupret from %2 unwind to caller +} + +declare i32 @__CxxFrameHandler3(...) Index: tools/llvm-c-test/echo.cpp =================================================================== --- tools/llvm-c-test/echo.cpp +++ tools/llvm-c-test/echo.cpp @@ -647,6 +647,50 @@ Dst = LLVMBuildInsertValue(Builder, Agg, V, I, Name); break; } + case LLVMCleanupPad: { + int Operands = LLVMGetNumOperands(Src); + if (Operands <= 0) + report_fatal_error("Expected at least one indice"); + LLVMValueRef Parent = LLVMGetOperand(Src, Operands - 1); + SmallVector Args; + for (int i = 0; i < Operands - 1; i++) + Args.push_back(LLVMGetOperand(Src, i)); + Dst = LLVMBuildCleanupPad(Builder, Parent, Args.data(), Operands - 1, Name); + break; + } + case LLVMCleanupRet: { + LLVMBasicBlockRef Unwind = nullptr; + if (LLVMGetNumOperands(Src) > 1) + Unwind = CloneBB(LLVMValueAsBasicBlock(LLVMGetOperand(Src, 1))); + Dst = LLVMBuildCleanupRet(Builder, LLVMGetOperand(Src, 0), Unwind); + break; + } + case LLVMCatchSwitch: { + LLVMBasicBlockRef Unwind = CloneBB(LLVMValueAsBasicBlock(LLVMGetOperand(Src, 1))); + if (LLVMGetNumOperands(Src) < 2) + report_fatal_error("Expected at least two operands"); + unsigned Handlers = LLVMGetNumOperands(Src) - 2; + Dst = LLVMBuildCatchSwitch(Builder, LLVMGetOperand(Src, 0), Unwind, Handlers, Name); + for (unsigned i = 0; i < Handlers; i++) + LLVMAddHandler(Dst, CloneBB(LLVMValueAsBasicBlock(LLVMGetOperand(Src, i+2)))); + break; + } + case LLVMCatchPad: { + int Operands = LLVMGetNumOperands(Src); + if (Operands <= 0) + report_fatal_error("Expected at least one indice"); + LLVMValueRef Parent = LLVMGetOperand(Src, Operands - 1); + SmallVector Args; + for (int i = 0; i < Operands - 1; i++) + Args.push_back(LLVMGetOperand(Src, i)); + Dst = LLVMBuildCatchPad(Builder, Parent, Args.data(), Operands - 1, Name); + break; + } + case LLVMCatchRet: { + LLVMBasicBlockRef Successor = CloneBB(LLVMValueAsBasicBlock(LLVMGetOperand(Src, 1))); + Dst = LLVMBuildCatchRet(Builder, LLVMGetOperand(Src, 0), Successor); + break; + } default: break; }