Skip to content

Commit 5ef408f

Browse files
authored
User/dmachaj/slim source location (#1379)
* First draft of slim_source_location * Fix build breaks from first impl * Fix failing test case
1 parent 2511bf7 commit 5ef408f

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

strings/base_macros.h

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,58 @@ typedef struct _GUID GUID;
8585
// Some projects may decide to disable std::source_location support to prevent source code information from ending up in their
8686
// release binaries, or to reduce binary size. Defining WINRT_NO_SOURCE_LOCATION will prevent this feature from activating.
8787
#if defined(__cpp_lib_source_location) && !defined(WINRT_NO_SOURCE_LOCATION)
88+
89+
namespace winrt::impl
90+
{
91+
// This struct is intended to be highly similar to std::source_location. The key difference is
92+
// that function_name is NOT included. Function names do not fold to identical strings and can
93+
// have heavy binary size overhead when templates cause many permutations to exist.
94+
struct slim_source_location
95+
{
96+
[[nodiscard]] static consteval slim_source_location current(
97+
const std::uint_least32_t line = __builtin_LINE(),
98+
const char* const file = __builtin_FILE()) noexcept
99+
{
100+
return slim_source_location{ line, file };
101+
}
102+
103+
[[nodiscard]] constexpr slim_source_location() noexcept = default;
104+
105+
[[nodiscard]] constexpr slim_source_location(const std::uint_least32_t line,
106+
const char* const file) noexcept :
107+
m_line(line),
108+
m_file(file)
109+
{}
110+
111+
[[nodiscard]] constexpr std::uint_least32_t line() const noexcept
112+
{
113+
return m_line;
114+
}
115+
116+
[[nodiscard]] constexpr const char* file_name() const noexcept
117+
{
118+
return m_file;
119+
}
120+
121+
constexpr const char* function_name() const noexcept
122+
{
123+
// This is intentionally not included. See comment above.
124+
return nullptr;
125+
}
126+
127+
private:
128+
const std::uint_least32_t m_line{};
129+
const char* const m_file{};
130+
};
131+
}
132+
133+
// std::source_location includes function_name which can be helpful but creates a lot of binary size impact. Many consumers
134+
// have defined WINRT_NO_SOURCE_LOCATION to prevent this impact, losing the value of source_location. We have defined a
135+
// slim_source_location struct that is equivalent but excludes function_name. This should have the vast majority of the
136+
// usefulness of source_location while having a much smaller binary impact.
137+
//
138+
// When building _DEBUG binary size is not usually much of a concern, so we can use the full source_location type.
139+
#ifdef _DEBUG
88140
#define WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT , std::source_location const& sourceInformation
89141
#define WINRT_IMPL_SOURCE_LOCATION_ARGS , std::source_location const& sourceInformation = std::source_location::current()
90142
#define WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM std::source_location const& sourceInformation = std::source_location::current()
@@ -96,7 +148,24 @@ typedef struct _GUID GUID;
96148

97149
#ifdef _MSC_VER
98150
#pragma detect_mismatch("WINRT_SOURCE_LOCATION", "true")
99-
#endif
151+
#endif // _MSC_VER
152+
153+
#else // !_DEBUG
154+
#define WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT , winrt::impl::slim_source_location const& sourceInformation
155+
#define WINRT_IMPL_SOURCE_LOCATION_ARGS , winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()
156+
#define WINRT_IMPL_SOURCE_LOCATION_ARGS_SINGLE_PARAM winrt::impl::slim_source_location const& sourceInformation = winrt::impl::slim_source_location::current()
157+
158+
#define WINRT_IMPL_SOURCE_LOCATION_FORWARD , sourceInformation
159+
#define WINRT_IMPL_SOURCE_LOCATION_FORWARD_SINGLE_PARAM sourceInformation
160+
161+
#define WINRT_SOURCE_LOCATION_ACTIVE
162+
163+
#ifdef _MSC_VER
164+
#pragma detect_mismatch("WINRT_SOURCE_LOCATION", "slim")
165+
#endif // _MSC_VER
166+
167+
#endif // _DEBUG
168+
100169
#else
101170
#define WINRT_IMPL_SOURCE_LOCATION_ARGS_NO_DEFAULT
102171
#define WINRT_IMPL_SOURCE_LOCATION_ARGS
@@ -107,5 +176,5 @@ typedef struct _GUID GUID;
107176

108177
#ifdef _MSC_VER
109178
#pragma detect_mismatch("WINRT_SOURCE_LOCATION", "false")
110-
#endif
111-
#endif
179+
#endif // _MSC_VER
180+
#endif // defined(__cpp_lib_source_location) && !defined(WINRT_NO_SOURCE_LOCATION)

test/test_cpp20/custom_error.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,16 @@ TEST_CASE("custom_error_logger")
5454
const auto fileNameSv = std::string_view(s_loggerArgs.fileName);
5555
REQUIRE(!fileNameSv.empty());
5656
REQUIRE(fileNameSv.find("custom_error.cpp") != std::string::npos);
57+
#ifdef _DEBUG
5758
const auto functionNameSv = std::string_view(s_loggerArgs.functionName);
5859
REQUIRE(!functionNameSv.empty());
5960
// Every compiler has a slightly different naming approach for this function, and even the same
6061
// compiler can change its mind over time. Instead of matching the entire function name just
6162
// match against the part we care about.
6263
REQUIRE((functionNameSv.find("FailOnLine15") != std::string_view::npos));
64+
#else
65+
REQUIRE(s_loggerArgs.functionName == nullptr);
66+
#endif // _DEBUG
6367

6468
REQUIRE(s_loggerArgs.returnAddress);
6569
REQUIRE(s_loggerArgs.result == static_cast<int32_t>(0x80000018)); // E_ILLEGAL_DELEGATE_ASSIGNMENT)

0 commit comments

Comments
 (0)