public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: JeanHeyd Meneide <phdofthehouse@gmail.com>
To: gcc-patches@gcc.gnu.org, "libstdc++" <libstdc++@gcc.gnu.org>,
		Jonathan Wakely <jwakely@redhat.com>,
	Jakub Jelinek <jakub@redhat.com>
Subject: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
Date: Fri, 27 Dec 2019 19:27:00 -0000	[thread overview]
Message-ID: <CANHA4Oiog-fEJszB+kf4WbTux5WtFfbZ4OpWUxdJhGBoPV=BEQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 804 bytes --]

     This patch implements std::source_location. There's a couple
cases where the builtin implemented does not do what is expected of
it, and so the bottom 3 batches of test cases fails. I'm still
including the patch so that others can pick up on what might need to
change about the __builtin_source_location implementation (CC:
Jonathan Wakely, Jakub Jelinek).

2019-12-27  JeanHeyd "ThePhD" Meneide  <phdofthehouse@gmail.com>

        * include/Makefile.in: add source_location header
        * include/bits/c++config: Add new detection macros for
          LINE, COLUMN, and SOURCE_LOCATION builtins.
        * include/std/source_location: New.
        * testuite/std/support/srcloc/std.n4842.C (new): test source_location
        * testuite/std/support/srcloc/std.n4842.h (new): test source_location

[-- Attachment #2: p1208r6.patch.txt --]
[-- Type: text/plain, Size: 14601 bytes --]

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 6300de9e96d..fc593c7c461 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -70,6 +70,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index ae4a493ea65..c104ffb28ab 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -414,6 +414,7 @@ std_headers = \
 	${std_srcdir}/scoped_allocator \
 	${std_srcdir}/set \
 	${std_srcdir}/shared_mutex \
+	${std_srcdir}/source_location \
 	${std_srcdir}/span \
 	${std_srcdir}/sstream \
 	${std_srcdir}/stack \
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 7ccfc5f199d..2d2ec96a925 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -630,6 +630,7 @@ namespace std
 
 #if __GNUC__ >= 7
 // Assume these are available if the compiler claims to be a recent GCC:
+# define _GLIBCXX_HAVE_BUILTIN_LINE 1
 # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1
 # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1
 # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1
@@ -637,6 +638,9 @@ namespace std
 # if __GNUC__ >= 9
 #  define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1
 # endif
+# if __GNUC__ >= 10
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
 #elif defined(__is_identifier) && defined(__has_builtin)
 // For non-GNU compilers:
 # if ! __is_identifier(__has_unique_object_representations)
@@ -654,6 +658,15 @@ namespace std
 # if ! __is_identifier(__is_same)
 #  define _GLIBCXX_BUILTIN_IS_SAME_AS(T, U) __is_same(T, U)
 # endif
+# if __has_builtin(__builtin_source_location)
+#  define _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION 1
+# endif
+# if __has_builtin(__builtin_LINE)
+#  define _GLIBCXX_HAVE_BUILTIN_LINE 1
+# endif
+# if __has_builtin(__builtin_COLUMN)
+#  define _GLIBCXX_HAVE_BUILTIN_COLUMN 1
+# endif
 #endif // GCC
 
 // PSTL configuration
diff --git a/libstdc++-v3/include/std/source_location b/libstdc++-v3/include/std/source_location
new file mode 100644
index 00000000000..3bf219efa81
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,172 @@
+// Component for retrieving function, line and column source info. -*- C++ -*-
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file source_location
+ *  This is a Standard C++ Library header.
+ */
+
+//
+// P1208 source_location library
+// Contributed by ThePhD with <3
+//
+
+#ifndef _GLIBCXX_SOURCE_LOCATION
+#define _GLIBCXX_SOURCE_LOCATION 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+
+#include <bits/c++config.h>
+#include <cstdint>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+// use by-pointer for GCC-style __builtin_source_location;
+// use by-value for Clang-style builtins.
+#ifdef _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      unsigned int _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (const void *__src_loc_impl =
+	       __builtin_source_location ()) noexcept
+    {
+      source_location __ret;
+      __ret._M_data = static_cast<const __impl *>(__src_loc_impl);
+      return __ret;
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data ()
+    { }
+
+    constexpr const char *
+    file_name () const noexcept
+    { return _M_data ? _M_data->_M_file_name : ""; }
+
+    constexpr const char *
+    function_name () const noexcept
+    { return _M_data ? _M_data->_M_function_name : ""; }
+
+    constexpr uint_least32_t
+    line () const noexcept
+    { return _M_data ? _M_data->_M_line : 0; }
+  
+    constexpr uint_least32_t
+    column () const noexcept
+    { return _M_data ? _M_data->_M_column : 0; }
+
+  private:
+    const __impl *_M_data;
+  };
+
+#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE)
+
+  struct source_location
+  {
+  private:
+    struct __impl
+    {
+      const char *_M_file_name;
+      const char *_M_function_name;
+      uint_least32_t _M_line, _M_column;
+    };
+
+  public:
+    static consteval source_location
+    current (uint_least32_t __line = __builtin_LINE (),
+#ifdef _GLIBCXX_HAVE_BUILTIN_COLUMN
+	     uint_least32_t __column = __builtin_COLUMN (),
+#else
+	     uint_least32_t __column = 0,
+#endif // __builtin_COLUMN from Clang 9+
+	     const char* __file = __builtin_FILE (),
+	     const char* __function = __builtin_FUNCTION ()) noexcept
+    {
+      return source_location (__line, __column, __file, __function);
+    }
+
+    constexpr
+    source_location () noexcept
+    : _M_data()
+    {
+      _M_data._M_file_name = "";
+      _M_data._M_function_name = "";
+      _M_data._M_line = 0;
+      _M_data._M_column = 0;
+    }
+
+    constexpr const char *
+    file_name () const
+    { return _M_data._M_file_name; }
+
+    constexpr const char *
+    function_name () const
+    { return _M_data._M_function_name; }
+
+    constexpr uint_least32_t
+    line () const
+    { return _M_data._M_line; }
+  
+    constexpr uint_least32_t
+    column () const
+    { return _M_data._M_column; }
+
+  private:
+    constexpr
+    source_location (uint_least32_t __line, uint_least32_t __column,
+		     const char* __file, const char* __function) noexcept
+    : _M_data ()
+    {
+      this->_M_data._M_file_name = __file;
+      this->_M_data._M_function_name = __function;
+      this->_M_data._M_line = __line;
+      this->_M_data._M_column = __column;
+    }
+
+    const __impl _M_data;
+  };
+
+#endif // __builtin_source_location vs. __builtin_LINE + __builtin_COLUMN
+
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++20
+#endif // _GLIBCXX_SOURCE_LOCATION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index e55a092eb89..4357d7de71c 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -196,6 +196,11 @@
 #endif
 #define __cpp_lib_to_array 201907L
 #endif
