diff --git a/strings/base_error.h b/strings/base_error.h index 8a3a3a08..21010ccb 100644 --- a/strings/base_error.h +++ b/strings/base_error.h @@ -104,17 +104,17 @@ WINRT_EXPORT namespace winrt return *this; } - explicit hresult_error(hresult const code WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : m_code(verify_error(code)) + explicit hresult_error(hresult const code, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : m_code(verify_error(code)) { - originate(code, nullptr WINRT_IMPL_SOURCE_LOCATION_FORWARD); + originate(code, nullptr, sourceInformation); } - hresult_error(hresult const code, param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : m_code(verify_error(code)) + hresult_error(hresult const code, param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : m_code(verify_error(code)) { - originate(code, get_abi(message) WINRT_IMPL_SOURCE_LOCATION_FORWARD); + originate(code, get_abi(message), sourceInformation); } - hresult_error(hresult const code, take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : m_code(verify_error(code)) + hresult_error(hresult const code, take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : m_code(verify_error(code)) { com_ptr info; WINRT_IMPL_GetErrorInfo(0, info.put_void()); @@ -144,7 +144,7 @@ WINRT_EXPORT namespace winrt message = impl::trim_hresult_message(legacy.get(), WINRT_IMPL_SysStringLen(legacy.get())); } - originate(code, get_abi(message) WINRT_IMPL_SOURCE_LOCATION_FORWARD); + originate(code, get_abi(message), sourceInformation); } } @@ -199,7 +199,7 @@ WINRT_EXPORT namespace winrt private: - void originate(hresult const code, void* message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept + void originate(hresult const code, void* message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept { WINRT_VERIFY(WINRT_IMPL_RoOriginateLanguageException(code, message, nullptr)); @@ -208,11 +208,7 @@ WINRT_EXPORT namespace winrt // information is available on the caller who generated the error. if (winrt_throw_hresult_handler) { -#ifdef WINRT_SOURCE_LOCATION_ACTIVE winrt_throw_hresult_handler(sourceInformation.line(), sourceInformation.file_name(), sourceInformation.function_name(), WINRT_IMPL_RETURNADDRESS(), code); -#else - winrt_throw_hresult_handler(0, nullptr, nullptr, WINRT_IMPL_RETURNADDRESS(), code); -#endif } com_ptr info; @@ -244,104 +240,100 @@ WINRT_EXPORT namespace winrt struct hresult_access_denied : hresult_error { - hresult_access_denied(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_access_denied WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_access_denied(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_access_denied, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_access_denied(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_access_denied, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_access_denied(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_access_denied, sourceInformation) {} + hresult_access_denied(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_access_denied, message, sourceInformation) {} + hresult_access_denied(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_access_denied, take_ownership_from_abi, sourceInformation) {} }; struct hresult_wrong_thread : hresult_error { - hresult_wrong_thread(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_wrong_thread WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_wrong_thread(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_wrong_thread, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_wrong_thread(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_wrong_thread, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_wrong_thread(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_wrong_thread, sourceInformation) {} + hresult_wrong_thread(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_wrong_thread, message, sourceInformation) {} + hresult_wrong_thread(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_wrong_thread, take_ownership_from_abi, sourceInformation) {} }; struct hresult_not_implemented : hresult_error { - hresult_not_implemented(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_not_implemented WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_not_implemented(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_not_implemented, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_not_implemented(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_not_implemented, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_not_implemented(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_not_implemented, sourceInformation) {} + hresult_not_implemented(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_not_implemented, message, sourceInformation) {} + hresult_not_implemented(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_not_implemented, take_ownership_from_abi, sourceInformation) {} }; struct hresult_invalid_argument : hresult_error { - hresult_invalid_argument(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_invalid_argument WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_invalid_argument(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_invalid_argument, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_invalid_argument(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_invalid_argument, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_invalid_argument(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_invalid_argument, sourceInformation) {} + hresult_invalid_argument(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_invalid_argument, message, sourceInformation) {} + hresult_invalid_argument(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_invalid_argument, take_ownership_from_abi, sourceInformation) {} }; struct hresult_out_of_bounds : hresult_error { - hresult_out_of_bounds(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_out_of_bounds WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_out_of_bounds(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_out_of_bounds, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_out_of_bounds(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_out_of_bounds, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_out_of_bounds(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_out_of_bounds, sourceInformation) {} + hresult_out_of_bounds(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_out_of_bounds, message, sourceInformation) {} + hresult_out_of_bounds(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_out_of_bounds, take_ownership_from_abi, sourceInformation) {} }; struct hresult_no_interface : hresult_error { - hresult_no_interface(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_no_interface WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_no_interface(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_no_interface, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_no_interface(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_no_interface, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_no_interface(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_no_interface, sourceInformation) {} + hresult_no_interface(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_no_interface, message, sourceInformation) {} + hresult_no_interface(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_no_interface, take_ownership_from_abi, sourceInformation) {} }; struct hresult_class_not_available : hresult_error { - hresult_class_not_available(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_class_not_available WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_class_not_available(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_class_not_available, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_class_not_available(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_class_not_available, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_class_not_available(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_class_not_available, sourceInformation) {} + hresult_class_not_available(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_class_not_available, message, sourceInformation) {} + hresult_class_not_available(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_class_not_available, take_ownership_from_abi, sourceInformation) {} }; struct hresult_class_not_registered : hresult_error { - hresult_class_not_registered(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_class_not_registered WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_class_not_registered(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_class_not_registered, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_class_not_registered(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_class_not_registered, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_class_not_registered(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_class_not_registered, sourceInformation) {} + hresult_class_not_registered(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_class_not_registered, message, sourceInformation) {} + hresult_class_not_registered(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_class_not_registered, take_ownership_from_abi, sourceInformation) {} }; struct hresult_changed_state : hresult_error { - hresult_changed_state(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_changed_state WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_changed_state(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_changed_state, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_changed_state(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_changed_state, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_changed_state(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_changed_state, sourceInformation) {} + hresult_changed_state(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_changed_state, message, sourceInformation) {} + hresult_changed_state(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_changed_state, take_ownership_from_abi, sourceInformation) {} }; struct hresult_illegal_method_call : hresult_error { - hresult_illegal_method_call(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_illegal_method_call WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_illegal_method_call(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_illegal_method_call, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_illegal_method_call(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_illegal_method_call, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_illegal_method_call(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_method_call, sourceInformation) {} + hresult_illegal_method_call(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_method_call, message, sourceInformation) {} + hresult_illegal_method_call(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_method_call, take_ownership_from_abi, sourceInformation) {} }; struct hresult_illegal_state_change : hresult_error { - hresult_illegal_state_change(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_illegal_state_change WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_illegal_state_change(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_illegal_state_change, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_illegal_state_change(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_illegal_state_change, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_illegal_state_change(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_state_change, sourceInformation) {} + hresult_illegal_state_change(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_state_change, message, sourceInformation) {} + hresult_illegal_state_change(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_state_change, take_ownership_from_abi, sourceInformation) {} }; struct hresult_illegal_delegate_assignment : hresult_error { - hresult_illegal_delegate_assignment(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_illegal_delegate_assignment WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_illegal_delegate_assignment(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_illegal_delegate_assignment, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_illegal_delegate_assignment(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_illegal_delegate_assignment, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_illegal_delegate_assignment(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_delegate_assignment, sourceInformation) {} + hresult_illegal_delegate_assignment(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_delegate_assignment, message, sourceInformation) {} + hresult_illegal_delegate_assignment(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_illegal_delegate_assignment, take_ownership_from_abi, sourceInformation) {} }; struct hresult_canceled : hresult_error { - hresult_canceled(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) noexcept : hresult_error(impl::error_canceled WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_canceled(param::hstring const& message WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_canceled, message WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} - hresult_canceled(take_ownership_from_abi_t WINRT_IMPL_SOURCE_LOCATION_ARGS) noexcept : hresult_error(impl::error_canceled, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD) {} + hresult_canceled(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_canceled, sourceInformation) {} + hresult_canceled(param::hstring const& message, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_canceled, message, sourceInformation) {} + hresult_canceled(take_ownership_from_abi_t, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) noexcept : hresult_error(impl::error_canceled, take_ownership_from_abi, sourceInformation) {} }; - [[noreturn]] inline WINRT_IMPL_NOINLINE void throw_hresult(hresult const result WINRT_IMPL_SOURCE_LOCATION_ARGS) + [[noreturn]] inline WINRT_IMPL_NOINLINE void throw_hresult(hresult const result, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (winrt_throw_hresult_handler) { -#ifdef WINRT_SOURCE_LOCATION_ACTIVE winrt_throw_hresult_handler(sourceInformation.line(), sourceInformation.file_name(), sourceInformation.function_name(), WINRT_IMPL_RETURNADDRESS(), result); -#else - winrt_throw_hresult_handler(0, nullptr, nullptr, WINRT_IMPL_RETURNADDRESS(), result); -#endif } if (result == impl::error_bad_alloc) @@ -351,70 +343,70 @@ WINRT_EXPORT namespace winrt if (result == impl::error_access_denied) { - throw hresult_access_denied(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_access_denied(take_ownership_from_abi, sourceInformation); } if (result == impl::error_wrong_thread) { - throw hresult_wrong_thread(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_wrong_thread(take_ownership_from_abi, sourceInformation); } if (result == impl::error_not_implemented) { - throw hresult_not_implemented(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_not_implemented(take_ownership_from_abi, sourceInformation); } if (result == impl::error_invalid_argument) { - throw hresult_invalid_argument(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_invalid_argument(take_ownership_from_abi, sourceInformation); } if (result == impl::error_out_of_bounds) { - throw hresult_out_of_bounds(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_out_of_bounds(take_ownership_from_abi, sourceInformation); } if (result == impl::error_no_interface) { - throw hresult_no_interface(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_no_interface(take_ownership_from_abi, sourceInformation); } if (result == impl::error_class_not_available) { - throw hresult_class_not_available(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_class_not_available(take_ownership_from_abi, sourceInformation); } if (result == impl::error_class_not_registered) { - throw hresult_class_not_registered(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_class_not_registered(take_ownership_from_abi, sourceInformation); } if (result == impl::error_changed_state) { - throw hresult_changed_state(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_changed_state(take_ownership_from_abi, sourceInformation); } if (result == impl::error_illegal_method_call) { - throw hresult_illegal_method_call(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_illegal_method_call(take_ownership_from_abi, sourceInformation); } if (result == impl::error_illegal_state_change) { - throw hresult_illegal_state_change(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_illegal_state_change(take_ownership_from_abi, sourceInformation); } if (result == impl::error_illegal_delegate_assignment) { - throw hresult_illegal_delegate_assignment(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_illegal_delegate_assignment(take_ownership_from_abi, sourceInformation); } if (result == impl::error_canceled) { - throw hresult_canceled(take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_canceled(take_ownership_from_abi, sourceInformation); } - throw hresult_error(result, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_error(result, take_ownership_from_abi, sourceInformation); } inline WINRT_IMPL_NOINLINE hresult to_hresult() noexcept @@ -475,55 +467,55 @@ WINRT_EXPORT namespace winrt } } - [[noreturn]] inline void throw_last_error(WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM) + [[noreturn]] inline void throw_last_error(winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { - throw_hresult(impl::hresult_from_win32(WINRT_IMPL_GetLastError()) WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw_hresult(impl::hresult_from_win32(WINRT_IMPL_GetLastError()), sourceInformation); } - inline hresult check_hresult(hresult const result WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT) + inline hresult check_hresult(hresult const result, winrt::impl::slim_source_location const& sourceInformation) { if (result < 0) { - throw_hresult(result WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw_hresult(result, sourceInformation); } return result; } template - void check_nt(T result WINRT_IMPL_SOURCE_LOCATION_ARGS) + void check_nt(T result, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (result != 0) { - throw_hresult(impl::hresult_from_nt(result) WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw_hresult(impl::hresult_from_nt(result), sourceInformation); } } template - void check_win32(T result WINRT_IMPL_SOURCE_LOCATION_ARGS) + void check_win32(T result, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (result != 0) { - throw_hresult(impl::hresult_from_win32(result) WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw_hresult(impl::hresult_from_win32(result), sourceInformation); } } template - T check_bool(T result WINRT_IMPL_SOURCE_LOCATION_ARGS) + T check_bool(T result, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (!result) { - winrt::throw_last_error(WINRT_IMPL_SOURCE_LOCATION_FORWARD_SINGLE_PARAM); + winrt::throw_last_error(sourceInformation); } return result; } template - T* check_pointer(T* pointer WINRT_IMPL_SOURCE_LOCATION_ARGS) + T* check_pointer(T* pointer, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (!pointer) { - throw_last_error(WINRT_IMPL_SOURCE_LOCATION_FORWARD_SINGLE_PARAM); + throw_last_error(sourceInformation); } return pointer; @@ -538,17 +530,17 @@ WINRT_EXPORT namespace winrt namespace winrt::impl { - inline hresult check_hresult_allow_bounds(hresult const result WINRT_IMPL_SOURCE_LOCATION_ARGS) + inline hresult check_hresult_allow_bounds(hresult const result, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (result != impl::error_out_of_bounds && result != impl::error_fail && result != impl::error_file_not_found) { - check_hresult(result WINRT_IMPL_SOURCE_LOCATION_FORWARD); + check_hresult(result, sourceInformation); } return result; } template - WINRT_IMPL_NOINLINE void check_cast_result(T* from WINRT_IMPL_SOURCE_LOCATION_ARGS) + WINRT_IMPL_NOINLINE void check_cast_result(T* from, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()) { if (!from) { @@ -563,7 +555,7 @@ namespace winrt::impl impl::bstr_handle capabilitySid; if (restrictedError->GetErrorDetails(description.put(), &code, restrictedDescription.put(), capabilitySid.put()) == 0) { - throw hresult_error(code, take_ownership_from_abi WINRT_IMPL_SOURCE_LOCATION_FORWARD); + throw hresult_error(code, take_ownership_from_abi, sourceInformation); } } } diff --git a/strings/base_macros.h b/strings/base_macros.h index e0167d15..d9e19547 100644 --- a/strings/base_macros.h +++ b/strings/base_macros.h @@ -77,14 +77,56 @@ struct IUnknown; typedef struct _GUID GUID; #endif -// std::source_location is a C++20 feature, which is above the C++17 feature floor for cppwinrt. The source location needs -// to be the calling code, not cppwinrt itself, so that it is useful to developers building on top of this library. As a -// result any public-facing method that can result in an error needs a default-constructed source_location argument. Because -// this type does not exist in C++17 we need to use a macro to optionally add parameters and forwarding wherever appropriate. +#if defined(__cpp_consteval) +#define WINRT_IMPL_CONSTEVAL consteval +#else +#define WINRT_IMPL_CONSTEVAL constexpr +#endif + +// The intrinsics (such as __builtin_FILE()) that power std::source_location are also used to power winrt:impl::slim_source_location. +// The source location needs to be for the calling code, not cppwinrt itself, so that it is useful to developers building on top of +// this library. As a result any public-facing method that can result in an error needs a default-constructed slim_source_location +// argument so that it will collect source information from the application code that is calling into cppwinrt. // -// Some projects may decide to disable std::source_location support to prevent source code information from ending up in their -// release binaries, or to reduce binary size. Defining WINRT_NO_SOURCE_LOCATION will prevent this feature from activating. -#if defined(__cpp_lib_source_location) && !defined(WINRT_NO_SOURCE_LOCATION) +// We do not directly use std::source_location for two reasons: +// 1) std::source_location::function_name() is unavoidable. These strings end up in the final binary, bloating their size. This +// is particularly impactful for code bases that use templates heavily. Cases of 50% binary size growth have been observed. +// 2) std::source_location is a cpp20 feature, which is above the cpp17 feature floor for cppwinrt. By defining our own version +// we can avoid ODR violations in mixed cpp17/cpp20 builds. cpp17 callers will have an ABI that matches cpp20 callers (they +// will just not have useful file/line/function information). +// +// Some projects may decide that the source information binary size impact is not worth the benefit. Defining WINRT_NO_SOURCE_LOCATION +// will prevent this feature from activating. The slim_source_location type will be forwarded around but it will not include any +// nonzero data. That eliminates the biggest source of binary size overhead. +// +// To help with debugging the __builtin_FUNCTION() intrinsic will be used in _DEBUG builds. This will provide a bit more diagnostic +// value at the cost of binary size. The assumption is that binary size is considered less important in debug builds so this tradeoff +// is acceptable. +// +// The different behavior of the default parameters to winrt::impl::slim_source_location::current() is technically an ODR violation, +// albeit a minor one. There should be no serious consequence to this violation. In practice it means that mixing cpp17/cpp20, +// or mixing WINRT_NO_SOURCE_LOCATION with undefining it, will lead to inconsistent source location information. It may be missing +// when it is expected to be included, or it may be present when it is not expected. The behavior will depend on the linker's choice +// when there are multiple translation units with different options. This violation is tracked by https://github.com/microsoft/cppwinrt/issues/1445. + +#if !defined(__cpp_lib_source_location) || defined(WINRT_NO_SOURCE_LOCATION) +// Case1: cpp17 mode. The source_location intrinsics are not available. +// Case2: The caller has disabled source_location support. Ensure that there is no binary size overhead for line/file/function. +#define WINRT_IMPL_BUILTIN_LINE 0 +#define WINRT_IMPL_BUILTIN_FILE nullptr +#define WINRT_IMPL_BUILTIN_FUNCTION nullptr +#elif _DEBUG +// cpp20 _DEBUG builds include function information, which has a heavy binary size impact, in addition to file/line. +#define WINRT_IMPL_BUILTIN_LINE __builtin_LINE() +#define WINRT_IMPL_BUILTIN_FILE __builtin_FILE() +#define WINRT_IMPL_BUILTIN_FUNCTION __builtin_FUNCTION() +#else +// Release builds in cpp20 mode get file and line information but NOT function information. Function strings +// quickly add up to a substantial binary size impact, especially when templates are heavily used. +#define WINRT_IMPL_BUILTIN_LINE __builtin_LINE() +#define WINRT_IMPL_BUILTIN_FILE __builtin_FILE() +#define WINRT_IMPL_BUILTIN_FUNCTION nullptr +#endif namespace winrt::impl { @@ -93,19 +135,23 @@ namespace winrt::impl // have heavy binary size overhead when templates cause many permutations to exist. struct slim_source_location { - [[nodiscard]] static consteval slim_source_location current( - const std::uint_least32_t line = __builtin_LINE(), - const char* const file = __builtin_FILE()) noexcept + [[nodiscard]] static WINRT_IMPL_CONSTEVAL slim_source_location current( + const std::uint_least32_t line = WINRT_IMPL_BUILTIN_LINE, + const char* const file = WINRT_IMPL_BUILTIN_FILE, + const char* const function = WINRT_IMPL_BUILTIN_FUNCTION) noexcept { - return slim_source_location{ line, file }; + return slim_source_location{ line, file, function }; } [[nodiscard]] constexpr slim_source_location() noexcept = default; - [[nodiscard]] constexpr slim_source_location(const std::uint_least32_t line, - const char* const file) noexcept : + [[nodiscard]] constexpr slim_source_location( + const std::uint_least32_t line, + const char* const file, + const char* const function) noexcept : m_line(line), - m_file(file) + m_file(file), + m_function(function) {} [[nodiscard]] constexpr std::uint_least32_t line() const noexcept @@ -118,63 +164,18 @@ namespace winrt::impl return m_file; } - constexpr const char* function_name() const noexcept + [[nodiscard]] constexpr const char* function_name() const noexcept { - // This is intentionally not included. See comment above. - return nullptr; + return m_function; } private: const std::uint_least32_t m_line{}; const char* const m_file{}; + const char* const m_function{}; }; } -// std::source_location includes function_name which can be helpful but creates a lot of binary size impact. Many consumers -// have defined WINRT_NO_SOURCE_LOCATION to prevent this impact, losing the value of source_location. We have defined a -// slim_source_location struct that is equivalent but excludes function_name. This should have the vast majority of the -// usefulness of source_location while having a much smaller binary impact. -// -// When building _DEBUG binary size is not usually much of a concern, so we can use the full source_location type. -#ifdef _DEBUG -#define WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT , std::source_location const& sourceInformation -#define WINRT_IMPL_SOURCE_LOCATION_ARGS , std::source_location const& sourceInformation = std::source_location::current() -#define WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM std::source_location const& sourceInformation = std::source_location::current() - -#define WINRT_IMPL_SOURCE_LOCATION_FORWARD , sourceInformation -#define WINRT_IMPL_SOURCE_LOCATION_FORWARD_SINGLE_PARAM sourceInformation - -#define WINRT_SOURCE_LOCATION_ACTIVE - -#ifdef _MSC_VER -#pragma detect_mismatch("WINRT_SOURCE_LOCATION", "true") -#endif // _MSC_VER - -#else // !_DEBUG -#define WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT , winrt::impl::slim_source_location const& sourceInformation -#define WINRT_IMPL_SOURCE_LOCATION_ARGS , winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current() -#define WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current() - -#define WINRT_IMPL_SOURCE_LOCATION_FORWARD , sourceInformation -#define WINRT_IMPL_SOURCE_LOCATION_FORWARD_SINGLE_PARAM sourceInformation - -#define WINRT_SOURCE_LOCATION_ACTIVE - #ifdef _MSC_VER #pragma detect_mismatch("WINRT_SOURCE_LOCATION", "slim") #endif // _MSC_VER - -#endif // _DEBUG - -#else -#define WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT -#define WINRT_IMPL_SOURCE_LOCATION_ARGS -#define WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM - -#define WINRT_IMPL_SOURCE_LOCATION_FORWARD -#define WINRT_IMPL_SOURCE_LOCATION_FORWARD_SINGLE_PARAM - -#ifdef _MSC_VER -#pragma detect_mismatch("WINRT_SOURCE_LOCATION", "false") -#endif // _MSC_VER -#endif // defined(__cpp_lib_source_location) && !defined(WINRT_NO_SOURCE_LOCATION) diff --git a/strings/base_meta.h b/strings/base_meta.h index 2c1796e9..25deb42e 100644 --- a/strings/base_meta.h +++ b/strings/base_meta.h @@ -1,7 +1,7 @@ WINRT_EXPORT namespace winrt { - hresult check_hresult(hresult const result WINRT_IMPL_SOURCE_LOCATION_ARGS); + hresult check_hresult(hresult const result, winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()); hresult to_hresult() noexcept; template