From eccec8684142e05f2f92f0f5bd5b47dda3ba1529 Mon Sep 17 00:00:00 2001
From: JeanHeyd Meneide <phdofthehouse@gmail.com>
Date: Tue, 1 Dec 2020 14:39:47 -0700
Subject: [PATCH] Feature: Macros for identifying the wide and narrow execution
 string literal encoding

gcc/c-family
	* c-cppbuiltin.c (c_cpp_builtins): Add predefined
	{__GNUC_EXECUTION_CHARSET_NAME} and
	_WIDE_EXECUTION_CHARSET_NAME} macros.

gcc/
	* doc/cpp.texi: Document new macros.

gcc/testsuite/
	* c-c++-common/cpp/wide-narrow-predef-macros.c: New test.

libcpp/
	* charset.c (init_iconv_desc): Initialize "to" and "from" fields.
	* directives.c (cpp_get_narrow_charset_name): New function.
	(cpp_get_wide_charset_name): Likewise.
	* include/cpplib.h (cpp_get_narrow_charset_name): Prototype.
	(cpp_get_wide_charset_name): Likewise.
	* internal.h (cset_converter): Add "to" and "from" fields.
---
 gcc/c-family/c-cppbuiltin.c                        |  7 +++++++
 gcc/doc/cpp.texi                                   |  9 +++++++++
 .../c-c++-common/cpp/wide-narrow-predef-macros.c   | 13 +++++++++++++
 libcpp/charset.c                                   |  3 +++
 libcpp/directives.c                                | 14 ++++++++++++++
 libcpp/include/cpplib.h                            |  5 +++++
 libcpp/internal.h                                  |  2 ++
 7 files changed, 53 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 41914f64874a..7b7b07db1361 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -877,6 +877,13 @@ c_cpp_builtins (cpp_reader *pfile)
 
   define_language_independent_builtin_macros (pfile);
 
+  /* encoding definitions used by users and libraries  */
+  builtin_define_with_value ("__GNUC_EXECUTION_CHARSET_NAME",
+    cpp_get_narrow_charset_name (pfile), 1);
+  builtin_define_with_value ("__GNUC_WIDE_EXECUTION_CHARSET_NAME",
+    cpp_get_wide_charset_name (pfile), 1);
+
+
   if (c_dialect_cxx ())
   {
     int major;
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 291e14676be0..5dcd67259e37 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -2451,6 +2451,15 @@ features are supported by GCC.
 @item __NO_MATH_ERRNO__
 This macro is defined if @option{-fno-math-errno} is used, or enabled
 by another option such as @option{-ffast-math} or by default.
+
+@item __GNUC_EXECUTION_CHARSET_NAME
+@itemx __GNUC_WIDE_EXECUTION_CHARSET_NAME
+These macros are defined to expand to a narrow string literal of
+the name of the narrow and wide compile-time execution character
+set used.  It directly reflects the name passed to the options
+@option{-fexec-charset} and @option{-fwide-exec-charset}, or the defaults
+documented for those options (that is, it can expand to something like
+@code{"UTF-8"}).  @xref{Invocation}.
 @end table
 
 @node System-specific Predefined Macros
diff --git a/gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c b/gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c
new file mode 100644
index 000000000000..d5440f8a61e4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/wide-narrow-predef-macros.c
@@ -0,0 +1,13 @@
+/*
+   { dg-do compile }
+ */
+
+#if !defined(__GNUC_EXECUTION_CHARSET_NAME)
+#error "Required implementation macro for comple-time charset name is not present"
+#endif
+#if !defined(__GNUC_WIDE_EXECUTION_CHARSET_NAME)
+#error "Required implementation macro for wide comple-time charset name is not present"
+#endif
+
+const char narrow_name[] = __GNUC_EXECUTION_CHARSET_NAME;
+const char wide_name[] = __GNUC_WIDE_EXECUTION_CHARSET_NAME;
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 28b81c9c8642..3e5578b13904 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -638,6 +638,9 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from)
   char *pair;
   size_t i;
 
+  ret.to = to;
+  ret.from = from;
+
   if (!strcasecmp (to, from))
     {
       ret.func = convert_no_conversion;
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 75115600e3aa..0d09da71abde 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -2596,6 +2596,20 @@ cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
   pfile->cb = *cb;
 }
 
+/* The narrow character set identifier.  */
+const char *
+cpp_get_narrow_charset_name (cpp_reader *pfile)
+{
+  return pfile->narrow_cset_desc.to;
+}
+
+/* The wide character set identifier.  */
+const char *
+cpp_get_wide_charset_name (cpp_reader *pfile)
+{
+  return pfile->wide_cset_desc.to;
+}
+
 /* The dependencies structure.  (Creates one if it hasn't already been.)  */
 class mkdeps *
 cpp_get_deps (cpp_reader *pfile)
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 2becd2e8e545..692aee58d19e 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -1005,6 +1005,11 @@ extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
 extern const char *cpp_find_header_unit (cpp_reader *, const char *file,
 					 bool angle_p,  location_t);
 
+/* Call these to get name data about the various compile-time
+   charsets.  */
+extern const char *cpp_get_narrow_charset_name (cpp_reader *) ATTRIBUTE_PURE;
+extern const char *cpp_get_wide_charset_name (cpp_reader *) ATTRIBUTE_PURE;
+
 /* This function reads the file, but does not start preprocessing.  It
    returns the name of the original file; this is the same as the
    input file, except for preprocessed input.  This will generate at
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 45bbbddf2684..4010af87496f 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -48,6 +48,8 @@ struct cset_converter
   convert_f func;
   iconv_t cd;
   int width;
+  const char* from;
+  const char* to;
 };
 
 #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t))
-- 
GitLab