Index: libcxx/docs/FeatureTestMacroTable.rst =================================================================== --- libcxx/docs/FeatureTestMacroTable.rst +++ libcxx/docs/FeatureTestMacroTable.rst @@ -202,6 +202,8 @@ ------------------------------------------------- ----------------- ``__cpp_lib_ranges`` *unimplemented* ------------------------------------------------- ----------------- + ``__cpp_lib_source_location`` ``201907L`` + ------------------------------------------------- ----------------- ``__cpp_lib_span`` ``202002L`` ------------------------------------------------- ----------------- ``__cpp_lib_three_way_comparison`` *unimplemented* Index: libcxx/include/CMakeLists.txt =================================================================== --- libcxx/include/CMakeLists.txt +++ libcxx/include/CMakeLists.txt @@ -130,6 +130,7 @@ set setjmp.h shared_mutex + source_location span sstream stack Index: libcxx/include/module.modulemap =================================================================== --- libcxx/include/module.modulemap +++ libcxx/include/module.modulemap @@ -428,6 +428,11 @@ export initializer_list export * } + module source_location { + requires cplusplus20 + header "source_location" + export * + } module sstream { header "sstream" // FIXME: should re-export istream, ostream, ios, streambuf, string? Index: libcxx/include/source_location =================================================================== --- /dev/null +++ libcxx/include/source_location @@ -0,0 +1,90 @@ +// -*- C++ -*- +//===--------------------------- regex ------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_SOURCE_LOCATION +#define _LIBCPP_SOURCE_LOCATION + +/* + source_location synopsis + +namespace std { +struct source_location +{ + // source_location construction + static consteval source_location current() noexcept; + constexpr source_location() noexcept; + + // source_location field access + constexpr uint_least32_t line() const noexcept; + constexpr uint_least32_t column() const noexcept; + constexpr const char* file_name() const noexcept; + constexpr const char* function_name() const noexcept; + +private: + uint_least32_t line_; + uint_least32_t column_; + const char* file_name_; + const char* function_name_; +}; + +} // std + +*/ + +#include <__config> + +#if _LIBCPP_STD_VER > 17 + +#include + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct source_location { + // source_location construction + static consteval source_location + current(uint_least32_t line = __builtin_LINE(), + uint_least32_t column = __builtin_COLUMN(), + const char* file_name = __builtin_FILE(), + const char* function_name = __builtin_FUNCTION()) noexcept { + source_location loc{}; + loc.line_ = line; + loc.column_ = column; + loc.file_name_ = file_name; + loc.function_name_ = function_name; + + return loc; + } + + constexpr source_location() noexcept = default; + + // source_location field access + constexpr uint_least32_t line() const noexcept { return line_; } + constexpr uint_least32_t column() const noexcept { return column_; } + constexpr const char* file_name() const noexcept { return file_name_; } + constexpr const char* function_name() const noexcept { + return function_name_; + } + +private: + uint_least32_t line_; + uint_least32_t column_; + const char* file_name_{""}; + const char* function_name_{""}; +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP_SOURCE_LOCATION Index: libcxx/include/version =================================================================== --- libcxx/include/version +++ libcxx/include/version @@ -100,6 +100,7 @@ __cpp_lib_shared_ptr_arrays 201611L __cpp_lib_shared_ptr_weak_type 201606L __cpp_lib_shared_timed_mutex 201402L +__cpp_lib_source_location 201907L __cpp_lib_span 202002L __cpp_lib_string_udls 201304L __cpp_lib_string_view 201606L @@ -242,6 +243,7 @@ # define __cpp_lib_math_constants 201907L # endif // # define __cpp_lib_ranges 201811L +# define __cpp_lib_source_location 201907L # define __cpp_lib_span 202002L // # define __cpp_lib_three_way_comparison 201711L # define __cpp_lib_to_array 201907L Index: libcxx/test/libcxx/double_include.sh.cpp =================================================================== --- libcxx/test/libcxx/double_include.sh.cpp +++ libcxx/test/libcxx/double_include.sh.cpp @@ -116,6 +116,9 @@ #ifndef _LIBCPP_HAS_NO_THREADS #include #endif +#if __cplusplus >= 202002L +#include +#endif #include #include #include Index: libcxx/test/libcxx/support/source_location.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/libcxx/support/source_location.pass.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// + +// + +#include +#include +#include + +#include "test_macros.h" + +#include +#include +#include +#include + +#include "source_location" + +// [support.srcloc.class] p1.1 +static_assert(std::is_nothrow_move_constructible_v); +// [support.srcloc.class] p1.2 +static_assert(std::is_nothrow_move_assignable_v); +// [support.srcloc.class] p1.3 +static_assert(std::is_nothrow_swappable_v); + +constexpr auto f(std::source_location a = std::source_location::current()) { + return a; +} + +int main(int, char**) { + // [support.srcloc.class] p1 Cpp17DefaultConstructible + { + std::source_location t; + std::source_location u{}; + std::source_location tt = std::source_location(); + std::source_location uu = std::source_location{}; + } + + // [support.srcloc.class] p1 Cpp17CopyConstructible + { + std::source_location v; + [[maybe_unused]] std::source_location t = v; + [[maybe_unused]] std::source_location u(v); + } + + // [support.srcloc.class] p1 Cpp17CopyAssignable + { + std::source_location t; + std::source_location v; + t = v; + assert(t.line() == v.line()); + assert(t.column() == v.column()); + assert(strcmp(t.file_name(), v.file_name()) == 0); + assert(strcmp(t.function_name(), v.function_name()) == 0); + } + + // [support.srcloc.class] p1 Cpp17Destructible + { + std::source_location u; + u.~source_location(); + } + + // [support.srcloc.class] p3 + { + std::source_location rhs; + const auto line = rhs.line(); + const auto column = rhs.column(); + const std::string file_name = + rhs.file_name(); // This covers [support.srcloc.class] p2 + const std::string function_name = + rhs.function_name(); // This covers [support.srcloc.class] p2 + std::source_location lhs = std::move(rhs); + + // [support.srcloc.class] p3.1 + assert(strcmp(lhs.file_name(), file_name.c_str()) == 0); + // [support.srcloc.class] p3.2 + assert(strcmp(lhs.function_name(), function_name.c_str()) == 0); + // [support.srcloc.class] p3.3 + assert(lhs.line() == line); + // [support.srcloc.class] p3.4 + assert(lhs.column() == column); + } + + // [support.srcloc.cons] 3 ensure at least line matches + { + constexpr auto line = __LINE__ + 1; + constexpr auto sLocLine = f(); + static_assert(line == sLocLine.line()); + } + + // [support.srcloc.cons] 3 ensure at least line matches + { + constexpr std::source_location c = std::source_location::current(); + constexpr auto sLocLine = f(c); + static_assert(c.line() == sLocLine.line()); + } + + return 0; +} Index: libcxx/utils/generate_feature_test_macro_components.py =================================================================== --- libcxx/utils/generate_feature_test_macro_components.py +++ libcxx/utils/generate_feature_test_macro_components.py @@ -593,6 +593,12 @@ }, "headers": ["array"], }, + {"name": "__cpp_lib_source_location", + "values": { + "c++2a": int(201907), + }, + "headers": ["span"], + }, {"name": "__cpp_lib_span", "values": { "c++2a": int(202002),