-
-
Notifications
You must be signed in to change notification settings - Fork 134
adds experimental support for C++20 modules #248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
967964c
ded6ca9
1a0454c
c73cceb
6c27579
d3d6bdc
25a75dc
2375e9f
af8b2db
190a07e
a6f5018
0a8c500
ec9f31c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ install( | |
ARCHIVE # | ||
COMPONENT ${package_name}_development | ||
INCLUDES # | ||
FILE_SET CXX_MODULES | ||
|
||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" | ||
) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export module cpptrace; | ||
|
||
int main() | ||
|
||
{} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#ifndef CPPTRACE_EXCEPTIONS_MACROS_HPP | ||
#define CPPTRACE_EXCEPTIONS_MACROS_HPP | ||
|
||
// Exception wrapper utilities | ||
#define CPPTRACE_WRAP_BLOCK(statements) do { \ | ||
try { \ | ||
statements \ | ||
} catch(...) { \ | ||
::cpptrace::rethrow_and_wrap_if_needed(); \ | ||
} \ | ||
} while(0) | ||
|
||
#define CPPTRACE_WRAP(expression) [&] () -> decltype((expression)) { \ | ||
try { \ | ||
return expression; \ | ||
} catch(...) { \ | ||
::cpptrace::rethrow_and_wrap_if_needed(1); \ | ||
} \ | ||
} () | ||
|
||
#endif // CPPTRACE_EXCEPTIONS_MACROS_HPP |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#ifndef CPPTRACE_FROM_CURRENT_MACROS_HPP | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, is there a sensible way to make either of the following work instead of a new macros header? #include <cpptrace/from_current.hpp>
import cpptrace;
// or
import cpptrace;
#include <cpptrace/from_current.hpp> If a macros header is the best way to do this I think it's good with me - and I'm guessing if so other libraries might follow the same pattern. But I'd love to be able to keep There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can do the former, but not the latter (yet). Having said that, including #include <cpptrace/from_current_macros.hpp>
import cpptrace; Once support for modules stabilises, I'd recommend the docs encourage header users not include the |
||
#define CPPTRACE_FROM_CURRENT_MACROS_HPP | ||
|
||
// https://godbolt.org/z/4MsT6KqP1 | ||
#ifdef _MSC_VER | ||
#define CPPTRACE_UNREACHABLE() __assume(false) | ||
#else | ||
#define CPPTRACE_UNREACHABLE() __builtin_unreachable() | ||
#endif | ||
|
||
// https://godbolt.org/z/7neGPEche | ||
// gcc added support in 4.8 but I'm too lazy to check the minor version | ||
#if defined(__GNUC__) && (__GNUC__ < 5) | ||
#define CPPTRACE_NORETURN __attribute__((noreturn)) | ||
#else | ||
#define CPPTRACE_NORETURN [[noreturn]] | ||
#endif | ||
|
||
#ifdef _MSC_VER | ||
#define CPPTRACE_TYPE_FOR(param) \ | ||
::cpptrace::detail::argument<void(param)>::type | ||
// this awful double-IILE is due to C2713 "You can't use structured exception handling (__try/__except) and C++ | ||
// exception handling (try/catch) in the same function." | ||
#define CPPTRACE_TRY \ | ||
try { \ | ||
[&]() { \ | ||
__try { \ | ||
[&]() { | ||
#define CPPTRACE_CATCH(param) \ | ||
}(); \ | ||
} __except(::cpptrace::detail::exception_filter<CPPTRACE_TYPE_FOR(param)>(GetExceptionInformation())) {} \ | ||
}(); \ | ||
} catch(param) | ||
#else | ||
#define CPPTRACE_UNWIND_INTERCEPTOR_FOR(param) \ | ||
::cpptrace::detail::unwind_interceptor_for<void(param)> | ||
#define CPPTRACE_TRY \ | ||
try { \ | ||
try { | ||
#define CPPTRACE_CATCH(param) \ | ||
} catch(const CPPTRACE_UNWIND_INTERCEPTOR_FOR(param)&) { \ | ||
CPPTRACE_UNREACHABLE(); \ | ||
/* force instantiation of the init-er */ \ | ||
::cpptrace::detail::nop(CPPTRACE_UNWIND_INTERCEPTOR_FOR(param)::init); \ | ||
} \ | ||
} catch(param) | ||
#endif | ||
|
||
#ifdef CPPTRACE_UNPREFIXED_TRY_CATCH | ||
#define TRY CPPTRACE_TRY | ||
#define CATCH(param) CPPTRACE_CATCH(param) | ||
#endif | ||
|
||
#endif // CPPTRACE_FROM_CURRENT_MACROS_HPP |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
module; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest module interface files to end with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not convinced that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The uniform convention can help people to identify things more easily. E.g., I can search for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, as is the way of C++, it looks like people are already using a wide variety of extensions for modules https://github.com/search?type=code&q=%2F%5E%28%3F-i%29module%3B%2F+language%3Ac%2B%2B+-is%3Afork&p=1. I'm not super opinionated on this issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this is not a forcement but a suggestion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I'm avoidant is because the original GCC modules implementer told me that he was discouraging a different file extension after some experience. I don't think LLVM has that same aversion. Having said that, I've literally named the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After discussion I went ahead and updated it to .cppm - since this file will be installed to |
||
#include <cpptrace/basic.hpp> | ||
#include <cpptrace/cpptrace.hpp> | ||
#include <cpptrace/exceptions.hpp> | ||
#include <cpptrace/formatting.hpp> | ||
#include <cpptrace/forward.hpp> | ||
#include <cpptrace/from_current.hpp> | ||
#include <cpptrace/gdb_jit.hpp> | ||
|
||
export module cpptrace; | ||
|
||
namespace cpptrace::inline v1 { | ||
|
||
// cpptrace/basic | ||
export using cpptrace::raw_trace; | ||
export using cpptrace::object_frame; | ||
export using cpptrace::object_trace; | ||
export using cpptrace::nullable; | ||
export using cpptrace::stacktrace_frame; | ||
export using cpptrace::stacktrace; | ||
export using cpptrace::generate_raw_trace; | ||
export using cpptrace::generate_object_trace; | ||
export using cpptrace::generate_trace; | ||
export using cpptrace::safe_generate_raw_trace; | ||
export using cpptrace::safe_object_frame; | ||
export using cpptrace::can_get_safe_object_frame; | ||
export using cpptrace::can_signal_safe_unwind; | ||
export using cpptrace::can_get_safe_object_frame; | ||
export using cpptrace::register_jit_object; | ||
export using cpptrace::unregister_jit_object; | ||
export using cpptrace::clear_all_jit_objects; | ||
|
||
// cpptrace/exceptions | ||
export using cpptrace::exception; | ||
export using cpptrace::lazy_exception; | ||
export using cpptrace::exception_with_message; | ||
export using cpptrace::logic_error; | ||
export using cpptrace::domain_error; | ||
export using cpptrace::invalid_argument; | ||
export using cpptrace::length_error; | ||
export using cpptrace::out_of_range; | ||
export using cpptrace::runtime_error; | ||
export using cpptrace::range_error; | ||
export using cpptrace::overflow_error; | ||
export using cpptrace::underflow_error; | ||
export using cpptrace::nested_exception; | ||
export using cpptrace::system_error; | ||
export using cpptrace::rethrow_and_wrap_if_needed; | ||
|
||
// cpptrace/formatting | ||
export using cpptrace::basename; | ||
export using cpptrace::prettify_symbol; | ||
export using cpptrace::formatter; | ||
export using cpptrace::get_default_formatter; | ||
|
||
// cpptrace/forward | ||
export using cpptrace::frame_ptr; | ||
|
||
// cpptrace/from_current.hpp | ||
export using cpptrace::raw_trace_from_current_exception; | ||
export using cpptrace::from_current_exception; | ||
export using cpptrace::raw_trace_from_current_exception_rethrow; | ||
export using cpptrace::from_current_exception_rethrow; | ||
export using cpptrace::current_exception_was_rethrown; | ||
export using cpptrace::rethrow; | ||
export using cpptrace::clear_current_exception_traces; | ||
export using cpptrace::try_catch; | ||
|
||
namespace detail { | ||
#ifdef _MSC_VER | ||
export using cpptrace::detail::argument; | ||
export using cpptrace::detail::exception_filter; | ||
#else | ||
export using cpptrace::detail::unwind_interceptor_for; | ||
export using cpptrace::detail::nop; | ||
#endif | ||
} | ||
|
||
// cpptrace/gdb_jit | ||
namespace experimental { | ||
export using cpptrace::experimental::register_jit_objects_from_gdb_jit_interface; | ||
} | ||
|
||
// cpptrace/io | ||
export using cpptrace::operator<<; // FIXME: make hidden friend | ||
|
||
// cpptrace/utils | ||
export using cpptrace::demangle; | ||
export using cpptrace::get_snippet; | ||
export using cpptrace::isatty; | ||
export using cpptrace::stdin_fileno; | ||
export using cpptrace::stderr_fileno; | ||
export using cpptrace::stdout_fileno; | ||
export using cpptrace::register_terminate_handler; | ||
export using cpptrace::absorb_trace_exceptions; | ||
export using cpptrace::enable_inlined_call_resolution; | ||
export using cpptrace::cache_mode; | ||
export using cpptrace::log_level; | ||
export using cpptrace::set_log_level; | ||
export using cpptrace::set_log_callback; | ||
export using cpptrace::use_default_stderr_logger; | ||
export using cpptrace::cache_mode; | ||
|
||
namespace experimental { | ||
export using cpptrace::experimental::set_cache_mode; | ||
export using cpptrace::experimental::set_dwarf_resolver_line_table_cache_size; | ||
export using cpptrace::experimental::set_dwarf_resolver_disable_aranges; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this test will pass for much older versions of clang than I was expecting, all the way back to clang 10 while I'm under the impression the module implementation only got more feature-complete and stable recently https://gcc.godbolt.org/z/4r73zGxd6. On the other hand, it won't work for any version of gcc because of
-fmodules
(which might be ok, not sure how stable gcc is yet but I'm under the impression they're at least close to feature-complete / stability). Thoughts on how best to approach this? I'm not sure what the best default behavior is.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, that's going too far back. CMake support for modules is only very recent, so I guess we could gate on compiler versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking compiler version might be more robust yeah (but more of a hassle to check)