; ModuleID = 'ExceptionTest' %Object = type {} %UnwindInfo = type { i64, void (i32, %UnwindInfo *)*, i16, i16 } %UnwindContext = type opaque %Throwable = type { %Object, %UnwindInfo } @str_fmt = internal constant [4 x i8] c"%s\0A\00" @str_begin = internal constant [6 x i8] c"begin\00" @str_throw = internal constant [6 x i8] c"throw\00" @str_catch = internal constant [6 x i8] c"catch\00" @str_nocatch = internal constant [8 x i8] c"nocatch\00" ; action codes @UA_SEARCH_PHASE = internal constant i32 1 @UA_CLEANUP_PHASE = internal constant i32 2 @UA_HANDLER_FRAME = internal constant i32 4 @UA_FORCE_UNWIND = internal constant i32 8 ; reason codes @URC_NO_REASON = internal constant i32 0 @URC_FOREIGN_EXCEPTION_CAUGHT = internal constant i32 1 @URC_FATAL_PHASE2_ERROR = internal constant i32 2 @URC_FATAL_PHASE1_ERROR = internal constant i32 3 @URC_NORMAL_STOP = internal constant i32 4 @URC_END_OF_STACK = internal constant i32 5 @URC_HANDLER_FOUND = internal constant i32 6 @URC_INSTALL_CONTEXT = internal constant i32 7 @URC_CONTINUE_UNWIND = internal constant i32 8 declare i32 @__gcc_personality_v0(i32, i32, i64, i8*, %UnwindContext*) nounwind define i32 @main(i32, i8**) nounwind { entry: call void @print(i8* bitcast ([6 x i8]* @str_begin to i8 *)) invoke fastcc void @throwSomething() to label %nounwind unwind label %catch; catch: %eh_ptr = call i8* @llvm.eh.exception(); %eh_select34 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32 ( i8* %eh_ptr, i8* bitcast (i32 (i32, i32, i64, i8*, %UnwindContext*)* @__gcc_personality_v0 to i8*), i32 0) call void @print(i8* bitcast ([6 x i8]* @str_catch to i8 *)) ret i32 0 cc0: call void @print(i8* bitcast ([6 x i8]* @str_catch to i8 *)) ret i32 0 nounwind: call void @print(i8* bitcast ([8 x i8]* @str_nocatch to i8 *)) ret i32 -1 } define internal fastcc void @throwSomething() noreturn { entry: %throwable = malloc %Throwable call fastcc void @Throwable.construct(%Throwable* %throwable) %unwindInfo = getelementptr %Throwable* %throwable, i32 0, i32 1 call void @print(i8* bitcast ([6 x i8]* @str_throw to i8 *)) %throw = call i32 @_Unwind_RaiseException(%UnwindInfo* %unwindInfo) unreachable } define internal fastcc void @Throwable.construct(%Throwable* %self) nounwind { entry: %exceptionClass = getelementptr %Throwable* %self, i32 0, i32 1, i32 0 store i64 0, i64* %exceptionClass %exceptionCleanup = getelementptr %Throwable* %self, i32 0, i32 1, i32 1 store void (i32, %UnwindInfo *)* @exceptionCleanupFn, void (i32, %UnwindInfo *)** %exceptionCleanup %private1 = getelementptr %Throwable* %self, i32 0, i32 1, i32 2 store i16 0, i16* %private1 %private2 = getelementptr %Throwable* %self, i32 0, i32 1, i32 3 store i16 0, i16* %private2 ret void } define internal void @exceptionCleanupFn(i32 %reason, %UnwindInfo * %exc) { ret void } declare i32 @_Unwind_RaiseException(%UnwindInfo*) noreturn declare void @_Unwind_SetIP(%UnwindContext*, i8*); declare i8* @llvm.eh.exception() nounwind declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind declare void @printf(i8*, ...) nounwind define i32 @print(i8* %msg) nounwind { call void (i8*, ...)* @printf(i8* bitcast([4 x i8]* @str_fmt to i8*), i8* %msg) ret void }