llvm.org GIT mirror llvm / fea7778
[LLVM-C] Finish exception instruction bindings - Round 2 Summary: Previous revision caused a leak in the echo test that got caught by the ASAN bots because of missing free of the handlers array and was reverted in r328759. Resubmitting the patch with that correction. Add support for cleanupret, catchret, catchpad, cleanuppad and catchswitch and their associated accessors. Test is modified from SimplifyCFG because it contains many diverse usages of these instructions. Reviewers: whitequark, deadalnix Reviewed By: whitequark Subscribers: llvm-commits, vlad.tsyrklevich Differential Revision: https://reviews.llvm.org/D45100 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328883 91177308-0d34-0410-b5e6-96231b3b80d8 Robert Widmann 2 years ago
4 changed file(s) with 271 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
25542554 /**
25552555 * Obtain the argument count for a call instruction.
25562556 *
2557 * This expects an LLVMValueRef that corresponds to a llvm::CallInst or
2558 * llvm::InvokeInst.
2557 * This expects an LLVMValueRef that corresponds to a llvm::CallInst,
2558 * llvm::InvokeInst, or llvm:FuncletPadInst.
25592559 *
25602560 * @see llvm::CallInst::getNumArgOperands()
25612561 * @see llvm::InvokeInst::getNumArgOperands()
2562 * @see llvm::FuncletPadInst::getNumArgOperands()
25622563 */
25632564 unsigned LLVMGetNumArgOperands(LLVMValueRef Instr);
25642565
26432644 /**
26442645 * Return the unwind destination basic block.
26452646 *
2647 * Works on llvm::InvokeInst, llvm::CleanupReturnInst, and
2648 * llvm::CatchSwitchInst instructions.
2649 *
2650 * @see llvm::InvokeInst::getUnwindDest()
2651 * @see llvm::CleanupReturnInst::getUnwindDest()
2652 * @see llvm::CatchSwitchInst::getUnwindDest()
2653 */
2654 LLVMBasicBlockRef LLVMGetUnwindDest(LLVMValueRef InvokeInst);
2655
2656 /**
2657 * Set the normal destination basic block.
2658 *
26462659 * This only works on llvm::InvokeInst instructions.
26472660 *
2648 * @see llvm::InvokeInst::getUnwindDest()
2649 */
2650 LLVMBasicBlockRef LLVMGetUnwindDest(LLVMValueRef InvokeInst);
2651
2652 /**
2653 * Set the normal destination basic block.
2654 *
2655 * This only works on llvm::InvokeInst instructions.
2656 *
26572661 * @see llvm::InvokeInst::setNormalDest()
26582662 */
26592663 void LLVMSetNormalDest(LLVMValueRef InvokeInst, LLVMBasicBlockRef B);
26612665 /**
26622666 * Set the unwind destination basic block.
26632667 *
2664 * This only works on llvm::InvokeInst instructions.
2668 * Works on llvm::InvokeInst, llvm::CleanupReturnInst, and
2669 * llvm::CatchSwitchInst instructions.
26652670 *
26662671 * @see llvm::InvokeInst::setUnwindDest()
2672 * @see llvm::CleanupReturnInst::setUnwindDest()
2673 * @see llvm::CatchSwitchInst::setUnwindDest()
26672674 */
26682675 void LLVMSetUnwindDest(LLVMValueRef InvokeInst, LLVMBasicBlockRef B);
26692676
28922899 LLVMValueRef *Args, unsigned NumArgs,
28932900 LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
28942901 const char *Name);
2902 LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
2903
2904 /* Exception Handling */
2905 LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
28952906 LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty,
28962907 LLVMValueRef PersFn, unsigned NumClauses,
28972908 const char *Name);
2898 LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
2899 LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
2909 LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, LLVMValueRef CatchPad,
2910 LLVMBasicBlockRef BB);
2911 LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, LLVMValueRef CatchPad,
2912 LLVMBasicBlockRef BB);
2913 LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
2914 LLVMValueRef *Args, unsigned NumArgs,
2915 const char *Name);
2916 LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
2917 LLVMValueRef *Args, unsigned NumArgs,
2918 const char *Name);
2919 LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, LLVMValueRef ParentPad,
2920 LLVMBasicBlockRef UnwindBB,
2921 unsigned NumHandlers, const char *Name);
29002922
29012923 /* Add a case to the switch instruction */
29022924 void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal,
29192941
29202942 /* Set the 'cleanup' flag in the landingpad instruction */
29212943 void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val);
2944
2945 /* Add a destination to the catchswitch instruction */
2946 void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef Dest);
2947
2948 /* Get the number of handlers on the catchswitch instruction */
2949 unsigned LLVMGetNumHandlers(LLVMValueRef CatchSwitch);
2950
2951 /**
2952 * Obtain the basic blocks acting as handlers for a catchswitch instruction.
2953 *
2954 * The Handlers parameter should point to a pre-allocated array of
2955 * LLVMBasicBlockRefs at least LLVMGetNumHandlers() large. On return, the
2956 * first LLVMGetNumHandlers() entries in the array will be populated
2957 * with LLVMBasicBlockRef instances.
2958 *
2959 * @param CatchSwitch The catchswitch instruction to operate on.
2960 * @param Handlers Memory address of an array to be filled with basic blocks.
2961 */
2962 void LLVMGetHandlers(LLVMValueRef CatchSwitch, LLVMBasicBlockRef *Handlers);
2963
2964 /* Funclets */
2965
2966 /* Get the number of funcletpad arguments. */
2967 LLVMValueRef LLVMGetArgOperand(LLVMValueRef Funclet, unsigned i);
2968
2969 /* Set a funcletpad argument at the given index. */
2970 void LLVMSetArgOperand(LLVMValueRef Funclet, unsigned i, LLVMValueRef value);
2971
2972 /**
2973 * Get the parent catchswitch instruction of a catchpad instruction.
2974 *
2975 * This only works on llvm::CatchPadInst instructions.
2976 *
2977 * @see llvm::CatchPadInst::getCatchSwitch()
2978 */
2979 LLVMValueRef LLVMGetParentCatchSwitch(LLVMValueRef CatchPad);
2980
2981 /**
2982 * Set the parent catchswitch instruction of a catchpad instruction.
2983 *
2984 * This only works on llvm::CatchPadInst instructions.
2985 *
2986 * @see llvm::CatchPadInst::setCatchSwitch()
2987 */
2988 void LLVMSetParentCatchSwitch(LLVMValueRef CatchPad, LLVMValueRef CatchSwitch);
29222989
29232990 /* Arithmetic */
29242991 LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS,
21952195 return nullptr;
21962196 }
21972197
2198 unsigned LLVMGetNumArgOperands(LLVMValueRef Instr) {
2199 if (FuncletPadInst *FPI = dyn_cast(unwrap(Instr))) {
2200 return FPI->getNumArgOperands();
2201 }
2202 return CallSite(unwrap(Instr)).getNumArgOperands();
2203 }
2204
21982205 /*--.. Call and invoke instructions ........................................--*/
2199
2200 unsigned LLVMGetNumArgOperands(LLVMValueRef Instr) {
2201 return CallSite(unwrap(Instr)).getNumArgOperands();
2202 }
22032206
22042207 unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) {
22052208 return CallSite(unwrap(Instr)).getCallingConv();
22832286 }
22842287
22852288 LLVMBasicBlockRef LLVMGetUnwindDest(LLVMValueRef Invoke) {
2289 if (CleanupReturnInst *CRI = dyn_cast(unwrap(Invoke))) {
2290 return wrap(CRI->getUnwindDest());
2291 } else if (CatchSwitchInst *CSI = dyn_cast(unwrap(Invoke))) {
2292 return wrap(CSI->getUnwindDest());
2293 }
22862294 return wrap(unwrap(Invoke)->getUnwindDest());
22872295 }
22882296
22912299 }
22922300
22932301 void LLVMSetUnwindDest(LLVMValueRef Invoke, LLVMBasicBlockRef B) {
2302 if (CleanupReturnInst *CRI = dyn_cast(unwrap(Invoke))) {
2303 return CRI->setUnwindDest(unwrap(B));
2304 } else if (CatchSwitchInst *CSI = dyn_cast(unwrap(Invoke))) {
2305 return CSI->setUnwindDest(unwrap(B));
2306 }
22942307 unwrap(Invoke)->setUnwindDest(unwrap(B));
22952308 }
22962309
25122525 return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), NumClauses, Name));
25132526 }
25142527
2528 LLVMValueRef LLVMBuildCatchPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
2529 LLVMValueRef *Args, unsigned NumArgs,
2530 const char *Name) {
2531 return wrap(unwrap(B)->CreateCatchPad(unwrap(ParentPad),
2532 makeArrayRef(unwrap(Args), NumArgs),
2533 Name));
2534 }
2535
2536 LLVMValueRef LLVMBuildCleanupPad(LLVMBuilderRef B, LLVMValueRef ParentPad,
2537 LLVMValueRef *Args, unsigned NumArgs,
2538 const char *Name) {
2539 if (ParentPad == nullptr) {
2540 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
2541 ParentPad = wrap(Constant::getNullValue(Ty));
2542 }
2543 return wrap(unwrap(B)->CreateCleanupPad(unwrap(ParentPad),
2544 makeArrayRef(unwrap(Args), NumArgs),
2545 Name));
2546 }
2547
25152548 LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) {
25162549 return wrap(unwrap(B)->CreateResume(unwrap(Exn)));
2550 }
2551
2552 LLVMValueRef LLVMBuildCatchSwitch(LLVMBuilderRef B, LLVMValueRef ParentPad,
2553 LLVMBasicBlockRef UnwindBB,
2554 unsigned NumHandlers, const char *Name) {
2555 if (ParentPad == nullptr) {
2556 Type *Ty = Type::getTokenTy(unwrap(B)->getContext());
2557 ParentPad = wrap(Constant::getNullValue(Ty));
2558 }
2559 return wrap(unwrap(B)->CreateCatchSwitch(unwrap(ParentPad), unwrap(UnwindBB),
2560 NumHandlers, Name));
2561 }
2562
2563 LLVMValueRef LLVMBuildCatchRet(LLVMBuilderRef B, LLVMValueRef CatchPad,
2564 LLVMBasicBlockRef BB) {
2565 return wrap(unwrap(B)->CreateCatchRet(unwrap(CatchPad),
2566 unwrap(BB)));
2567 }
2568
2569 LLVMValueRef LLVMBuildCleanupRet(LLVMBuilderRef B, LLVMValueRef CatchPad,
2570 LLVMBasicBlockRef BB) {
2571 return wrap(unwrap(B)->CreateCleanupRet(unwrap(CatchPad),
2572 unwrap(BB)));
25172573 }
25182574
25192575 LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) {
25482604
25492605 void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) {
25502606 unwrap(LandingPad)->setCleanup(Val);
2607 }
2608
2609 void LLVMAddHandler(LLVMValueRef CatchSwitch, LLVMBasicBlockRef Dest) {
2610 unwrap(CatchSwitch)->addHandler(unwrap(Dest));
2611 }
2612
2613 unsigned LLVMGetNumHandlers(LLVMValueRef CatchSwitch) {
2614 return unwrap(CatchSwitch)->getNumHandlers();
2615 }
2616
2617 void LLVMGetHandlers(LLVMValueRef CatchSwitch, LLVMBasicBlockRef *Handlers) {
2618 CatchSwitchInst *CSI = unwrap(CatchSwitch);
2619 for (CatchSwitchInst::handler_iterator I = CSI->handler_begin(),
2620 E = CSI->handler_end(); I != E; ++I)
2621 *Handlers++ = wrap(*I);
2622 }
2623
2624 LLVMValueRef LLVMGetParentCatchSwitch(LLVMValueRef CatchPad) {
2625 return wrap(unwrap(CatchPad)->getCatchSwitch());
2626 }
2627
2628 void LLVMSetParentCatchSwitch(LLVMValueRef CatchPad, LLVMValueRef CatchSwitch) {
2629 unwrap(CatchPad)
2630 ->setCatchSwitch(unwrap(CatchSwitch));
2631 }
2632
2633 /*--.. Funclets ...........................................................--*/
2634
2635 LLVMValueRef LLVMGetArgOperand(LLVMValueRef Funclet, unsigned i) {
2636 return wrap(unwrap(Funclet)->getArgOperand(i));
2637 }
2638
2639 void LLVMSetArgOperand(LLVMValueRef Funclet, unsigned i, LLVMValueRef value) {
2640 unwrap(Funclet)->setArgOperand(i, unwrap(value));
25512641 }
25522642
25532643 /*--.. Arithmetic ..........................................................--*/
121121 done:
122122 ret i32 %p
123123 }
124
125 declare void @personalityFn()
126
127 define void @exn() personality void ()* @personalityFn {
128 entry:
129 invoke void @decl()
130 to label %via.cleanup unwind label %exn.dispatch
131 via.cleanup:
132 invoke void @decl()
133 to label %via.catchswitch unwind label %cleanup.inner
134 cleanup.inner:
135 %cp.inner = cleanuppad within none []
136 cleanupret from %cp.inner unwind label %exn.dispatch
137 via.catchswitch:
138 invoke void @decl()
139 to label %exit unwind label %dispatch.inner
140 dispatch.inner:
141 %cs.inner = catchswitch within none [label %pad.inner] unwind label %exn.dispatch
142 pad.inner:
143 %catch.inner = catchpad within %cs.inner [i32 0]
144 catchret from %catch.inner to label %exit
145 exn.dispatch:
146 %cs = catchswitch within none [label %pad1, label %pad2] unwind label %cleanup
147 pad1:
148 catchpad within %cs [i32 1]
149 unreachable
150 pad2:
151 catchpad within %cs [i32 2]
152 unreachable
153 cleanup:
154 %cp = cleanuppad within none []
155 cleanupret from %cp unwind to caller
156 exit:
157 ret void
158 }
145145 return LLVMMetadataTypeInContext(Ctx);
146146 case LLVMX86_MMXTypeKind:
147147 return LLVMX86MMXTypeInContext(Ctx);
148 default:
149 break;
148 case LLVMTokenTypeKind:
149 return LLVMTokenTypeInContext(Ctx);
150150 }
151151
152152 fprintf(stderr, "%d is not a supported typekind\n", Kind);
310310 return LLVMGetUndef(TypeCloner(M).Clone(Cst));
311311 }
312312
313 // Try null
314 if (LLVMIsNull(Cst)) {
315 check_value_kind(Cst, LLVMConstantTokenNoneValueKind);
316 LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
317 return LLVMConstNull(Ty);
318 }
319
313320 // Try float literal
314321 if (LLVMIsAConstantFP(Cst)) {
315322 check_value_kind(Cst, LLVMConstantFPValueKind);
630637 LLVMSetCleanup(Dst, LLVMIsCleanup(Src));
631638 break;
632639 }
640 case LLVMCleanupRet: {
641 LLVMValueRef CatchPad = CloneValue(LLVMGetOperand(Src, 0));
642 LLVMBasicBlockRef Unwind = nullptr;
643 if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(Src))
644 Unwind = DeclareBB(UDest);
645 Dst = LLVMBuildCleanupRet(Builder, CatchPad, Unwind);
646 break;
647 }
648 case LLVMCatchRet: {
649 LLVMValueRef CatchPad = CloneValue(LLVMGetOperand(Src, 0));
650 LLVMBasicBlockRef SuccBB = DeclareBB(LLVMGetSuccessor(Src, 0));
651 Dst = LLVMBuildCatchRet(Builder, CatchPad, SuccBB);
652 break;
653 }
654 case LLVMCatchPad: {
655 LLVMValueRef ParentPad = CloneValue(LLVMGetParentCatchSwitch(Src));
656 SmallVector Args;
657 int ArgCount = LLVMGetNumArgOperands(Src);
658 for (int i = 0; i < ArgCount; i++)
659 Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
660 Dst = LLVMBuildCatchPad(Builder, ParentPad,
661 Args.data(), ArgCount, Name);
662 break;
663 }
664 case LLVMCleanupPad: {
665 LLVMValueRef ParentPad = CloneValue(LLVMGetOperand(Src, 0));
666 SmallVector Args;
667 int ArgCount = LLVMGetNumArgOperands(Src);
668 for (int i = 0; i < ArgCount; i++)
669 Args.push_back(CloneValue(LLVMGetArgOperand(Src, i)));
670 Dst = LLVMBuildCleanupPad(Builder, ParentPad,
671 Args.data(), ArgCount, Name);
672 break;
673 }
674 case LLVMCatchSwitch: {
675 LLVMValueRef ParentPad = CloneValue(LLVMGetOperand(Src, 0));
676 LLVMBasicBlockRef UnwindBB = nullptr;
677 if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(Src)) {
678 UnwindBB = DeclareBB(UDest);
679 }
680 unsigned NumHandlers = LLVMGetNumHandlers(Src);
681 Dst = LLVMBuildCatchSwitch(Builder, ParentPad, UnwindBB, NumHandlers, Name);
682 if (NumHandlers > 0) {
683 LLVMBasicBlockRef *Handlers = static_cast(
684 safe_malloc(NumHandlers * sizeof(LLVMBasicBlockRef)));
685 LLVMGetHandlers(Src, Handlers);
686 for (unsigned i = 0; i < NumHandlers; i++)
687 LLVMAddHandler(Dst, DeclareBB(Handlers[i]));
688 free(Handlers);
689 }
690 break;
691 }
633692 case LLVMExtractValue: {
634693 LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
635694 if (LLVMGetNumIndices(Src) != 1)