Hi,<br><br>I'm trying to get exception handling working in my compiler targetting LLVM. I've been working from the LLVM exception handling documentation (including <a href="http://llvm.org/docs/ExceptionHandling.html">http://llvm.org/docs/ExceptionHandling.html</a> and <a href="http://wiki.llvm.org/HowTo:_Build_JIT_based_Exception_mechanism">http://wiki.llvm.org/HowTo:_Build_JIT_based_Exception_mechanism</a>) and looking at g++-llvm's output.<br>
<br>I've been trying to get a minimal test function to work, which simply invokes _Unwind_RaiseException with a single clean-up landing pad. However. when I run it my personality function is not getting called - _Unwind_RaiseException simply returns apparently doing nothing. Looking at the x86-64 assembly output from llc, I can see this is happening because the personality function is not getting into the DWARF eh table (the landing pad is there though). <br>
<br>I'm stumped as to why not. I'd be grateful if anyone can point out what I'm doing wrong here:<br><br>define i32 @_ZN4N0014Main5test5EN2IO6WriterEiA_l(%6*, %4*, i32, %33*) {<br>entry:<br> %err = alloca %4* ; <%4**> [#uses=1]<br>
%count = alloca i32 ; <i32*> [#uses=1]<br> %e = alloca %33* ; <%33**> [#uses=2]<br> %this = alloca %6* ; <%6**> [#uses=1]<br>
%.ex_value = alloca i8* ; <i8**> [#uses=1]<br> %.ex_value_l = alloca i8* ; <i8**> [#uses=0]<br> %.ex_type = alloca i64 ; <i64*> [#uses=1]<br>
br label %4<br><br>; <label>:4 ; preds = %entry<br> store %6* %0, %6** %this<br> store %4* %1, %4** %err<br> store i32 %2, i32* %count<br> store %33* %3, %33** %e<br> br label %.try_body<br>
<br>.try_body: ; preds = %4<br> %5 = load %33** %e ; <%33*> [#uses=1]<br> %6 = getelementptr inbounds %33* %5, i32 0, i32 2, i32 0 ; <i64*> [#uses=1]<br>
%7 = invoke i8* (...)* bitcast (i32 (%struct._Unwind_Exception*)* @_Unwind_RaiseException to i8* (...)*)(i64* %6)<br> to label %8 unwind label %.finally_pad ; <i8*> [#uses=0]<br><br>; <label>:8 ; preds = %.try_body<br>
br label %.finally_handler<br><br>.finally_pad: ; preds = %.try_body<br> %9 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]<br> store i8* %9, i8** %.ex_value<br>
%10 = call i64 (i8*, i8*, ...)* @llvm.eh.selector.i64(i8* %9, i8* bitcast (i32 (i32, i32, i64, %struct._Unwind_Exception*, %struct._Unwind_Context*)* @__l_personality to i8*)) ; <i64> [#uses=1]<br> %11 = icmp eq i64 %10, 0 ; <i1> [#uses=1]<br>
%12 = select i1 %11, i64 0, i64 1 ; <i64> [#uses=1]<br> store i64 %12, i64* %.ex_type<br> br label %.finally_handler<br><br>.finally_handler: ; preds = %.finally_pad, %8<br>
%13 = call i8* (...)* bitcast (i32 (i8*, ...)* @printf to i8* (...)*)(i8* getelementptr ([9 x i8]* @__string_27, i32 0, i32 0)) ; <i8*> [#uses=0]<br> ret i32 0<br>}<br><br>Thanks in advance,<br>-- James Williams<br>
<br>PS: Thanks to all LLVM contributers for such a well designed IR and code generation library. Switching my compiler from its existing back end to LLVM has so far been incredibly quick and easy - a matter of a few evenings and a couple of weekends!<br>