declare i32 @puts(ptr nocapture readonly)
declare void @exit(i32)

define void @handle_exception(ptr %ex_ptr) personality i32(...)* @__gxx_personality_v0 { 
entry: 
  %str = alloca [16 x i8], align 1 
  %str_ptr = getelementptr inbounds [16 x i8], ptr %str, i32 0, i32 0 
  store [17 x i8] c "Exception caught!", ptr %str, align 1 
  call i32 @puts(ptr %str_ptr) 
  ret void 
}

define i32 @throwing_function() personality i32(...)* @__gxx_personality_v0 { 
entry: 
  %dummy_ex = alloca i32, align 4 
  invoke void @exit(i32 1) to label %invoke.cont unwind label %lpad invoke.cont: 
  unreachable lpad: 
  %ex = landingpad { ptr, i32 } cleanup 
  %ex_ptr = extractvalue { ptr, i32 } %ex, 0 
  call void @handle_exception(ptr %ex_ptr) 
  ret i32 0 
}

define i32 @main() { 
entry: 
  %result = call i32 @throwing_function() 
  ret i32 0 
}

declare i32 @__gxx_personality_v0(...)