diff --git a/include/slang/util/TypeTraits.h b/include/slang/util/TypeTraits.h index eada3a4da..b068d1c16 100644 --- a/include/slang/util/TypeTraits.h +++ b/include/slang/util/TypeTraits.h @@ -26,7 +26,7 @@ namespace detail { template constexpr std::string_view wrappedTypeName() { - return SLANG_ASSERT_FUNCTION; + return std::source_location::current().function_name(); } constexpr std::size_t wrappedTypeNamePrefixLength() { diff --git a/include/slang/util/Util.h b/include/slang/util/Util.h index 5c9464c16..ec05b6c08 100644 --- a/include/slang/util/Util.h +++ b/include/slang/util/Util.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,16 +17,6 @@ #include "slang/slang_export.h" #include "slang/util/Enum.h" -#if defined(__GNUC__) || defined(__clang__) -# define SLANG_ASSERT_FUNCTION __PRETTY_FUNCTION__ -#elif defined(_MSC_VER) -# define SLANG_ASSERT_FUNCTION __FUNCSIG__ -#elif defined(__SUNPRO_CC) -# define SLANG_ASSERT_FUNCTION __func__ -#else -# define SLANG_ASSERT_FUNCTION __FUNCTION__ -#endif - #if __cpp_exceptions # define SLANG_TRY try # define SLANG_CATCH(X) catch (X) @@ -33,8 +24,7 @@ #else # define SLANG_TRY if (true) # define SLANG_CATCH(X) if (false) -# define SLANG_THROW(e) \ - slang::assert::handleThrow((e).what(), __FILE__, __LINE__, SLANG_ASSERT_FUNCTION) +# define SLANG_THROW(e) slang::assert::handleThrow((e).what(), std::source_location::current()) #endif #if defined(__clang__) @@ -70,14 +60,13 @@ #endif #if SLANG_ASSERT_ENABLED -# define SLANG_ASSERT(cond) \ - do { \ - if (!(cond)) \ - slang::assert::assertFailed(#cond, __FILE__, __LINE__, SLANG_ASSERT_FUNCTION); \ +# define SLANG_ASSERT(cond) \ + do { \ + if (!(cond)) \ + slang::assert::assertFailed(#cond, std::source_location::current()); \ } while (false) -# define SLANG_UNREACHABLE \ - slang::assert::handleUnreachable(__FILE__, __LINE__, SLANG_ASSERT_FUNCTION) +# define SLANG_UNREACHABLE slang::assert::handleUnreachable(std::source_location::current()) #else # define SLANG_ASSERT(cond) \ do { \ @@ -130,18 +119,15 @@ class SLANG_EXPORT AssertionException : public std::logic_error { /// A handler that runs when an ASSERT condition fails; it will unconditionally /// throw an exception. -[[noreturn]] SLANG_EXPORT void assertFailed(const char* expr, const char* file, int line, - const char* func); +[[noreturn]] SLANG_EXPORT void assertFailed(const char* expr, const std::source_location& location); /// A handler that runs when an exception is thrown but exceptions are disabled; it will /// unconditionally abort the program. -[[noreturn]] SLANG_EXPORT void handleThrow(const char* msg, const char* file, int line, - const char* func); +[[noreturn]] SLANG_EXPORT void handleThrow(const char* msg, const std::source_location& location); /// A handler that runs when a code path is reached that is supposed to be unreachable. /// An exception will be thrown or the program will be aborted. -[[noreturn]] SLANG_EXPORT void handleUnreachable(const char* file, int line, const char* func); - +[[noreturn]] SLANG_EXPORT void handleUnreachable(const std::source_location& location); } // namespace assert /// A wrapper around a pointer that indicates that it should never be null. diff --git a/source/util/Util.cpp b/source/util/Util.cpp index 3cbe47a85..2023ecb73 100644 --- a/source/util/Util.cpp +++ b/source/util/Util.cpp @@ -15,10 +15,10 @@ namespace slang::assert { -[[noreturn]] void assertFailed(const char* expr, const char* file, int line, const char* func) { +[[noreturn]] void assertFailed(const char* expr, const std::source_location& location) { auto msg = fmt::format("Assertion '{}' failed\n in file {}, line {}\n" " function: {}\n", - expr, file, line, func); + expr, location.file_name(), location.line(), location.function_name()); #if __cpp_exceptions throw AssertionException(msg); @@ -29,19 +29,19 @@ namespace slang::assert { } #if !__cpp_exceptions -[[noreturn]] void handleThrow(const char* msg, const char* file, int line, const char* func) { +[[noreturn]] void handleThrow(const char* msg, const std::source_location& location) { fprintf(stderr, "internal compiler error: '%s'\n in file %s, line %d\n" " function: %s\n", - msg, file, line, func); + msg, location.file_name(), location.line(), location.function_name()); std::abort(); } #endif -[[noreturn]] void handleUnreachable(const char* file, int line, const char* func) { +[[noreturn]] void handleUnreachable(const std::source_location& location) { auto msg = fmt::format("Supposedly unreachable code was executed\n in file {}, line {}\n" " function: {}\n", - file, line, func); + location.file_name(), location.line(), location.function_name()); #if __cpp_exceptions throw std::logic_error(msg); diff --git a/tools/netlist/include/Debug.h b/tools/netlist/include/Debug.h index 2281163bd..7255bddeb 100644 --- a/tools/netlist/include/Debug.h +++ b/tools/netlist/include/Debug.h @@ -10,12 +10,17 @@ #include "Config.h" #include #include +#include namespace netlist { +inline const char* file_name(const char* file) { + return strrchr(file, '/') ? strrchr(file, '/') + 1 : file; +} + template -void DebugMessage(const char* filename, const int line, fmt::format_string fmt, T&&... args) { - fmt::print("{}:{}: ", filename, line); +void DebugMessage(const std::source_location& location, fmt::format_string fmt, T&&... args) { + fmt::print("{}:{}: ", file_name(location.file_name()), location.line()); fmt::print(fmt, std::forward(args)...); } @@ -26,12 +31,10 @@ void InfoMessage(fmt::format_string fmt, T&&... args) { } // namespace netlist -#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) - #ifdef DEBUG -# define DEBUG_PRINT(str, ...) \ - if (netlist::Config::getInstance().debugEnabled) { \ - DebugMessage(__FILENAME__, __LINE__, str __VA_OPT__(, ) __VA_ARGS__); \ +# define DEBUG_PRINT(str, ...) \ + if (netlist::Config::getInstance().debugEnabled) { \ + DebugMessage(std::source_location::current(), str __VA_OPT__(, ) __VA_ARGS__); \ } #else # define DEBUG_PRINT(str, ...)