[LLVM-C] Finish exception instruction bindings

Summary:
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, echristo

Reviewed By: echristo

Subscribers: llvm-commits, harlanhaskins

Differential Revision: https://reviews.llvm.org/D44496

llvm-svn: 328759
diff --git a/llvm/tools/llvm-c-test/echo.cpp b/llvm/tools/llvm-c-test/echo.cpp
index 29eb8d8..20269bcb 100644
--- a/llvm/tools/llvm-c-test/echo.cpp
+++ b/llvm/tools/llvm-c-test/echo.cpp
@@ -146,8 +146,8 @@
         return LLVMMetadataTypeInContext(Ctx);
       case LLVMX86_MMXTypeKind:
         return LLVMX86MMXTypeInContext(Ctx);
-      default:
-        break;
+      case LLVMTokenTypeKind:
+        return LLVMTokenTypeInContext(Ctx);
     }
 
     fprintf(stderr, "%d is not a supported typekind\n", Kind);
@@ -311,6 +311,13 @@
     return LLVMGetUndef(TypeCloner(M).Clone(Cst));
   }
 
+  // Try null
+  if (LLVMIsNull(Cst)) {
+    check_value_kind(Cst, LLVMConstantTokenNoneValueKind);
+    LLVMTypeRef Ty = TypeCloner(M).Clone(Cst);
+    return LLVMConstNull(Ty);
+  }
+
   // Try float literal
   if (LLVMIsAConstantFP(Cst)) {
     check_value_kind(Cst, LLVMConstantFPValueKind);
@@ -631,6 +638,57 @@
         LLVMSetCleanup(Dst, LLVMIsCleanup(Src));
         break;
       }
+      case LLVMCleanupRet: {
+        LLVMValueRef CatchPad = CloneValue(LLVMGetOperand(Src, 0));
+        LLVMBasicBlockRef Unwind = nullptr;
+        if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(Src))
+          Unwind = DeclareBB(UDest);
+        Dst = LLVMBuildCleanupRet(Builder, CatchPad, Unwind);
+        break;
+      }
+      case LLVMCatchRet: {
+        LLVMValueRef CatchPad = CloneValue(LLVMGetOperand(Src, 0));
+        LLVMBasicBlockRef SuccBB = DeclareBB(LLVMGetSuccessor(Src, 0));
+        Dst = LLVMBuildCatchRet(Builder, CatchPad, SuccBB);
+        break;
+      }
+      case LLVMCatchPad: {
+        LLVMValueRef ParentPad = CloneValue(LLVMGetParentCatchSwitch(Src));
+        SmallVector<LLVMValueRef, 8> Args;
+        int ArgCount = LLVMGetNumArgOperands(Src);
+        for (int i = 0; i < ArgCount; i++)
+          Args.push_back(CloneValue(LLVMGetOperand(Src, i)));
+        Dst = LLVMBuildCatchPad(Builder, ParentPad,
+                                Args.data(), ArgCount, Name);
+        break;
+      }
+      case LLVMCleanupPad: {
+        LLVMValueRef ParentPad = CloneValue(LLVMGetOperand(Src, 0));
+        SmallVector<LLVMValueRef, 8> Args;
+        int ArgCount = LLVMGetNumArgOperands(Src);
+        for (int i = 0; i < ArgCount; i++)
+          Args.push_back(CloneValue(LLVMGetArgOperand(Src, i)));
+        Dst = LLVMBuildCleanupPad(Builder, ParentPad,
+                                  Args.data(), ArgCount, Name);
+        break;
+      }
+      case LLVMCatchSwitch: {
+        LLVMValueRef ParentPad = CloneValue(LLVMGetOperand(Src, 0));
+        LLVMBasicBlockRef UnwindBB = nullptr;
+        if (LLVMBasicBlockRef UDest = LLVMGetUnwindDest(Src)) {
+          UnwindBB = DeclareBB(UDest);
+        }
+        unsigned NumHandlers = LLVMGetNumHandlers(Src);
+        Dst = LLVMBuildCatchSwitch(Builder, ParentPad, UnwindBB, NumHandlers, Name);
+        if (NumHandlers > 0) {
+          LLVMBasicBlockRef *Handlers = static_cast<LLVMBasicBlockRef*>(
+                       safe_malloc(NumHandlers * sizeof(LLVMBasicBlockRef)));
+          LLVMGetHandlers(Src, Handlers);
+          for (unsigned i = 0; i < NumHandlers; i++)
+            LLVMAddHandler(Dst, DeclareBB(Handlers[i]));
+        }
+        break;
+      }
       case LLVMExtractValue: {
         LLVMValueRef Agg = CloneValue(LLVMGetOperand(Src, 0));
         if (LLVMGetNumIndices(Src) != 1)