Created
May 11, 2011 20:37
-
-
Save ytomino/967290 to your computer and use it in GitHub Desktop.
LLVM exception test with libstdc++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; llvm-as c++exn.ll && llvm-ld -native c++exn.bc -lstdc++.6 && ./a.out | |
; LLVM primitives | |
declare i8* @llvm.eh.exception() nounwind readonly | |
declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind | |
declare i32 @llvm.eh.typeid.for(i8*) nounwind | |
; libc | |
declare i32 @puts(i8*) | |
; libgcc | |
declare void @_Unwind_Resume_or_Rethrow(i8*) | |
; libstdc++ | |
declare i32 @__gxx_personality_v0(...) | |
declare i8* @__cxa_allocate_exception(i32) | |
declare void @__cxa_throw(i8*, i8*, i8*) | |
declare i8* @__cxa_begin_catch(i8*) | |
declare void @__cxa_end_catch() | |
@_ZTIi = external constant i8* ; typeinfo(int) | |
@_ZTIf = external constant i8* ; typeinfo(float) | |
@str0 = private constant [4 x i8] c"int\00" | |
@str1 = private constant [6 x i8] c"float\00" | |
define i32 @main() { | |
%reraising_exn = alloca i8* | |
%raising_exn = call i8* @__cxa_allocate_exception(i32 4) nounwind | |
%raising_exn.ptr = bitcast i8* %raising_exn to i32* | |
store i32 0, i32* %raising_exn.ptr | |
invoke void @__cxa_throw(i8* %raising_exn, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn | |
to label %after_try | |
unwind label %begin_catch | |
begin_catch: | |
%exn = call i8* @llvm.eh.exception() nounwind | |
store i8* %exn, i8** %reraising_exn | |
%sel = call i32 (i8*, i8*, ...)* @llvm.eh.selector( | |
i8* %exn, | |
i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), | |
i8* bitcast (i8** @_ZTIi to i8*), | |
i8* bitcast (i8** @_ZTIf to i8*), | |
i8* null) nounwind | |
br label %when_int | |
when_int: | |
%eh.int.typeid = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) nounwind | |
%eh.int.comp = icmp eq i32 %sel, %eh.int.typeid | |
br i1 %eh.int.comp, label %catch_int, label %when_float | |
catch_int: | |
%eh.int.obj = call i8* @__cxa_begin_catch(i8* %exn) nounwind | |
%eh.int.ptr = bitcast i8* %eh.int.obj to i32* | |
%eh.int.val = load i32* %eh.int.ptr | |
invoke i32 @puts(i8* getelementptr inbounds ([4 x i8]* @str0, i32 0, i32 0)) | |
to label %end_catch | |
unwind label %raise_another | |
when_float: | |
%eh.float.typeid = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIf to i8*)) nounwind | |
%eh.float.comp = icmp eq i32 %sel, %eh.float.typeid | |
br i1 %eh.float.comp, label %catch_float, label %reraising | |
catch_float: | |
%eh.float.obj = call i8* @__cxa_begin_catch(i8* %exn) nounwind | |
%eh.float.ptr = bitcast i8* %eh.float.obj to float* | |
%eh.float.val = load float* %eh.float.ptr | |
invoke i32 @puts(i8* getelementptr inbounds ([6 x i8]* @str1, i32 0, i32 0)) | |
to label %end_catch | |
unwind label %raise_another | |
end_catch: | |
call void @__cxa_end_catch() nounwind | |
br label %after_try | |
raise_another: | |
%ra.exn = call i8* @llvm.eh.exception() nounwind | |
store i8* %ra.exn, i8** %reraising_exn | |
%ra.sel = call i32 (i8*, i8*, ...)* @llvm.eh.selector( | |
i8* %ra.exn, | |
i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), | |
i8* null) nounwind | |
call void @__cxa_end_catch() nounwind | |
br label %reraising | |
reraising: | |
%reraising_exn.val = load i8** %reraising_exn | |
call void @_Unwind_Resume_or_Rethrow(i8* %reraising_exn.val) noreturn | |
unreachable | |
after_try: ; after try-catch statement | |
ret i32 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment