1*bdd1243dSDimitry Andric// -*- C++ -*- 2*bdd1243dSDimitry Andric//===----------------------------------------------------------------------===// 3*bdd1243dSDimitry Andric// 4*bdd1243dSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*bdd1243dSDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*bdd1243dSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*bdd1243dSDimitry Andric// 8*bdd1243dSDimitry Andric//===----------------------------------------------------------------------===// 9*bdd1243dSDimitry Andric 10*bdd1243dSDimitry Andric#ifndef _LIBCPP_SOURCE_LOCATION 11*bdd1243dSDimitry Andric#define _LIBCPP_SOURCE_LOCATION 12*bdd1243dSDimitry Andric 13*bdd1243dSDimitry Andric/* source_location synopsis 14*bdd1243dSDimitry Andric 15*bdd1243dSDimitry Andricnamespace std { 16*bdd1243dSDimitry Andric struct source_location { 17*bdd1243dSDimitry Andric static consteval source_location current() noexcept; 18*bdd1243dSDimitry Andric constexpr source_location() noexcept; 19*bdd1243dSDimitry Andric 20*bdd1243dSDimitry Andric constexpr uint_least32_t line() const noexcept; 21*bdd1243dSDimitry Andric constexpr uint_least32_t column() const noexcept; 22*bdd1243dSDimitry Andric constexpr const char* file_name() const noexcept; 23*bdd1243dSDimitry Andric constexpr const char* function_name() const noexcept; 24*bdd1243dSDimitry Andric }; 25*bdd1243dSDimitry Andric} 26*bdd1243dSDimitry Andric*/ 27*bdd1243dSDimitry Andric 28*bdd1243dSDimitry Andric#include <__config> 29*bdd1243dSDimitry Andric#include <cstdint> 30*bdd1243dSDimitry Andric#include <version> 31*bdd1243dSDimitry Andric 32*bdd1243dSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 33*bdd1243dSDimitry Andric# pragma GCC system_header 34*bdd1243dSDimitry Andric#endif 35*bdd1243dSDimitry Andric 36*bdd1243dSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 37*bdd1243dSDimitry Andric 38*bdd1243dSDimitry Andric#if _LIBCPP_STD_VER >= 20 && __has_builtin(__builtin_source_location) 39*bdd1243dSDimitry Andric 40*bdd1243dSDimitry Andricclass source_location { 41*bdd1243dSDimitry Andric // The names source_location::__impl, _M_file_name, _M_function_name, _M_line, and _M_column 42*bdd1243dSDimitry Andric // are hard-coded in the compiler and must not be changed here. 43*bdd1243dSDimitry Andric struct __impl { 44*bdd1243dSDimitry Andric const char* _M_file_name; 45*bdd1243dSDimitry Andric const char* _M_function_name; 46*bdd1243dSDimitry Andric unsigned _M_line; 47*bdd1243dSDimitry Andric unsigned _M_column; 48*bdd1243dSDimitry Andric }; 49*bdd1243dSDimitry Andric const __impl* __ptr_ = nullptr; 50*bdd1243dSDimitry Andric // GCC returns the type 'const void*' from the builtin, while clang returns 51*bdd1243dSDimitry Andric // `const __impl*`. Per C++ [expr.const], casts from void* are not permitted 52*bdd1243dSDimitry Andric // in constant evaluation, so we don't want to use `void*` as the argument 53*bdd1243dSDimitry Andric // type unless the builtin returned that, anyhow, and the invalid cast is 54*bdd1243dSDimitry Andric // unavoidable. 55*bdd1243dSDimitry Andric using __bsl_ty = decltype(__builtin_source_location()); 56*bdd1243dSDimitry Andric 57*bdd1243dSDimitry Andricpublic: 58*bdd1243dSDimitry Andric // The defaulted __ptr argument is necessary so that the builtin is evaluated 59*bdd1243dSDimitry Andric // in the context of the caller. An explicit value should never be provided. 60*bdd1243dSDimitry Andric static consteval source_location current(__bsl_ty __ptr = __builtin_source_location()) noexcept { 61*bdd1243dSDimitry Andric source_location __sl; 62*bdd1243dSDimitry Andric __sl.__ptr_ = static_cast<const __impl*>(__ptr); 63*bdd1243dSDimitry Andric return __sl; 64*bdd1243dSDimitry Andric } 65*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr source_location() noexcept = default; 66*bdd1243dSDimitry Andric 67*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr uint_least32_t line() const noexcept { 68*bdd1243dSDimitry Andric return __ptr_ != nullptr ? __ptr_->_M_line : 0; 69*bdd1243dSDimitry Andric } 70*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr uint_least32_t column() const noexcept { 71*bdd1243dSDimitry Andric return __ptr_ != nullptr ? __ptr_->_M_column : 0; 72*bdd1243dSDimitry Andric } 73*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const char* file_name() const noexcept { 74*bdd1243dSDimitry Andric return __ptr_ != nullptr ? __ptr_->_M_file_name : ""; 75*bdd1243dSDimitry Andric } 76*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr const char* function_name() const noexcept { 77*bdd1243dSDimitry Andric return __ptr_ != nullptr ? __ptr_->_M_function_name : ""; 78*bdd1243dSDimitry Andric } 79*bdd1243dSDimitry Andric}; 80*bdd1243dSDimitry Andric 81*bdd1243dSDimitry Andric#endif // _LIBCPP_STD_VER >= 20 && __has_builtin(__builtin_source_location) 82*bdd1243dSDimitry Andric 83*bdd1243dSDimitry Andric_LIBCPP_END_NAMESPACE_STD 84*bdd1243dSDimitry Andric 85*bdd1243dSDimitry Andric#endif // _LIBCPP_SOURCE_LOCATION 86