public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: JeanHeyd Meneide <phdofthehouse@gmail.com>
To: Jonathan Wakely <jwakely@redhat.com>
Cc: Jakub Jelinek <jakub@redhat.com>,
	gcc-patches@gcc.gnu.org, 	"libstdc++" <libstdc++@gcc.gnu.org>
Subject: Re: [ PATCH ] [ C++ ] [ libstdc++ ] P1208r6 Merge source_location
Date: Thu, 02 Jan 2020 21:57:00 -0000	[thread overview]
Message-ID: <CANHA4OieN8T+c7r_gtM+EEq_krY-_thTWGmhbW+=-DHSD7j8mA@mail.gmail.com> (raw)
In-Reply-To: <20200102102822.GL40198@redhat.com>

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

On Thu, Jan 2, 2020 at 5:28 AM Jonathan Wakely <jwakely@redhat.com> wrote:
>
> Do nothing - compiling with Clang won't define std::source_location at
> all.

You got it! Patch re-done after discussion here
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93093) and recommended
no-Clang change.

2020-01-02  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/consteval.std.n4842.h (new):
test source_location
        * 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: 37166 bytes --]

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 f983743b052..6ca431b24ee 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..4c805df0dfa
--- /dev/null
+++ b/libstdc++-v3/include/std/source_location
@@ -0,0 +1,101 @@
+// Component for retrieving function, line and column source info. -*- C++ -*-
+
+// Copyright (C) 2019-2020 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
+
+#include <bits/c++config.h>
+#include <cstdint>
+
+#if __cplusplus > 201703L
+#ifdef _GLIBCXX_HAVE_BUILTIN_SOURCE_LOCATION
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#define __cpp_lib_source_location 201907L
+
+  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;
+  };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // has __builtin_source_location
+#endif // C++20
+
+#endif // _GLIBCXX_SOURCE_LOCATION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index ab8111468e4..e482c87ac36 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_source_location 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/consteval.std.n4842.C b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
new file mode 100644
index 00000000000..7c057b60e48
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/consteval.std.n4842.C
@@ -0,0 +1,147 @@
+// Copyright (C) 2019-2020 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"
+
+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;
+
+
+  static_assert (std::source_location::current ().line () == __LINE__);
+  static_assert (std::source_location::current ().column () == 49);
+
+
+  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: All 3 cases below are busted
+  // Which is user-hostile, but right now
+  // constant evaluation evaluates the call immediately
+  // and without call stack information...
+  constexpr std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+#if 0
+  constexpr std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  static_assert(member_defaulted_sl.member.line() == 35);
+  // closing paren of constructor declaration
+  static_assert(member_defaulted_sl.member.column() == 26);
+  static_assert(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+#endif
+  static_assert(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+#if 0
+  constexpr std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  static_assert(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  static_assert(member_sl.member.column() == 29);
+  static_assert(member_sl_fn_name.ends_with("main"sv));
+#endif
+  static_assert(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  constexpr std::string_view f_sl_fi_name(f_sl.file_name());
+#if 0
+  constexpr std::string_view f_sl_fn_name(f_sl.function_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));
+#endif
+  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.C b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
new file mode 100644
index 00000000000..fecd79d139a
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/support/srcloc/std.n4842.C
@@ -0,0 +1,149 @@
+// Copyright (C) 2019-2020 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 run { target c++2a } }
+
+#include <source_location>
+#include <string_view>
+#include <testsuite_hooks.h>
+#include "std.n4842.h"
+
+struct s {
+  std::source_location member = std::source_location::current();
+  int other_member = 1;
+  
+  s(std::source_location loc = std::source_location::current())
+    : member(loc) // values of member refer to calling function
+  { }
+
+  s(int blather) : // values of member refer to this location
+    other_member(blather)
+  { }
+};
+
+std::source_location
+f(std::source_location a = std::source_location::current());
+
+std::source_location
+f(std::source_location a)
+{ return a; }
+
+std::source_location
+g()
+{
+  std::source_location c = std::source_location::current();
+  return f(c);
+}
+
+int main ()
+{
+  std::source_location main_sl = std::source_location::current();
+  std::source_location f_arg_sl = f(main_sl);
+  std::source_location g_sl = g();
+  std::source_location f_sl = f();
+  std::source_location h_sl = h();
+  s member_main_sl(main_sl);
+  s member_defaulted_sl(1);
+  s member_sl = s{};
+
+  using namespace std::string_view_literals;
+
+  std::string_view main_sl_fn_name(main_sl.function_name());
+  std::string_view main_sl_fi_name(main_sl.file_name());
+  VERIFY(main_sl.line() == 58);
+  // closing paren of call
+  VERIFY(main_sl.column() == 64);
+  VERIFY(main_sl_fn_name.ends_with("main"sv));
+  VERIFY(main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_arg_sl_fn_name(f_arg_sl.function_name());
+  std::string_view f_arg_sl_fi_name(f_arg_sl.file_name());
+  VERIFY(f_arg_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_arg_sl.column() == 64);
+  VERIFY(f_arg_sl_fn_name.ends_with("main"sv));
+  VERIFY(f_arg_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view g_sl_fn_name(g_sl.function_name());
+  std::string_view g_sl_fi_name(g_sl.file_name());
+  VERIFY(g_sl.line() == 52);
+  VERIFY(g_sl.column() == 58); // closing paren of call
+  VERIFY(g_sl_fn_name.ends_with("g"sv));
+  VERIFY(g_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view h_sl_fn_name(h_sl.function_name());
+  std::string_view h_sl_fi_name(h_sl.file_name());
+  VERIFY(h_sl.line() == 23);
+  VERIFY(h_sl.column() == 58); // closing paren of call
+  VERIFY(h_sl_fn_name.ends_with("h"sv));
+  VERIFY(h_sl_fi_name.ends_with("std.n4842.h"sv));
+
+  std::string_view member_main_sl_fn_name(member_main_sl.member.function_name());
+  std::string_view member_main_sl_fi_name(member_main_sl.member.file_name());
+  VERIFY(member_main_sl.member.line() == 58);
+  VERIFY(member_main_sl.member.column() == 64);
+  VERIFY(member_main_sl_fn_name.ends_with("main"sv));
+  VERIFY(member_main_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  // FIXME: the following cases are all busted
+  // despite the standard giving examples to the contrary.
+  // Unfortunately GCC's constant folder / evaluator
+  // (and the standard's) manifestly constant evaluates
+  // default arguments, and at that point GCC has no
+  // call stack information for anyone to
+  // produce additional information.
+  // It will require extra work to make these work with it.
+  std::string_view member_defaulted_sl_fi_name(
+    member_defaulted_sl.member.file_name());
+#if 0
+  std::string_view member_defaulted_sl_fn_name(
+    member_defaulted_sl.member.function_name());
+  VERIFY(member_defaulted_sl.member.line() == 37);
+  // closing paren of constructor declaration
+  VERIFY(member_defaulted_sl.member.column() == 26);
+  VERIFY(member_defaulted_sl_fn_name.ends_with("s::s"sv));
+#endif
+  VERIFY(member_defaulted_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view member_sl_fi_name(
+    member_sl.member.file_name());
+#if 0
+  std::string_view member_sl_fn_name(
+    member_sl.member.function_name());
+  VERIFY(member_sl.member.line() == 62);
+  // closing brace/paren of constructor
+  VERIFY(member_sl.member.column() == 29);
+  VERIFY(member_sl_fn_name.ends_with("main"sv));
+#endif
+  VERIFY(member_sl_fi_name.ends_with("std.n4842.C"sv));
+
+  std::string_view f_sl_fi_name(f_sl.file_name());
+#if 0
+  std::string_view f_sl_fn_name(f_sl.function_name());
+  VERIFY(f_sl.line() == 58);
+  // closing paren of call
+  VERIFY(f_sl.column() == 43);
+  VERIFY(f_sl_fn_name.ends_with("main"sv));
+#endif
+  VERIFY(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:[~2020-01-02 21:57 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-27 19:27 JeanHeyd Meneide
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 [this message]
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='CANHA4OieN8T+c7r_gtM+EEq_krY-_thTWGmhbW+=-DHSD7j8mA@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).