diff --git a/stl/inc/source_location b/stl/inc/source_location index e4e724d652..31d5fb34cb 100644 --- a/stl/inc/source_location +++ b/stl/inc/source_location @@ -20,15 +20,25 @@ _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new +#ifndef _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION +#ifdef __EDG__ // TRANSITION, DevCom-10199227 +#define _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION 0 +#elif defined(__clang__) // TRANSITION, Clang 17 has this builtin +#define _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION __has_builtin(__builtin_FUNCSIG) +#else // ^^^ Clang / MSVC vvv +#define _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION 1 +#endif // ^^^ MSVC ^^^ +#endif // ^^^ !defined(_USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION) ^^^ + _STD_BEGIN _EXPORT_STD struct source_location { _NODISCARD static consteval source_location current(const uint_least32_t _Line_ = __builtin_LINE(), const uint_least32_t _Column_ = __builtin_COLUMN(), const char* const _File_ = __builtin_FILE(), -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - const char* const _Function_ = __builtin_FUNCTION() -#else // ^^^ workaround / no workaround vvv +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION const char* const _Function_ = __builtin_FUNCSIG() -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + const char* const _Function_ = __builtin_FUNCTION() +#endif // ^^^ basic ^^^ ) noexcept { source_location _Result{}; _Result._Line = _Line_; diff --git a/tests/std/include/test_header_units_and_modules.hpp b/tests/std/include/test_header_units_and_modules.hpp index 828a3e9bbc..cdb5ce1446 100644 --- a/tests/std/include/test_header_units_and_modules.hpp +++ b/tests/std/include/test_header_units_and_modules.hpp @@ -679,11 +679,21 @@ constexpr bool impl_test_source_location() { const auto sl = source_location::current(); assert(sl.line() == __LINE__ - 1); assert(sl.column() == 38); -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(sl.function_name() == "impl_test_source_location"sv); -#else // ^^^ workaround / no workaround vvv + +#ifdef __EDG__ // TRANSITION, DevCom-10199227 +#define TEST_DETAILED_FUNCTION_NAME 0 +#elif defined(__clang__) // TRANSITION, Clang 17 has this builtin +#define TEST_DETAILED_FUNCTION_NAME __has_builtin(__builtin_FUNCSIG) +#else // ^^^ Clang / MSVC vvv +#define TEST_DETAILED_FUNCTION_NAME 1 +#endif // ^^^ MSVC ^^^ + +#if TEST_DETAILED_FUNCTION_NAME assert(sl.function_name() == "bool __cdecl impl_test_source_location(void)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + assert(sl.function_name() == "impl_test_source_location"sv); +#endif // ^^^ basic ^^^ + assert(string_view{sl.file_name()}.ends_with("test_header_units_and_modules.hpp"sv)); return true; } diff --git a/tests/std/tests/P1208R6_source_location/header.h b/tests/std/tests/P1208R6_source_location/header.h index e9c8b48bbb..3369da4d63 100644 --- a/tests/std/tests/P1208R6_source_location/header.h +++ b/tests/std/tests/P1208R6_source_location/header.h @@ -17,10 +17,10 @@ constexpr void header_test() { #else // ^^^ EDG / C1XX vvv assert(x.column() == 37); #endif // ^^^ C1XX ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(x.function_name() == "header_test"sv); -#else // ^^^ workaround / no workaround vvv +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION assert(x.function_name() == "void __cdecl header_test(void)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + assert(x.function_name() == "header_test"sv); +#endif // ^^^ basic ^^^ assert(string_view{x.file_name()}.ends_with("header.h"sv)); } diff --git a/tests/std/tests/P1208R6_source_location/test.cpp b/tests/std/tests/P1208R6_source_location/test.cpp index 4640ca5c13..18b8f26f57 100644 --- a/tests/std/tests/P1208R6_source_location/test.cpp +++ b/tests/std/tests/P1208R6_source_location/test.cpp @@ -9,6 +9,12 @@ #include using namespace std; +#ifdef _M_IX86 +#define THISCALL_OR_CDECL "__thiscall" +#else +#define THISCALL_OR_CDECL "__cdecl" +#endif + static_assert(is_nothrow_default_constructible_v); static_assert(is_nothrow_move_constructible_v); static_assert(is_nothrow_move_assignable_v); @@ -61,11 +67,11 @@ constexpr void local_test() { #else // ^^^ EDG / C1XX vvv assert(x.column() == 37); #endif // ^^^ C1XX ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(x.function_name() == "local_test"sv); -#else // ^^^ workaround / no workaround vvv +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION assert(x.function_name() == "void __cdecl local_test(void)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + assert(x.function_name() == "local_test"sv); +#endif // ^^^ basic ^^^ assert(string_view{x.file_name()}.ends_with(test_cpp)); } @@ -73,11 +79,11 @@ constexpr void argument_test( const unsigned int line, const unsigned int column, const source_location x = source_location::current()) { assert(x.line() == line); assert(x.column() == column); -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(x.function_name() == "test"sv); -#else // ^^^ workaround / no workaround vvv +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION assert(x.function_name() == "bool __cdecl test(void)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + assert(x.function_name() == "test"sv); +#endif // ^^^ basic ^^^ assert(string_view{x.file_name()}.ends_with(test_cpp)); } @@ -89,15 +95,18 @@ constexpr void sloc_constructor_test() { #else // ^^^ defined(__EDG__) / !defined(__EDG__) vvv assert(x.loc.column() == 13); #endif // ^^^ !defined(__EDG__) ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(x.loc.function_name() == "sloc_constructor_test"sv); -#else // ^^^ workaround / no workaround vvv +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION +#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-1285783 if (is_constant_evaluated()) { - assert(x.loc.function_name() == "int __cdecl main(void)"sv); // TRANSITION, VSO-1285783 - } else { + assert(x.loc.function_name() == "int __cdecl main(void)"sv); + } else +#endif // ^^^ workaround ^^^ + { assert(x.loc.function_name() == "void __cdecl sloc_constructor_test(void)"sv); } -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + assert(x.loc.function_name() == "sloc_constructor_test"sv); +#endif // ^^^ basic ^^^ assert(string_view{x.loc.file_name()}.ends_with(test_cpp)); } @@ -111,13 +120,11 @@ constexpr void different_constructor_test() { #else // ^^^ EDG / C1XX vvv assert(x.loc.column() == 5); #endif // ^^^ C1XX ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION + assert(x.loc.function_name() == THISCALL_OR_CDECL " s::s(int)"sv); +#else // ^^^ detailed / basic vvv assert(x.loc.function_name() == "s"sv); -#elif defined(_M_IX86) // ^^^ workaround / no workaround vvv - assert(x.loc.function_name() == "__thiscall s::s(int)"sv); -#else // ^^^ _M_IX86 / !_M_IX86 vvv - assert(x.loc.function_name() == "__cdecl s::s(int)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#endif // ^^^ basic ^^^ assert(string_view{x.loc.file_name()}.ends_with(test_cpp)); } @@ -129,15 +136,18 @@ constexpr void sub_member_test() { #else // ^^^ defined(__EDG__) / !defined(__EDG__) vvv assert(s.x.loc.column() == 14); #endif // ^^^ !defined(__EDG__) ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(s.x.loc.function_name() == "sub_member_test"sv); -#else // ^^^ workaround / no workaround vvv +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION +#if !defined(__clang__) && !defined(__EDG__) // TRANSITION, VSO-1285783 if (is_constant_evaluated()) { - assert(s.x.loc.function_name() == "int __cdecl main(void)"sv); // TRANSITION, VSO-1285783 - } else { + assert(s.x.loc.function_name() == "int __cdecl main(void)"sv); + } else +#endif // ^^^ workaround ^^^ + { assert(s.x.loc.function_name() == "void __cdecl sub_member_test(void)"sv); } -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#else // ^^^ detailed / basic vvv + assert(s.x.loc.function_name() == "sub_member_test"sv); +#endif // ^^^ basic ^^^ assert(string_view{s.x.loc.file_name()}.ends_with(test_cpp)); const s2 s_i{1}; @@ -149,13 +159,11 @@ constexpr void sub_member_test() { #else // ^^^ EDG / C1XX vvv assert(s_i.x.loc.column() == 5); #endif // ^^^ C1XX ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 +#if _USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION + assert(s_i.x.loc.function_name() == THISCALL_OR_CDECL " s2::s2(int)"sv); +#else // ^^^ detailed / basic vvv assert(s_i.x.loc.function_name() == "s2"sv); -#elif defined(_M_IX86) // ^^^ workaround / no workaround vvv - assert(s_i.x.loc.function_name() == "__thiscall s2::s2(int)"sv); -#else // ^^^ _M_IX86 / !_M_IX86 vvv - assert(s_i.x.loc.function_name() == "__cdecl s2::s2(int)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#endif // ^^^ basic ^^^ assert(string_view{s_i.x.loc.file_name()}.ends_with(test_cpp)); } @@ -176,19 +184,20 @@ constexpr void lambda_test() { assert(x1.column() == 52); assert(x2.column() == 50); #endif // ^^^ C1XX ^^^ -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 - assert(x1.function_name() == "lambda_test"sv); - assert(x2.function_name() == "operator()"sv); -#elif defined(_M_IX86) // ^^^ workaround / no workaround vvv - assert(x1.function_name() == "void __cdecl lambda_test(void)"sv); - assert( - string_view{x2.function_name()}.starts_with("struct std::source_location __thiscall lambda_test::(void)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#endif // ^^^ detailed non-Clang ^^^ assert(string_view{x1.file_name()}.ends_with(test_cpp)); const auto x2 = function_template(); assert(x1.line() == x2.line()); assert(x1.column() == x2.column()); -#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-10199227 and LLVM-58951 +#if !_USE_DETAILED_FUNCTION_NAME_IN_SOURCE_LOCATION assert(x2.function_name() == "function_template"sv); -#else // ^^^ workaround / no workaround vvv +#elif defined(__clang__) // ^^^ basic / detailed Clang vvv + assert(x2.function_name() == "source_location __cdecl function_template(void) [T = int]"sv); +#else // ^^^ detailed Clang / detailed non-Clang vvv assert(x2.function_name() == "struct std::source_location __cdecl function_template(void)"sv); -#endif // TRANSITION, DevCom-10199227 and LLVM-58951 +#endif // ^^^ detailed non-Clang ^^^ assert(string_view{x1.file_name()} == string_view{x2.file_name()}); }