lg2: workaround clang-tidy's lack of source_location
clang/clang-tidy do not currently support C++20 source_location,
which causes repositories attempting to use lg2 but with clang-tidy
enabled to fail with lots of missing-type errors. Workaround this
by detecting the situation and falling back to use
std::experimental::source_location.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Idb5a555243568c394505890035423d39e9b22407
diff --git a/lib/include/phosphor-logging/lg2.hpp b/lib/include/phosphor-logging/lg2.hpp
index e1ac0ab..9486916 100644
--- a/lib/include/phosphor-logging/lg2.hpp
+++ b/lib/include/phosphor-logging/lg2.hpp
@@ -9,12 +9,12 @@
#include <phosphor-logging/lg2/flags.hpp>
#include <phosphor-logging/lg2/header.hpp>
#include <phosphor-logging/lg2/level.hpp>
-#include <source_location>
+#include <phosphor-logging/lg2/source_location.hpp>
namespace lg2
{
/** Implementation of the structured logging `lg2::log` interface. */
-template <level S = level::debug, details::any_but<std::source_location>... Ts>
+template <level S = level::debug, details::any_but<lg2::source_location>... Ts>
struct log
{
/** log with a custom source_location.
@@ -23,7 +23,7 @@
* @param[in] msg - The message to log.
* @param[in] ts - The rest of the arguments.
*/
- explicit log(const std::source_location& s, const char* msg,
+ explicit log(const lg2::source_location& s, const char* msg,
details::header_str_conversion_t<Ts&&>... ts)
{
details::log_conversion::start(
@@ -39,7 +39,7 @@
*/
explicit log(
const char* msg, details::header_str_conversion_t<Ts&&>... ts,
- const std::source_location& s = std::source_location::current()) :
+ const lg2::source_location& s = lg2::source_location::current()) :
log(s, msg, std::forward<details::header_str_conversion_t<Ts&&>>(ts)...)
{
}
@@ -54,7 +54,7 @@
explicit log(const char*, Ts&&...) -> log<S, Ts...>;
template <level S = level::debug, typename... Ts>
-explicit log(const std::source_location&, const char*, Ts&&...)
+explicit log(const lg2::source_location&, const char*, Ts&&...)
-> log<S, Ts...>;
/** Macro to define aliases for lg2::level(...) -> lg2::log<level>(...)
@@ -72,7 +72,7 @@
explicit levelval(const char*, Ts&&...) -> levelval<Ts...>; \
\
template <typename... Ts> \
- explicit levelval(const std::source_location&, const char*, Ts&&...) \
+ explicit levelval(const lg2::source_location&, const char*, Ts&&...) \
->levelval<Ts...>
// Enumerate the aliases for each log level.
diff --git a/lib/include/phosphor-logging/lg2/conversion.hpp b/lib/include/phosphor-logging/lg2/conversion.hpp
index 9788b1a..0c24c5b 100644
--- a/lib/include/phosphor-logging/lg2/conversion.hpp
+++ b/lib/include/phosphor-logging/lg2/conversion.hpp
@@ -7,8 +7,8 @@
#include <phosphor-logging/lg2/header.hpp>
#include <phosphor-logging/lg2/level.hpp>
#include <phosphor-logging/lg2/logger.hpp>
+#include <phosphor-logging/lg2/source_location.hpp>
#include <sdbusplus/message/native_types.hpp>
-#include <source_location>
#include <string_view>
#include <tuple>
#include <type_traits>
@@ -260,7 +260,7 @@
/** Conversion and validation is complete. Pass along to the final
* do_log variadic function. */
template <typename... Ts>
- static void done(level l, const std::source_location& s, const char* m,
+ static void done(level l, const lg2::source_location& s, const char* m,
Ts&&... ts)
{
do_log(l, s, m, std::forward<Ts>(ts)..., nullptr);
@@ -372,7 +372,7 @@
/** Start processing a sequence of arguments to `lg2::log` using `step` or
* `done`. */
template <typename... Ts>
- static void start(level l, const std::source_location& s, const char* msg,
+ static void start(level l, const lg2::source_location& s, const char* msg,
Ts&&... ts)
{
// If there are no arguments (ie. just a message), then skip processing
diff --git a/lib/include/phosphor-logging/lg2/logger.hpp b/lib/include/phosphor-logging/lg2/logger.hpp
index 7459589..a392e70 100644
--- a/lib/include/phosphor-logging/lg2/logger.hpp
+++ b/lib/include/phosphor-logging/lg2/logger.hpp
@@ -2,7 +2,7 @@
#include <cstddef>
#include <phosphor-logging/lg2/level.hpp>
-#include <source_location>
+#include <phosphor-logging/lg2/source_location.hpp>
namespace lg2::details
{
@@ -19,6 +19,6 @@
* log call.
* @param[in] char* - The primary message to log.
*/
-void do_log(level, const std::source_location&, const char*, ...);
+void do_log(level, const lg2::source_location&, const char*, ...);
} // namespace lg2::details
diff --git a/lib/include/phosphor-logging/lg2/source_location.hpp b/lib/include/phosphor-logging/lg2/source_location.hpp
new file mode 100644
index 0000000..9d2033b
--- /dev/null
+++ b/lib/include/phosphor-logging/lg2/source_location.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+// As of clang-12, clang still doesn't support std::source_location, which
+// means that clang-tidy also doesn't support std::source_location.
+// Inside the libstdc++ implementation of <source_location> is this check of
+// __builtin_source_location to determine if the compiler supports the
+// necessary bits for std::source_location, and if not the header ends up doing
+// nothing. Use this same builtin-check to detect when we're running under
+// an "older" clang and fallback to std::experimental::source_location instead.
+
+#if __has_builtin(__builtin_source_location)
+#include <source_location>
+
+namespace lg2
+{
+using source_location = std::source_location;
+}
+
+#else
+#include <experimental/source_location>
+
+namespace lg2
+{
+using source_location = std::experimental::source_location;
+}
+
+#endif
diff --git a/lib/include/phosphor-logging/meson.build b/lib/include/phosphor-logging/meson.build
index 2b166cb..8c477ad 100644
--- a/lib/include/phosphor-logging/meson.build
+++ b/lib/include/phosphor-logging/meson.build
@@ -29,6 +29,7 @@
'lg2/header.hpp',
'lg2/level.hpp',
'lg2/logger.hpp',
+ 'lg2/source_location.hpp',
subdir: 'phosphor-logging/lg2',
)
diff --git a/lib/lg2_logger.cpp b/lib/lg2_logger.cpp
index fd3921c..c8a0d7f 100644
--- a/lib/lg2_logger.cpp
+++ b/lib/lg2_logger.cpp
@@ -125,13 +125,13 @@
static constexpr size_t static_locs = pos_func + 1;
/** No-op output of a message. */
-static void noop_extra_output(level, const std::source_location&,
+static void noop_extra_output(level, const lg2::source_location&,
const std::string&)
{
}
/** std::cerr output of a message. */
-static void cerr_extra_output(level l, const std::source_location& s,
+static void cerr_extra_output(level l, const lg2::source_location& s,
const std::string& m)
{
std::cerr << s.file_name() << ":" << s.line() << ":" << s.function_name()
@@ -143,7 +143,7 @@
isatty(fileno(stderr)) ? cerr_extra_output : noop_extra_output;
// Do_log implementation.
-void do_log(level l, const std::source_location& s, const char* m, ...)
+void do_log(level l, const lg2::source_location& s, const char* m, ...)
{
using namespace std::string_literals;