diff options
author | Brian Gianforcaro <bgianf@serenityos.org> | 2021-04-23 22:26:53 -0700 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-04-24 20:33:00 +0200 |
commit | 0ad29bc3c915a7e093d5400b8bb43a3e553f46ed (patch) | |
tree | cc50c1e99d6c7e5afce869e8afc87569f7546a01 | |
parent | b0faf2287a016a1d1568313ab28a494c4b20398e (diff) | |
download | serenity-0ad29bc3c915a7e093d5400b8bb43a3e553f46ed.zip |
AK: Add SourceLocation support
C++20 added std::source_location, which lets you capture the
callers __FILE__ / __LINE__ / __FUNCTION__ etc as a default
argument to functions.
See: https://en.cppreference.com/w/cpp/utility/source_location
During a bug investigation @ADKaster suggested we could use this
to make the LOCK_DEBUG feature of the kernel more user friendly
and allow it to automatically instrument all call sites.
We then implemented / tested it over discord. :^)
Co-Authored-by: Andrew Kaster <andrewdkaster@gmail.com>
-rw-r--r-- | AK/SourceLocation.h | 41 | ||||
-rw-r--r-- | AK/Tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | AK/Tests/TestSourceLocation.cpp | 33 |
3 files changed, 75 insertions, 0 deletions
diff --git a/AK/SourceLocation.h b/AK/SourceLocation.h new file mode 100644 index 0000000000..ee77526fcf --- /dev/null +++ b/AK/SourceLocation.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021, Andrew Kaster <andrewdkaster@gmail.com> + * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/StringView.h> +#include <AK/Types.h> + +namespace AK { + +class SourceLocation { +public: + [[nodiscard]] constexpr StringView function_name() const { return StringView(m_function); } + [[nodiscard]] constexpr StringView file_name() const { return StringView(m_file); } + [[nodiscard]] constexpr u32 line_number() const { return m_line; } + + [[nodiscard]] static constexpr SourceLocation current(const char* const file = __builtin_FILE(), u32 line = __builtin_LINE(), const char* const function = __builtin_FUNCTION()) + { + return SourceLocation(file, line, function); + } + +private: + constexpr SourceLocation(const char* const file, u32 line, const char* const function) + : m_function(function) + , m_file(file) + , m_line(line) + { + } + + const char* const m_function { nullptr }; + const char* const m_file { nullptr }; + const u32 m_line { 0 }; +}; + +} + +using AK::SourceLocation; diff --git a/AK/Tests/CMakeLists.txt b/AK/Tests/CMakeLists.txt index 07c5e99afd..e2de8f372d 100644 --- a/AK/Tests/CMakeLists.txt +++ b/AK/Tests/CMakeLists.txt @@ -45,6 +45,7 @@ set(AK_TEST_SOURCES TestRefPtr.cpp TestSinglyLinkedList.cpp TestSourceGenerator.cpp + TestSourceLocation.cpp TestSpan.cpp TestString.cpp TestStringUtils.cpp diff --git a/AK/Tests/TestSourceLocation.cpp b/AK/Tests/TestSourceLocation.cpp new file mode 100644 index 0000000000..12f2e16c17 --- /dev/null +++ b/AK/Tests/TestSourceLocation.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, Andrew Kaster <andrewdkaster@gmail.com> + * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/SourceLocation.h> +#include <AK/StringView.h> +#include <AK/TestSuite.h> + +TEST_CASE(basic_scenario) +{ + auto location = SourceLocation::current(); + EXPECT_EQ(StringView(__FILE__), location.file_name()); + EXPECT_EQ(StringView(__FUNCTION__), location.function_name()); + EXPECT_EQ(__LINE__ - 3u, location.line_number()); +} + +static StringView test_default_arg(const SourceLocation& loc = SourceLocation::current()) +{ + return loc.function_name(); +} + +TEST_CASE(default_arg_scenario) +{ + auto actual_calling_function = test_default_arg(); + auto expected_calling_function = StringView(__FUNCTION__); + + EXPECT_EQ(expected_calling_function, actual_calling_function); +} + +TEST_MAIN(SourceLocation) |