+#if defined(_GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION)
+# define __cpp_lib_is_constant_evaluated 201907L
+#elif defined(_GLIBCXX_HAVE_BUILTIN_LINE) && defined(_GLIBCXX_HAVE_BUILTIN_COLUMN)
+# define __cpp_lib_is_constant_evaluated 201907L
+#endif
 #endif // C++2a
 #endif // C++17
 #endif // C++14
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
new file mode 100644
index 00000000000..b3b6e5c5125
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
@@ -0,0 +1,137 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// Example from C++ Standard Working Draft N4842, November 2019 Mailing
+// Adapted for testing.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  constexpr s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  constexpr s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+constexpr std::source_location
+f(std::source_location a = std::source_location::current())
+{ return a; }
+
+constexpr std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+#include "std.n4842.h"
+#include <iostream>
+int main ()
+{
+  constexpr std::source_location main_sl = std::source_location::current();
+  constexpr std::source_location f_arg_sl = f(main_sl);
+  constexpr std::source_location g_sl = g();
+  constexpr std::source_location f_sl = f();
+  constexpr std::source_location h_sl = h();
+  constexpr s member_main_sl(main_sl);
+  constexpr s member_defaulted_sl(1);
+  constexpr s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+  constexpr std::string_view main_sl_fn_name(main_sl.function_name());
+  constexpr std::string_view main_sl_fi_name(main_sl.file_name());
+  static_assert(main_sl.line() == 55);
+  // closing paren of call
+  static_assert(main_sl.column() == 74);
+  static_assert(main_sl_fn_name.ends_with("main"sv));
+  static_assert(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  static_assert(f_arg_sl.line() == 55);
+  // closing paren of call
+  static_assert(f_arg_sl.column() == 74);
+  static_assert(f_arg_sl_fn_name.ends_with("main"sv));
+  static_assert(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view g_sl_fn_name(g_sl.function_name());
+  constexpr std::string_view g_sl_fi_name(g_sl.file_name());
+  static_assert(g_sl.line() == 47);
+  static_assert(g_sl.column() == 58); // closing paren of call
+  static_assert(g_sl_fn_name.ends_with("g"sv));
+  static_assert(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view h_sl_fn_name(h_sl.function_name());
+  constexpr std::string_view h_sl_fi_name(h_sl.file_name());
+  static_assert(h_sl.line() == 23);
+  static_assert(h_sl.column() == 58); // closing paren of call
+  static_assert(h_sl_fn_name.ends_with("h"sv));
+  static_assert(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  static_assert(member_main_sl.member.line() == 55);
+  static_assert(member_main_sl.member.column() == 74);
+  static_assert(member_main_sl_fn_name.ends_with("main"sv));
+  static_assert(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: Jakub's patch does not
+  // properly get the name of the calling function
+  // when used as a default argument,
+  // nor does it follow the example in the std
+  // FIXME: All 3 cases below are busted
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+  static_assert(member_defaulted_sl.member.line() == 59);
+  // closing brace/paren of constructor
+  static_assert(member_defaulted_sl.member.column() == 29);
+  static_assert(member_defaulted_sl_fn_name.ends_with("main"sv));
+  static_assert(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+  static_assert(member_sl.member.line() == 59);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.ends_with("main"sv));
+  static_assert(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_sl_fn_name(f_sl.function_name());
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+  static_assert(f_sl.line() == 58);
+  // closing paren of call
+  static_assert(f_sl.column() == 43);
+  static_assert(f_sl_fn_name.ends_with("main"sv));
+  static_assert(f_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
new file mode 100644
index 00000000000..50ff5c41bea
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.h
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <source_location>
+
+constexpr std::source_location
+h ()
+{
+  std::source_location a = std::source_location::current();
+  return a;
+}

             reply	other threads:[~2019-12-27 19:27 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-27 19:27 JeanHeyd Meneide [this message]
2019-12-27 19:33 ` Jakub Jelinek
2019-12-28  3:28   ` JeanHeyd Meneide
2020-01-02 10:28     ` Jonathan Wakely
2020-01-02 21:57       ` JeanHeyd Meneide
2020-01-02 22:07         ` Jakub Jelinek
2020-01-02 22:21           ` JeanHeyd Meneide
2020-12-03 19:25             ` Jonathan Wakely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANHA4Oiog-fEJszB+kf4WbTux5WtFfbZ4OpWUxdJhGBoPV=BEQ@mail.gmail.com' \
    --to=phdofthehouse@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jwakely@redhat.com \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).