Hello all, I have a number of questions about the correct usage of the LLVM IR exception handling intrinsics. I am implementing a language of my own and have come to consider implementing exceptions and exception handling. I looked at the IR generated by Clang for some simple functions. I saw calls to, for example, __cxa_throw. But what I didn't see is any DWARF data tables or SJLJ pushing/popping. I know that for some targets, including the one that I use most, which is mingw32, there are multiple possible implementations (DWARF and SEH). So how can the code generator know how to implement the intrinsics like landing pad? Furthermore, even if there is some option in the LLVM API which I did not see, which specifies which option to use, then why are some other parts of the EH API so low-level? If the backend can determine that I intended Itanium ABI DWARF exception handling, then it should also know how to implement throw and catch based on that spec. It therefore seems unnecessary that other parts of the API involve digging around in exception tables. The documentation also raises further questions about other EH implementations. Only Itanium ABI and SJLJ are referenced. I'm pretty sure that SEH is a derivative of SJLJ, but what about the other EH handling mechanisms, like Windows x64? There are also intrinsics for values that make no sense. A prime example is the "selector" value, returned by typeid.for. The Itanium ABI makes absolutely no reference to a selector value of any kind. The documentation says that it returns an index into the exception table. How does it behave if SJLJ EH was chosen? What use would that even be, anyway? It is said that it is to be compared against the result of the landingpad instruction, but there's nothing saying what the landingpad returns or what the results would mean. This is further compounded by the fact that it's at least implied that the landingpad can actually return virtually any type. How could you compare an i32 against a landingpad that returns a pointer to a pointer to a std::string? What even are the valid return types of a landingpad instruction? The EH intrinsics specify that some parts of the Itanium ABI handling involve calling functions like __cxa_begin_catch. But how should these functions be implemented? The SJLJ documentation is even more vague- no API is even suggested. I have searched for examples for implementing EH on top of LLVM, and virtually the only one available is Clang. This is not terribly helpful since you'd inherently expect Clang to be coupled to the various C++ implementations used and it's not like a C++ implementation is going to be able to take the simple approach. I guess what I'm saying here is, how on earth do you put these pieces together and actually throw or catch an exception? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131222/7513bbfc/attachment.html>
Hi, mingw32 / Win32 / dwarf exceptions are implemented in clang/LLVM and are well-tested. SJLJ isn't implemented in Windows. Kai Nacke implemented a patch for mingw32 / Win64 / SEH exceptions for the LDC compiler on top of LLVM, see http://wiki.dlang.org/Building_and_hacking_LDC_on_Windows_using_MSVC (Patch adding Win64 SEH to LLVM 3.5) and is working to integrating it back into trunk. Yaron 2013/12/23 DeadMG <wolfeinstein at gmail.com>> Hello all, > > I have a number of questions about the correct usage of the LLVM IR > exception handling intrinsics. I am implementing a language of my own and > have come to consider implementing exceptions and exception handling. > > I looked at the IR generated by Clang for some simple functions. I saw > calls to, for example, __cxa_throw. But what I didn't see is any DWARF data > tables or SJLJ pushing/popping. I know that for some targets, including the > one that I use most, which is mingw32, there are multiple possible > implementations (DWARF and SEH). So how can the code generator know how to > implement the intrinsics like landing pad? > > Furthermore, even if there is some option in the LLVM API which I did not > see, which specifies which option to use, then why are some other parts of > the EH API so low-level? If the backend can determine that I intended > Itanium ABI DWARF exception handling, then it should also know how to > implement throw and catch based on that spec. It therefore seems > unnecessary that other parts of the API involve digging around in exception > tables. > > The documentation also raises further questions about other EH > implementations. Only Itanium ABI and SJLJ are referenced. I'm pretty sure > that SEH is a derivative of SJLJ, but what about the other EH handling > mechanisms, like Windows x64? > > There are also intrinsics for values that make no sense. A prime example > is the "selector" value, returned by typeid.for. The Itanium ABI makes > absolutely no reference to a selector value of any kind. The documentation > says that it returns an index into the exception table. How does it behave > if SJLJ EH was chosen? What use would that even be, anyway? It is said that > it is to be compared against the result of the landingpad instruction, but > there's nothing saying what the landingpad returns or what the results > would mean. This is further compounded by the fact that it's at least > implied that the landingpad can actually return virtually any type. How > could you compare an i32 against a landingpad that returns a pointer to a > pointer to a std::string? What even are the valid return types of a > landingpad instruction? > > The EH intrinsics specify that some parts of the Itanium ABI handling > involve calling functions like __cxa_begin_catch. But how should these > functions be implemented? The SJLJ documentation is even more vague- no API > is even suggested. > > I have searched for examples for implementing EH on top of LLVM, and > virtually the only one available is Clang. This is not terribly helpful > since you'd inherently expect Clang to be coupled to the various C++ > implementations used and it's not like a C++ implementation is going to be > able to take the simple approach. > > I guess what I'm saying here is, how on earth do you put these pieces > together and actually throw or catch an exception? > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131223/2e0775d4/attachment.html>
I don't know if you are familiar with the D language, but it also supports exceptions and has an LLVM frontend. It can be found at https://github.com/ldc-developers/ldc. -- Mikael 2013/12/23 DeadMG <wolfeinstein at gmail.com>> Hello all, > > I have a number of questions about the correct usage of the LLVM IR > exception handling intrinsics. I am implementing a language of my own and > have come to consider implementing exceptions and exception handling. > > I looked at the IR generated by Clang for some simple functions. I saw > calls to, for example, __cxa_throw. But what I didn't see is any DWARF data > tables or SJLJ pushing/popping. I know that for some targets, including the > one that I use most, which is mingw32, there are multiple possible > implementations (DWARF and SEH). So how can the code generator know how to > implement the intrinsics like landing pad? > > Furthermore, even if there is some option in the LLVM API which I did not > see, which specifies which option to use, then why are some other parts of > the EH API so low-level? If the backend can determine that I intended > Itanium ABI DWARF exception handling, then it should also know how to > implement throw and catch based on that spec. It therefore seems > unnecessary that other parts of the API involve digging around in exception > tables. > > The documentation also raises further questions about other EH > implementations. Only Itanium ABI and SJLJ are referenced. I'm pretty sure > that SEH is a derivative of SJLJ, but what about the other EH handling > mechanisms, like Windows x64? > > There are also intrinsics for values that make no sense. A prime example > is the "selector" value, returned by typeid.for. The Itanium ABI makes > absolutely no reference to a selector value of any kind. The documentation > says that it returns an index into the exception table. How does it behave > if SJLJ EH was chosen? What use would that even be, anyway? It is said that > it is to be compared against the result of the landingpad instruction, but > there's nothing saying what the landingpad returns or what the results > would mean. This is further compounded by the fact that it's at least > implied that the landingpad can actually return virtually any type. How > could you compare an i32 against a landingpad that returns a pointer to a > pointer to a std::string? What even are the valid return types of a > landingpad instruction? > > The EH intrinsics specify that some parts of the Itanium ABI handling > involve calling functions like __cxa_begin_catch. But how should these > functions be implemented? The SJLJ documentation is even more vague- no API > is even suggested. > > I have searched for examples for implementing EH on top of LLVM, and > virtually the only one available is Clang. This is not terribly helpful > since you'd inherently expect Clang to be coupled to the various C++ > implementations used and it's not like a C++ implementation is going to be > able to take the simple approach. > > I guess what I'm saying here is, how on earth do you put these pieces > together and actually throw or catch an exception? > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20131223/5f59ea0e/attachment.html>