diff --git a/Utilities/BitField.h b/Utilities/BitField.h index faa5a2a45a..32785e5e7e 100644 --- a/Utilities/BitField.h +++ b/Utilities/BitField.h @@ -8,7 +8,7 @@ #pragma GCC diagnostic ignored "-Weffc++" #endif -template +template struct bf_base { using type = T; @@ -35,7 +35,7 @@ protected: }; // Bitfield accessor (N bits from I position, 0 is LSB) -template +template struct bf_t : bf_base { using type = typename bf_t::type; @@ -156,8 +156,17 @@ struct bf_t : bf_base } }; +template +struct std::common_type, bf_t> : std::common_type {}; + +template +struct std::common_type, T2> : std::common_type> {}; + +template +struct std::common_type> : std::common_type, T2> {}; + // Field pack (concatenated from left to right) -template +template struct cf_t : bf_base::bitsize> { using type = typename cf_t::type; @@ -198,7 +207,7 @@ struct cf_t : bf_base::bitsize> }; // Empty field pack (recursion terminator) -template<> +template <> struct cf_t { static constexpr uint bitsize = 0; @@ -208,13 +217,13 @@ struct cf_t return 0; } - template + template static constexpr auto extract(const T&) -> decltype(+T()) { return 0; } - template + template static constexpr T insert(T /*value*/) { return 0; @@ -222,7 +231,7 @@ struct cf_t }; // Fixed field (provides constant values in field pack) -template +template struct ff_t : bf_base { using type = typename ff_t::type; @@ -246,7 +255,7 @@ struct ff_t : bf_base #pragma GCC diagnostic pop #endif -template +template struct fmt_unveil, void> { using type = typename fmt_unveil>::type; @@ -257,7 +266,7 @@ struct fmt_unveil, void> } }; -template +template struct fmt_unveil, void> { using type = typename fmt_unveil>::type; @@ -268,7 +277,7 @@ struct fmt_unveil, void> } }; -template +template struct fmt_unveil, void> { using type = typename fmt_unveil>::type; diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 2713ef75ba..85e6c1cddf 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -1163,12 +1163,12 @@ void fs::sync() #endif } -[[noreturn]] void fs::xnull(const src_loc& loc) +[[noreturn]] void fs::xnull(std::source_location loc) { fmt::throw_exception("Null object.%s", loc); } -[[noreturn]] void fs::xfail(const src_loc& loc) +[[noreturn]] void fs::xfail(std::source_location loc) { fmt::throw_exception("Unexpected fs::error %s%s", g_tls_error, loc); } diff --git a/Utilities/File.h b/Utilities/File.h index a2b21a5ff9..c95bcbfc02 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -166,8 +166,8 @@ namespace fs virtual std::unique_ptr open_dir(const std::string& path) = 0; }; - [[noreturn]] void xnull(const src_loc&); - [[noreturn]] void xfail(const src_loc&); + [[noreturn]] void xnull(std::source_location); + [[noreturn]] void xfail(std::source_location); [[noreturn]] void xovfl(); constexpr struct pod_tag_t{} pod_tag; @@ -281,35 +281,23 @@ namespace fs } // Change file size (possibly appending zero bytes) - bool trunc(u64 length, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + bool trunc(u64 length, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->trunc(length); } // Get file information - stat_t get_stat( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + stat_t get_stat(std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->get_stat(); } // Sync file buffers - void sync( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + void sync(std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->sync(); } @@ -317,117 +305,76 @@ namespace fs bool strict_read_check(u64 offset, u64 size, u64 type_size) const; // Read the data from the file and return the amount of data written in buffer - u64 read(void* buffer, u64 count, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 read(void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->read(buffer, count); } // Read the data from the file at specified offset in thread-safe manner - u64 read_at(u64 offset, void* buffer, u64 count, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 read_at(u64 offset, void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->read_at(offset, buffer, count); } // Write the data to the file and return the amount of data actually written - u64 write(const void* buffer, u64 count, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 write(const void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->write(buffer, count); } // Change current position, returns resulting position - u64 seek(s64 offset, seek_mode whence = seek_set, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 seek(s64 offset, seek_mode whence = seek_set, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->seek(offset, whence); } // Get file size - u64 size( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 size(std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->size(); } // Get current position - u64 pos( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 pos(std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->seek(0, seek_cur); } // Write std::basic_string unconditionally template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - const file& write(const std::basic_string& str, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + const file& write(const std::basic_string& str, std::source_location src_loc = std::source_location::current()) const { - if (write(str.data(), str.size() * sizeof(T), line, col, file, func) != str.size() * sizeof(T)) xfail({line, col, file, func}); + if (write(str.data(), str.size() * sizeof(T), src_loc) != str.size() * sizeof(T)) xfail(src_loc); return *this; } // Write POD unconditionally template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - const file& write(const T& data, - pod_tag_t = pod_tag, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + const file& write(const T& data, std::source_location src_loc = std::source_location::current()) const { - if (write(std::addressof(data), sizeof(T), line, col, file, func) != sizeof(T)) xfail({line, col, file, func}); + if (write(std::addressof(data), sizeof(T), src_loc) != sizeof(T)) xfail(src_loc); return *this; } // Write POD std::vector unconditionally template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - const file& write(const std::vector& vec, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + const file& write(const std::vector& vec, std::source_location src_loc = std::source_location::current()) const { - if (write(vec.data(), vec.size() * sizeof(T), line, col, file, func) != vec.size() * sizeof(T)) xfail({line, col, file, func}); + if (write(vec.data(), vec.size() * sizeof(T), src_loc) != vec.size() * sizeof(T)) xfail(src_loc); return *this; } // Read std::basic_string template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - bool read(std::basic_string& str, usz _size = umax, - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION(), - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN()) const + bool read(std::basic_string& str, usz _size = umax, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); if (_size != umax) { @@ -440,30 +387,22 @@ namespace fs str.resize(_size); } - return read(str.data(), sizeof(T) * str.size(), line, col, file, func) == sizeof(T) * str.size(); + return read(str.data(), sizeof(T) * str.size(), src_loc) == sizeof(T) * str.size(); } // Read POD, sizeof(T) is used template requires (std::is_trivially_copyable_v && !std::is_pointer_v) bool read(T& data, - pod_tag_t = pod_tag, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + pod_tag_t = pod_tag, std::source_location src_loc = std::source_location::current()) const { - return read(std::addressof(data), sizeof(T), line, col, file, func) == sizeof(T); + return read(std::addressof(data), sizeof(T), src_loc) == sizeof(T); } // Read POD std::vector template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - bool read(std::vector& vec, usz _size = umax, bool use_offs = false, usz offset = umax, - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION(), - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN()) const + bool read(std::vector& vec, usz _size = umax, bool use_offs = false, usz offset = umax, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); if (_size != umax) { @@ -478,52 +417,39 @@ namespace fs if (use_offs) { - return read_at(offset, vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size(); + return read_at(offset, vec.data(), sizeof(T) * vec.size(), src_loc) == sizeof(T) * vec.size(); } - return read(vec.data(), sizeof(T) * vec.size(), line, col, file, func) == sizeof(T) * vec.size(); + return read(vec.data(), sizeof(T) * vec.size(), src_loc) == sizeof(T) * vec.size(); } // Read POD (experimental) template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - T read( - pod_tag_t = pod_tag, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + T read(pod_tag_t = pod_tag, std::source_location src_loc = std::source_location::current()) const { T result; - if (!read(result, pod_tag, line, col, file, func)) xfail({line, col, file, func}); + if (!read(result, pod_tag, src_loc)) xfail(src_loc); return result; } // Read full file to std::basic_string template - std::basic_string to_string( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + std::basic_string to_string(std::source_location src_loc = std::source_location::current()) const { std::basic_string result; result.resize(size() / sizeof(T)); seek(0); - if (!read(result, result.size(), file, func, line, col)) xfail({line, col, file, func}); + if (!read(result, result.size(), src_loc)) xfail(src_loc); return result; } // Read full file to std::vector template requires (std::is_trivially_copyable_v && !std::is_pointer_v) - std::vector to_vector( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + std::vector to_vector(std::source_location src_loc = std::source_location::current()) const { std::vector result; result.resize(size() / sizeof(T)); - if (!read(result, result.size(), true, 0, file, func, line, col)) xfail({line, col, file, func}); + if (!read(result, result.size(), true, 0, src_loc)) xfail(src_loc); return result; } @@ -534,13 +460,9 @@ namespace fs file_id get_id() const; // Gathered write - u64 write_gather(const iovec_clone* buffers, u64 buf_count, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + u64 write_gather(const iovec_clone* buffers, u64 buf_count, std::source_location src_loc = std::source_location::current()) const { - if (!m_file) xnull({line, col, file, func}); + if (!m_file) xnull(src_loc); return m_file->write_gather(buffers, buf_count); } }; @@ -584,24 +506,16 @@ namespace fs } // Get next directory entry - bool read(dir_entry& out, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + bool read(dir_entry& out, std::source_location src_loc = std::source_location::current()) const { - if (!m_dir) xnull({line, col, file, func}); + if (!m_dir) xnull(src_loc); return m_dir->read(out); } // Reset to the beginning - void rewind( - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + void rewind(std::source_location src_loc = std::source_location::current()) const { - if (!m_dir) xnull({line, col, file, func}); + if (!m_dir) xnull(src_loc); return m_dir->rewind(); } diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 8a4f6480b9..34e75b4311 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -414,22 +414,35 @@ void fmt_class_string::format(std::string& out, u64 arg) } template <> -void fmt_class_string::format(std::string& out, u64 arg) +void fmt_class_string::format(std::string& out, u64 arg) { - const src_loc& loc = get_object(arg); + const std::source_location& loc = get_object(arg); - if (loc.col != umax) + auto is_valid = [](auto num) { - fmt::append(out, "\n(in file %s:%u[:%u]", loc.file, loc.line, loc.col); + return num && num != umax; + }; + + const bool has_line = is_valid(loc.line()); + + if (has_line && is_valid(loc.column())) + { + fmt::append(out, "\n(in file %s:%u[:%u]", loc.file_name(), loc.line(), loc.column()); } + else if (has_line) + { + fmt::append(out, "\n(in file %s:%u", loc.file_name(), loc.line()); + } + // Let's not care about such useless corner cases + // else if (is_valid(loc.column()) else { - fmt::append(out, "\n(in file %s:%u", loc.file, loc.line); + fmt::append(out, "\n(in file %s", loc.file_name()); } - if (loc.func && *loc.func) + if (auto func = loc.function_name(); func && func[0]) { - fmt::append(out, ", in function %s)", loc.func); + fmt::append(out, ", in function %s)", func); } else { @@ -452,14 +465,14 @@ void fmt_class_string::format(std::string& out, u64 arg) namespace fmt { - [[noreturn]] void raw_verify_error(const src_loc& loc, const char8_t* msg) + [[noreturn]] void raw_verify_error(std::source_location loc, const char8_t* msg) { std::string out; fmt::append(out, "%s%s", msg ? msg : u8"Verification failed", loc); thread_ctrl::emergency_exit(out); } - [[noreturn]] void raw_throw_exception(const src_loc& loc, const char* fmt, const fmt_type_info* sup, const u64* args) + [[noreturn]] void raw_throw_exception(std::source_location loc, const char* fmt, const fmt_type_info* sup, const u64* args) { std::string out; raw_append(out, fmt, sup, args); diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index 590df9f767..0388e921f8 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -357,7 +357,7 @@ namespace fmt } // Internal exception message formatting template, must be explicitly specialized or instantiated in cpp to minimize code bloat - [[noreturn]] void raw_throw_exception(const src_loc&, const char*, const fmt_type_info*, const u64*); + [[noreturn]] void raw_throw_exception(std::source_location, const char*, const fmt_type_info*, const u64*); // Throw exception with formatting template @@ -366,13 +366,9 @@ namespace fmt struct args_break_t {}; [[noreturn]] FORCE_INLINE SAFE_BUFFERS() throw_exception(const CharT(&fmt)[N], const Args&... args, - args_break_t = args_break_t{}, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) + args_break_t = args_break_t{}, std::source_location src_loc = std::source_location::current()) { - raw_throw_exception({line, col, file, func}, reinterpret_cast(fmt), type_info_v, fmt_args_t{fmt_unveil::get(args)...}); + raw_throw_exception(src_loc, reinterpret_cast(fmt), type_info_v, fmt_args_t{fmt_unveil::get(args)...}); } #ifndef _MSC_VER @@ -427,11 +423,7 @@ namespace fmt // Ensure with formatting template - decltype(auto) ensure(T&& arg, const CharT(&fmt)[N], tie args, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) noexcept + decltype(auto) ensure(T&& arg, const CharT(&fmt)[N], tie args, std::source_location src_loc = std::source_location::current()) noexcept { if (std::forward(arg)) [[likely]] { @@ -442,6 +434,6 @@ namespace fmt u64 data[sizeof...(Args) + 1]; args.init(data); - raw_throw_exception({line, col, file, func}, reinterpret_cast(fmt), type_info_v...>, +data); + raw_throw_exception(src_loc, reinterpret_cast(fmt), type_info_v...>, +data); } } diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index c1515c65c1..afb1fa82aa 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -151,11 +151,7 @@ struct ppu_module } template - to_be_t& get_ref(u32 addr, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + to_be_t& get_ref(u32 addr, std::source_location src_loc = std::source_location::current()) const { constexpr usz size_element = std::is_void_v ? 0 : sizeof(std::conditional_t, char, T>); if (auto ptr = get_ptr(addr, u32{size_element})) @@ -163,16 +159,12 @@ struct ppu_module return *ptr; } - fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc{line, col, file, func}); + fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc); return *std::add_pointer_t>{}; } template requires requires (const U& obj) { obj.get_ptr(); } - to_be_t& get_ref(U&& addr, u32 index = 0, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) const + to_be_t& get_ref(U&& addr, u32 index = 0, std::source_location src_loc = std::source_location::current()) const { constexpr usz size_element = std::is_void_v ? 0 : sizeof(std::conditional_t, char, T>); if (auto ptr = get_ptr((addr + index).addr(), u32{size_element})) @@ -180,7 +172,7 @@ struct ppu_module return *ptr; } - fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", (addr + index).addr(), src_loc{line, col, file, func}); + fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", (addr + index).addr(), src_loc); return *std::add_pointer_t>{}; } }; diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 2c97a3f8be..10bc33fe4f 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -6589,7 +6589,7 @@ spu_thread::spu_prio_t spu_thread::priority_t::load() const if (_this->get_type() != spu_type::threaded || !_this->group->has_scheduler_context) { spu_thread::spu_prio_t prio{}; - prio.prio = smax; + prio.prio = s32{smax}; return prio; } diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index dbdeff9ae2..05c5d59623 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -220,13 +220,9 @@ namespace vm } template requires (std::is_integral_v && (sizeof(+T{}) > 4 || std::is_signed_v)) - vm::addr_t cast(const T& addr, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) + vm::addr_t cast(const T& addr, std::source_location src_loc = std::source_location::current()) { - return vm::addr_t{::narrow(+addr, line, col, file, func)}; + return vm::addr_t{::narrow(+addr, src_loc)}; } template requires (std::is_integral_v && (sizeof(+T{}) <= 4 && !std::is_signed_v)) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index b7b4e23dba..9fcd793266 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -132,7 +132,7 @@ namespace rsx { } - u32 get_address(u32 offset, u32 location, u32 size_to_check, u32 line, u32 col, const char* file, const char* func) + u32 get_address(u32 offset, u32 location, u32 size_to_check, std::source_location src_loc) { const auto render = get_current_renderer(); std::string_view msg; @@ -249,11 +249,11 @@ namespace rsx { // Allow failure if specified size // This is to allow accurate recovery for failures - rsx_log.warning("rsx::get_address(offset=0x%x, location=0x%x, size=0x%x): %s%s", offset, location, size_to_check, msg, src_loc{line, col, file, func}); + rsx_log.warning("rsx::get_address(offset=0x%x, location=0x%x, size=0x%x): %s%s", offset, location, size_to_check, msg, src_loc); return 0; } - fmt::throw_exception("rsx::get_address(offset=0x%x, location=0x%x): %s%s", offset, location, msg, src_loc{line, col, file, func}); + fmt::throw_exception("rsx::get_address(offset=0x%x, location=0x%x): %s%s", offset, location, msg, src_loc); } extern void set_rsx_yield_flag() noexcept @@ -3276,7 +3276,7 @@ namespace rsx return pair; } - void thread::recover_fifo(u32 line, u32 col, const char* file, const char* func) + void thread::recover_fifo(std::source_location src_loc) { bool kill_itself = g_cfg.core.rsx_fifo_accuracy == rsx_fifo_mode::as_ps3; @@ -3301,7 +3301,7 @@ namespace rsx if (kill_itself) { fmt::throw_exception("Dead FIFO commands queue state has been detected!" - "\nTry increasing \"Driver Wake-Up Delay\" setting or setting \"RSX FIFO Accuracy\" to \"%s\", both in Advanced settings. Called from %s", std::min(rsx_fifo_mode{static_cast(g_cfg.core.rsx_fifo_accuracy.get()) + 1}, rsx_fifo_mode::atomic_ordered), src_loc{line, col, file, func}); + "\nTry increasing \"Driver Wake-Up Delay\" setting or setting \"RSX FIFO Accuracy\" to \"%s\", both in Advanced settings. Called from %s", std::min(rsx_fifo_mode{static_cast(g_cfg.core.rsx_fifo_accuracy.get()) + 1}, rsx_fifo_mode::atomic_ordered), src_loc); } // Error. Should reset the queue diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 70db28453e..b386236a29 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -123,11 +123,7 @@ namespace rsx u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size); - u32 get_address(u32 offset, u32 location, u32 size_to_check = 0, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()); + u32 get_address(u32 offset, u32 location, u32 size_to_check = 0, std::source_location src_loc = std::source_location::current()); struct backend_configuration { @@ -226,10 +222,7 @@ namespace rsx // Returns [count of found commands, PC of their start] std::pair try_get_pc_of_x_cmds_backwards(s32 count, u32 get) const; - void recover_fifo(u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()); + void recover_fifo(std::source_location src_loc = std::source_location::current()); static void fifo_wake_delay(u64 div = 1); u32 get_fifo_cmd() const; diff --git a/rpcs3/Emu/RSX/VK/vkutils/shared.cpp b/rpcs3/Emu/RSX/VK/vkutils/shared.cpp index e524c62983..9f2d315305 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/shared.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/shared.cpp @@ -9,11 +9,7 @@ namespace vk { extern void print_debug_markers(); - void die_with_error(VkResult error_code, std::string message, - const char* file, - const char* func, - u32 line, - u32 col) + void die_with_error(VkResult error_code, std::string message, std::source_location src_loc) { std::string error_message; int severity = 0; // 0 - die, 1 - warn, 2 - nothing @@ -100,7 +96,7 @@ namespace vk error_message = "Descriptor pool creation failed (VK_ERROR_FRAGMENTATION)"; break; default: - error_message = fmt::format("Unknown Code (%Xh, %d)%s", static_cast(error_code), static_cast(error_code), src_loc{line, col, file, func}); + error_message = fmt::format("Unknown Code (%Xh, %d)%s", static_cast(error_code), static_cast(error_code), src_loc); break; } @@ -111,9 +107,9 @@ namespace vk print_debug_markers(); if (!message.empty()) message += "\n\n"; - fmt::throw_exception("%sAssertion Failed! Vulkan API call failed with unrecoverable error: %s%s", message, error_message, src_loc{line, col, file, func}); + fmt::throw_exception("%sAssertion Failed! Vulkan API call failed with unrecoverable error: %s%s", message, error_message, src_loc); case 1: - rsx_log.error("Vulkan API call has failed with an error but will continue: %s%s", error_message, src_loc{line, col, file, func}); + rsx_log.error("Vulkan API call has failed with an error but will continue: %s%s", error_message, src_loc); break; case 2: break; diff --git a/rpcs3/Emu/RSX/VK/vkutils/shared.h b/rpcs3/Emu/RSX/VK/vkutils/shared.h index 1400d10b16..f8ffcc103a 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/shared.h +++ b/rpcs3/Emu/RSX/VK/vkutils/shared.h @@ -8,11 +8,7 @@ namespace vk #define CHECK_RESULT(expr) { VkResult _res = (expr); if (_res != VK_SUCCESS) vk::die_with_error(_res); } #define CHECK_RESULT_EX(expr, msg) { VkResult _res = (expr); if (_res != VK_SUCCESS) vk::die_with_error(_res, msg); } - void die_with_error(VkResult error_code, std::string message = {}, - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION(), - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN()); + void die_with_error(VkResult error_code, std::string message = {}, std::source_location src_loc = std::source_location::current()); VKAPI_ATTR VkBool32 VKAPI_CALL dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType, u64 srcObject, usz location, s32 msgCode, diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index fc4e2be384..c54860f3d0 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -162,9 +162,9 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -void Emulator::CallFromMainThread(std::function&& func, atomic_t* wake_up, bool track_emu_state, u64 stop_ctr, u32 line, u32 col, const char* file, const char* fun) const +void Emulator::CallFromMainThread(std::function&& func, atomic_t* wake_up, bool track_emu_state, u64 stop_ctr, std::source_location src_loc) const { - std::function final_func = [this, before = IsStopped(), track_emu_state, thread_name = thread_ctrl::get_name(), src = src_loc{line, col, file, fun} + std::function final_func = [this, before = IsStopped(), track_emu_state, thread_name = thread_ctrl::get_name(), src = src_loc , count = (stop_ctr == umax ? +m_stop_ctr : stop_ctr), func = std::move(func)] { const bool call_it = (!track_emu_state || (count == m_stop_ctr && before == IsStopped())); @@ -180,19 +180,19 @@ void Emulator::CallFromMainThread(std::function&& func, atomic_t* w m_cb.call_from_main_thread(std::move(final_func), wake_up); } -void Emulator::BlockingCallFromMainThread(std::function&& func, u32 line, u32 col, const char* file, const char* fun) const +void Emulator::BlockingCallFromMainThread(std::function&& func, std::source_location src_loc) const { atomic_t wake_up = 0; - sys_log.trace("Blocking Callback from thread '%s' at [%s] is queued", thread_ctrl::get_name(), src_loc{line, col, file, fun}); + sys_log.trace("Blocking Callback from thread '%s' at [%s] is queued", thread_ctrl::get_name(), src_loc); - CallFromMainThread(std::move(func), &wake_up, true, umax, line, col, file, fun); + CallFromMainThread(std::move(func), &wake_up, true, umax, src_loc); while (!wake_up) { if (!thread_ctrl::get_current()) { - fmt::throw_exception("Calling thread of BlockingCallFromMainThread is not of named_thread<>, calling from %s", src_loc{line, col, file, fun}); + fmt::throw_exception("Calling thread of BlockingCallFromMainThread is not of named_thread<>, calling from %s", src_loc); } wake_up.wait(0); diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 27292c8f98..1600c56d67 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -191,17 +191,10 @@ public: // Call from the GUI thread void CallFromMainThread(std::function&& func, atomic_t* wake_up = nullptr, bool track_emu_state = true, u64 stop_ctr = umax, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* fun = __builtin_FUNCTION()) const; + std::source_location src_loc = std::source_location::current()) const; // Blocking call from the GUI thread - void BlockingCallFromMainThread(std::function&& func, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* fun = __builtin_FUNCTION()) const; + void BlockingCallFromMainThread(std::function&& func, std::source_location src_loc = std::source_location::current()) const; enum class stop_counter_t : u64{}; @@ -212,12 +205,9 @@ public: } void CallFromMainThread(std::function&& func, stop_counter_t counter, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* fun = __builtin_FUNCTION()) const + std::source_location src_loc = std::source_location::current()) const { - CallFromMainThread(std::move(func), nullptr, true, static_cast(counter), line, col, file, fun); + CallFromMainThread(std::move(func), nullptr, true, static_cast(counter), src_loc); } void PostponeInitCode(std::function&& func) diff --git a/rpcs3/Loader/PSF.cpp b/rpcs3/Loader/PSF.cpp index e455a71404..6bb7f4bb0e 100644 --- a/rpcs3/Loader/PSF.cpp +++ b/rpcs3/Loader/PSF.cpp @@ -186,7 +186,7 @@ namespace psf if (!static_cast(cond)) \ { \ if (err != error::stream) \ - psf_log.error("Error loading PSF '%s': %s%s", filename, err, src_loc{__builtin_LINE(), __builtin_COLUMN(), __builtin_FILE(), __builtin_FUNCTION()}); \ + psf_log.error("Error loading PSF '%s': %s%s", filename, err, std::source_location::current()); \ result.sfo.clear(); \ result.errc = err; \ return result; \ @@ -392,7 +392,7 @@ namespace psf return found->second.as_integer(); } - bool check_registry(const registry& psf, std::function validate, u32 line, u32 col, const char* file, const char* func) + bool check_registry(const registry& psf, std::function validate, std::source_location src_loc) { bool psf_ok = true; @@ -413,12 +413,12 @@ namespace psf { if (value.type() == format::string) { - psf_log.error("Entry '%s' is invalid: string='%s'.%s", key, value.as_string(), src_loc{line , col, file, func}); + psf_log.error("Entry '%s' is invalid: string='%s'.%s", key, value.as_string(), src_loc); } else { // TODO: Better logging of other types - psf_log.error("Entry %s is invalid.%s", key, value.as_string(), src_loc{line , col, file, func}); + psf_log.error("Entry %s is invalid.%s", key, value.as_string(), src_loc); } } diff --git a/rpcs3/Loader/PSF.h b/rpcs3/Loader/PSF.h index 044a6543c5..9cc8b16c19 100644 --- a/rpcs3/Loader/PSF.h +++ b/rpcs3/Loader/PSF.h @@ -103,11 +103,7 @@ namespace psf // Get integer value or default value u32 get_integer(const registry& psf, std::string_view key, u32 def = 0); - bool check_registry(const registry& psf, std::function validate = {}, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()); + bool check_registry(const registry& psf, std::function validate = {}, std::source_location src_loc = std::source_location::current()); // Assign new entry inline void assign(registry& psf, std::string_view key, entry&& _entry) diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index 52a1493b60..365673f36b 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__amd64__) #define ARCH_X64 1 @@ -908,47 +909,31 @@ const_str_t(const char8_t(&a)[Size]) -> const_str_t; using const_str = const_str_t<>; -struct src_loc -{ - u32 line; - u32 col; - const char* file; - const char* func; -}; - namespace fmt { - [[noreturn]] void raw_verify_error(const src_loc& loc, const char8_t* msg); + [[noreturn]] void raw_verify_error(std::source_location loc, const char8_t* msg); } template -constexpr decltype(auto) ensure(T&& arg, const_str msg = const_str(), - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) noexcept +constexpr decltype(auto) ensure(T&& arg, const_str msg = const_str(), std::source_location src_loc = std::source_location::current()) noexcept { if (std::forward(arg)) [[likely]] { return std::forward(arg); } - fmt::raw_verify_error({line, col, file, func}, msg); + fmt::raw_verify_error(src_loc, msg); } template requires (std::is_invocable_v) -constexpr decltype(auto) ensure(T&& arg, F&& pred, const_str msg = const_str(), - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) noexcept +constexpr decltype(auto) ensure(T&& arg, F&& pred, const_str msg = const_str(), std::source_location src_loc = std::source_location::current()) noexcept { if (std::forward(pred)(std::forward(arg))) [[likely]] { return std::forward(arg); } - fmt::raw_verify_error({line, col, file, func}, msg); + fmt::raw_verify_error(src_loc, msg); } // narrow() function details @@ -1024,16 +1009,12 @@ struct narrow_impl(std::declval()))> -[[nodiscard]] constexpr To narrow(const From& value, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) +[[nodiscard]] constexpr To narrow(const From& value, std::source_location src_loc = std::source_location::current()) { // Narrow check if (narrow_impl::test(value)) [[unlikely]] { - fmt::raw_verify_error({line, col, file, func}, u8"Narrowing error"); + fmt::raw_verify_error(src_loc, u8"Narrowing error"); } return static_cast(value); @@ -1041,11 +1022,7 @@ template // Returns u32 size() for container template requires requires (const CT& x) { std::size(x); } -[[nodiscard]] constexpr u32 size32(const CT& container, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) +[[nodiscard]] constexpr u32 size32(const CT& container, std::source_location src_loc = std::source_location::current()) { // TODO: Support std::array constexpr bool is_const = std::is_array_v>; @@ -1057,38 +1034,30 @@ template requires requires (const CT& x) { std::size(x); } } else { - return narrow(container.size(), line, col, file, func); + return narrow(container.size(), src_loc); } } template requires requires (CT&& x) { std::size(x); std::data(x); } || requires (CT&& x) { std::size(x); x.front(); } -[[nodiscard]] constexpr auto& at32(CT&& container, T&& index, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) +[[nodiscard]] constexpr auto& at32(CT&& container, T&& index, std::source_location src_loc = std::source_location::current()) { - // Make sure the index is within u32 range (TODO: downcast index properly with common_type) - const u32 idx = ::narrow(+index, line, 10001, file, func); - const u32 csz = ::size32(container, line, 10002, file, func); + // Make sure the index is within u32 range + const std::make_unsigned_t> idx = index; + const u32 csz = ::size32(container, src_loc); if (csz <= idx) [[unlikely]] - fmt::raw_verify_error({line, col, file, func}, u8"Out of range"); + fmt::raw_verify_error(src_loc, u8"Out of range"); auto it = std::begin(std::forward(container)); std::advance(it, idx); return *it; } template requires requires (CT&& x, T&& y) { x.count(y); x.find(y); } -[[nodiscard]] constexpr auto& at32(CT&& container, T&& index, - u32 line = __builtin_LINE(), - u32 col = __builtin_COLUMN(), - const char* file = __builtin_FILE(), - const char* func = __builtin_FUNCTION()) +[[nodiscard]] constexpr auto& at32(CT&& container, T&& index, std::source_location src_loc = std::source_location::current()) { // Associative container const auto found = container.find(std::forward(index)); if (found == container.end()) [[unlikely]] - fmt::raw_verify_error({line, col, file, func}, u8"Out of range"); + fmt::raw_verify_error(src_loc, u8"Out of range"); return found->second; }