From 0ad29bc3c915a7e093d5400b8bb43a3e553f46ed Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Fri, 23 Apr 2021 22:26:53 -0700 Subject: [PATCH] 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 --- AK/SourceLocation.h | 41 +++++++++++++++++++++++++++++++++ AK/Tests/CMakeLists.txt | 1 + AK/Tests/TestSourceLocation.cpp | 33 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 AK/SourceLocation.h create mode 100644 AK/Tests/TestSourceLocation.cpp 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 + * Copyright (c) 2021, Brian Gianforcaro + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +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 + * Copyright (c) 2021, Brian Gianforcaro + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +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)