d: Remove D-specific version definitions from target headers

Message ID 20221017180844.3492051-1-ibuclaw@gdcproject.org
State Accepted
Headers
Series d: Remove D-specific version definitions from target headers |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Iain Buclaw Oct. 17, 2022, 6:08 p.m. UTC
  Hi,

This splits up the targetdm sources so that each file only handles one
target platform.

Having all logic kept in the headers means that they could become out of
sync when a new target is added (loongarch*-*-linux*) or accidentally
broken if some headers in tm_file are omitted or changed about.

There might be an open bikeshed question as to appropriate names for
some of the platform sources (kfreebsd-d.cc or kfreebsd-gnu-d.cc).

Bootstrapped and regression tested on x86_64-linux-gnu, and also built
i686-cygwin, i686-gnu, i686-kfreebsd-gnu, i686-kopensolaris-gnu,
x86_64-cygwin, x86_64-w64-mingw32 cross compilers, the dumps of all
predefined version identifiers remain correct in all configurations.

OK?

Regards,
Iain.

---
gcc/ChangeLog:

	* config.gcc: Split out glibc-d.o into linux-d.o, kfreebsd-d.o,
	kopensolaris-d.o, and gnu-d.o.  Split out cygwin-d.o from winnt-d.o.
	* config/arm/linux-eabi.h (EXTRA_TARGET_D_OS_VERSIONS): Remove.
	* config/gnu.h (GNU_USER_TARGET_D_OS_VERSIONS): Remove.
	* config/i386/cygwin.h (EXTRA_TARGET_D_OS_VERSIONS): Remove.
	* config/i386/linux-common.h (EXTRA_TARGET_D_OS_VERSIONS): Remove.
	* config/i386/mingw32.h (EXTRA_TARGET_D_OS_VERSIONS): Remove.
	* config/i386/t-cygming: Add cygwin-d.o.
	* config/i386/winnt-d.cc (winnt_d_os_builtins): Only add
	MinGW-specific version condition.
	* config/kfreebsd-gnu.h (GNU_USER_TARGET_D_OS_VERSIONS): Remove.
	* config/kopensolaris-gnu.h (GNU_USER_TARGET_D_OS_VERSIONS): Remove.
	* config/linux-android.h (ANDROID_TARGET_D_OS_VERSIONS): Remove.
	* config/linux.h (GNU_USER_TARGET_D_OS_VERSIONS): Remove.
	* config/mips/linux-common.h (EXTRA_TARGET_D_OS_VERSIONS): Remove.
	* config/t-glibc: Remove glibc-d.o, add gnu-d.o, kfreebsd-d.o,
	kopensolaris-d.o.
	* config/t-linux: Add linux-d.o.
	* config/glibc-d.cc: Remove file.
	* config/gnu-d.cc: New file.
	* config/i386/cygwin-d.cc: New file.
	* config/kfreebsd-d.cc: New file.
	* config/kopensolaris-d.cc: New file.
	* config/linux-d.cc: New file.
---
 gcc/config.gcc                      | 24 +++++++--
 gcc/config/arm/linux-eabi.h         |  3 --
 gcc/config/{glibc-d.cc => gnu-d.cc} | 30 ++++-------
 gcc/config/gnu.h                    |  6 ---
 gcc/config/i386/cygwin-d.cc         | 83 +++++++++++++++++++++++++++++
 gcc/config/i386/cygwin.h            |  9 ----
 gcc/config/i386/linux-common.h      |  3 --
 gcc/config/i386/mingw32.h           | 12 -----
 gcc/config/i386/t-cygming           |  4 ++
 gcc/config/i386/winnt-d.cc          | 10 ++--
 gcc/config/kfreebsd-d.cc            | 65 ++++++++++++++++++++++
 gcc/config/kfreebsd-gnu.h           |  6 ---
 gcc/config/kopensolaris-d.cc        | 65 ++++++++++++++++++++++
 gcc/config/kopensolaris-gnu.h       |  6 ---
 gcc/config/linux-android.h          |  6 ---
 gcc/config/linux-d.cc               | 78 +++++++++++++++++++++++++++
 gcc/config/linux.h                  | 13 -----
 gcc/config/mips/linux-common.h      |  3 --
 gcc/config/t-glibc                  | 10 +++-
 gcc/config/t-linux                  |  4 ++
 20 files changed, 345 insertions(+), 95 deletions(-)
 rename gcc/config/{glibc-d.cc => gnu-d.cc} (65%)
 create mode 100644 gcc/config/i386/cygwin-d.cc
 create mode 100644 gcc/config/kfreebsd-d.cc
 create mode 100644 gcc/config/kopensolaris-d.cc
 create mode 100644 gcc/config/linux-d.cc
  

Comments

Li, Pan2 via Gcc-patches Oct. 23, 2022, 11:35 a.m. UTC | #1
> On 17/10/2022 20:08 CEST Iain Buclaw <ibuclaw@gdcproject.org> wrote:
> 
>  
> Hi,
> 
> This splits up the targetdm sources so that each file only handles one
> target platform.
> 
> Having all logic kept in the headers means that they could become out of
> sync when a new target is added (loongarch*-*-linux*) or accidentally
> broken if some headers in tm_file are omitted or changed about.
> 
> There might be an open bikeshed question as to appropriate names for
> some of the platform sources (kfreebsd-d.cc or kfreebsd-gnu-d.cc).
> 
> Bootstrapped and regression tested on x86_64-linux-gnu, and also built
> i686-cygwin, i686-gnu, i686-kfreebsd-gnu, i686-kopensolaris-gnu,
> x86_64-cygwin, x86_64-w64-mingw32 cross compilers, the dumps of all
> predefined version identifiers remain correct in all configurations.
> 
> OK?
> 

Ping?

I'll apply this tomorrow, but there is a general open question about whether taking logic out of target headers and putting it in config.gcc is the right approach moving forward for non C/C++ front-ends.  This is also relevant for Rust, which initially put all their target support definitions in headers, and have since removed the entire tangled mess that created.

Regards,
Iain.
  
Richard Biener Oct. 24, 2022, 6:35 a.m. UTC | #2
On Sun, 23 Oct 2022, ibuclaw@gdcproject.org wrote:

> > On 17/10/2022 20:08 CEST Iain Buclaw <ibuclaw@gdcproject.org> wrote:
> > 
> >  
> > Hi,
> > 
> > This splits up the targetdm sources so that each file only handles one
> > target platform.
> > 
> > Having all logic kept in the headers means that they could become out of
> > sync when a new target is added (loongarch*-*-linux*) or accidentally
> > broken if some headers in tm_file are omitted or changed about.
> > 
> > There might be an open bikeshed question as to appropriate names for
> > some of the platform sources (kfreebsd-d.cc or kfreebsd-gnu-d.cc).
> > 
> > Bootstrapped and regression tested on x86_64-linux-gnu, and also built
> > i686-cygwin, i686-gnu, i686-kfreebsd-gnu, i686-kopensolaris-gnu,
> > x86_64-cygwin, x86_64-w64-mingw32 cross compilers, the dumps of all
> > predefined version identifiers remain correct in all configurations.
> > 
> > OK?
> > 
> 
> Ping?
> 
> I'll apply this tomorrow, but there is a general open question about 
> whether taking logic out of target headers and putting it in config.gcc 
> is the right approach moving forward for non C/C++ front-ends.  This is 
> also relevant for Rust, which initially put all their target support 
> definitions in headers, and have since removed the entire tangled mess 
> that created.

I think Joseph has the best guidance in these areas.  My opinion is
that things that can be done in config.gcc are fine to do there,
especially if it simplifies things or avoids problems in other
places of the compiler.

Richard.
  

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2af30b4a6ec..2c9b9a06564 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -879,10 +879,8 @@  case ${target} in
   esac
   c_target_objs="${c_target_objs} glibc-c.o"
   cxx_target_objs="${cxx_target_objs} glibc-c.o"
-  d_target_objs="${d_target_objs} glibc-d.o"
   tmake_file="${tmake_file} t-glibc"
   target_has_targetcm=yes
-  target_has_targetdm=yes
   case $target in
     *-*-*uclibc* | *-*-uclinuxfdpiceabi)
       ;;
@@ -891,6 +889,24 @@  case ${target} in
       gcc_cv_initfini_array=yes
       ;;
   esac
+  case $target in
+    *-*-*linux*)
+      d_target_objs="${d_target_objs} linux-d.o"
+      target_has_targetdm=yes
+      ;;
+    *-*-kfreebsd*-gnu)
+      d_target_objs="${d_target_objs} kfreebsd-d.o"
+      target_has_targetdm=yes
+      ;;
+    *-*-kopensolaris*-gnu)
+      d_target_objs="${d_target_objs} kopensolaris-d.o"
+      target_has_targetdm=yes
+      ;;
+    *-*-gnu*)
+      d_target_objs="${d_target_objs} gnu-d.o"
+      target_has_targetdm=yes
+      ;;
+  esac
   ;;
 *-*-netbsd*)
   tm_p_file="${tm_p_file} netbsd-protos.h"
@@ -2051,7 +2067,7 @@  i[34567]86-*-cygwin*)
 	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
-	d_target_objs="${d_target_objs} winnt-d.o"
+	d_target_objs="${d_target_objs} cygwin-d.o"
 	target_has_targetdm="yes"
 	if test x$enable_threads = xyes; then
 		thread_file='posix'
@@ -2069,7 +2085,7 @@  x86_64-*-cygwin*)
 	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
-	d_target_objs="${d_target_objs} winnt-d.o"
+	d_target_objs="${d_target_objs} cygwin-d.o"
 	target_has_targetdm="yes"
 	if test x$enable_threads = xyes; then
 		thread_file='posix'
diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
index 50cc0bc6d08..6d803ceca1e 100644
--- a/gcc/config/arm/linux-eabi.h
+++ b/gcc/config/arm/linux-eabi.h
@@ -30,9 +30,6 @@ 
     }						\
   while (false)
 
-#define EXTRA_TARGET_D_OS_VERSIONS()		\
-  ANDROID_TARGET_D_OS_VERSIONS();
-
 /* We default to a soft-float ABI so that binaries can run on all
    target hardware.  If you override this to use the hard-float ABI then
    change the setting of GLIBC_DYNAMIC_LINKER_DEFAULT as well.  */
diff --git a/gcc/config/glibc-d.cc b/gcc/config/gnu-d.cc
similarity index 65%
rename from gcc/config/glibc-d.cc
rename to gcc/config/gnu-d.cc
index 1411f1973e5..1c0dff2afe7 100644
--- a/gcc/config/glibc-d.cc
+++ b/gcc/config/gnu-d.cc
@@ -1,4 +1,4 @@ 
-/* Glibc support needed only by D front-end.
+/* GNU system support needed only by D front-end.
    Copyright (C) 2017-2022 Free Software Foundation, Inc.
 
 GCC is free software; you can redistribute it and/or modify it under
@@ -23,41 +23,33 @@  along with GCC; see the file COPYING3.  If not see
 #include "d/d-target.h"
 #include "d/d-target-def.h"
 
-/* Implement TARGET_D_OS_VERSIONS for Glibc targets.  */
+/* Implement TARGET_D_OS_VERSIONS for GNU targets.  */
 
 static void
-glibc_d_os_builtins (void)
+gnu_d_os_builtins (void)
 {
   d_add_builtin_version ("Posix");
-
-#define builtin_version(TXT) d_add_builtin_version (TXT)
-
-#ifdef GNU_USER_TARGET_D_OS_VERSIONS
-  GNU_USER_TARGET_D_OS_VERSIONS ();
-#endif
-
-#ifdef EXTRA_TARGET_D_OS_VERSIONS
-  EXTRA_TARGET_D_OS_VERSIONS ();
-#endif
+  d_add_builtin_version ("Hurd");
+  d_add_builtin_version ("CRuntime_Glibc");
 }
 
 /* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
 
 static tree
-glibc_d_handle_target_object_format (void)
+gnu_d_handle_target_object_format (void)
 {
   const char *objfmt = "elf";
 
   return build_string_literal (strlen (objfmt) + 1, objfmt);
 }
 
-/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets.  */
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for GNU targets.  */
 
 static void
-glibc_d_register_target_info (void)
+gnu_d_register_target_info (void)
 {
   const struct d_target_info_spec handlers[] = {
-    { "objectFormat", glibc_d_handle_target_object_format },
+    { "objectFormat", gnu_d_handle_target_object_format },
     { NULL, NULL },
   };
 
@@ -65,9 +57,9 @@  glibc_d_register_target_info (void)
 }
 
 #undef TARGET_D_OS_VERSIONS
-#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#define TARGET_D_OS_VERSIONS gnu_d_os_builtins
 
 #undef TARGET_D_REGISTER_OS_TARGET_INFO
-#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+#define TARGET_D_REGISTER_OS_TARGET_INFO gnu_d_register_target_info
 
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/gnu.h b/gcc/config/gnu.h
index de2ead82be9..e8d72463ab2 100644
--- a/gcc/config/gnu.h
+++ b/gcc/config/gnu.h
@@ -31,9 +31,3 @@  along with GCC.  If not, see <http://www.gnu.org/licenses/>.
 	builtin_assert ("system=unix");		\
 	builtin_assert ("system=posix");	\
     } while (0)
-
-#define GNU_USER_TARGET_D_OS_VERSIONS()		\
-    do {					\
-	builtin_version ("Hurd");		\
-	builtin_version ("CRuntime_Glibc");	\
-    } while (0)
diff --git a/gcc/config/i386/cygwin-d.cc b/gcc/config/i386/cygwin-d.cc
new file mode 100644
index 00000000000..619930b4ff4
--- /dev/null
+++ b/gcc/config/i386/cygwin-d.cc
@@ -0,0 +1,83 @@ 
+/* Cygwin support needed only by D front-end.
+   Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tm_d.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Cygwin targets.  */
+
+static void
+cygwin_d_os_builtins (void)
+{
+  d_add_builtin_version ("Windows");
+  d_add_builtin_version ("Cygwin");
+  d_add_builtin_version ("Posix");
+  d_add_builtin_version ("CRuntime_Newlib");
+}
+
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+cygwin_d_handle_target_object_format (void)
+{
+  const char *objfmt = "coff";
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Cygwin targets.  */
+
+static void
+cygwin_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", cygwin_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS cygwin_d_os_builtins
+
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO cygwin_d_register_target_info
+
+/* Define TARGET_D_MINFO_SECTION for Cygwin targets.  */
+
+#undef TARGET_D_MINFO_SECTION
+#define TARGET_D_MINFO_SECTION "minfo"
+
+#undef TARGET_D_MINFO_START_NAME
+#define TARGET_D_MINFO_START_NAME "__start_minfo"
+
+#undef TARGET_D_MINFO_END_NAME
+#define TARGET_D_MINFO_END_NAME "__stop_minfo"
+
+/* Define TARGET_D_TEMPLATES_ALWAYS_COMDAT for Cygwin targets.  */
+
+#undef TARGET_D_TEMPLATES_ALWAYS_COMDAT
+#define TARGET_D_TEMPLATES_ALWAYS_COMDAT true
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index d06eda369cf..0a604d65b32 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -29,15 +29,6 @@  along with GCC; see the file COPYING3.  If not see
     }								\
   while (0)
 
-#define EXTRA_TARGET_D_OS_VERSIONS()				\
-  do								\
-    {								\
-      builtin_version ("Cygwin");				\
-      builtin_version ("Posix");				\
-      builtin_version ("CRuntime_Newlib");			\
-    }								\
-  while (0)
-
 #undef CPP_SPEC
 #define CPP_SPEC "%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
   %{!ansi:-Dunix} \
diff --git a/gcc/config/i386/linux-common.h b/gcc/config/i386/linux-common.h
index efa7fb2072c..53cf86f58e7 100644
--- a/gcc/config/i386/linux-common.h
+++ b/gcc/config/i386/linux-common.h
@@ -27,9 +27,6 @@  along with GCC; see the file COPYING3.  If not see
     }                                          \
   while (0)
 
-#define EXTRA_TARGET_D_OS_VERSIONS()		\
-  ANDROID_TARGET_D_OS_VERSIONS();
-
 #undef CC1_SPEC
 #define CC1_SPEC \
   LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index d3ca0cd0279..c2b3841296c 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -53,18 +53,6 @@  along with GCC; see the file COPYING3.  If not see
     }								\
   while (0)
 
-#define EXTRA_TARGET_D_OS_VERSIONS()				\
-  do								\
-    {								\
-      builtin_version ("MinGW");				\
-      if (TARGET_64BIT && ix86_abi == MS_ABI)			\
-	builtin_version ("Win64");				\
-      else if (!TARGET_64BIT)					\
-	builtin_version ("Win32");				\
-      builtin_version ("CRuntime_Microsoft");			\
-    }								\
-  while (0)
-
 #ifndef TARGET_USE_PTHREAD_BY_DEFAULT
 #define SPEC_PTHREAD1 "pthread"
 #define SPEC_PTHREAD2 "!no-pthread"
diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming
index d4803dea401..f892c27b71d 100644
--- a/gcc/config/i386/t-cygming
+++ b/gcc/config/i386/t-cygming
@@ -39,6 +39,10 @@  winnt-stubs.o: $(srcdir)/config/i386/winnt-stubs.cc $(CONFIG_H) $(SYSTEM_H) core
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 	$(srcdir)/config/i386/winnt-stubs.cc
 
+cygwin-d.o: $(srcdir)/config/i386/cygwin-d.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 winnt-d.o: $(srcdir)/config/i386/winnt-d.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gcc/config/i386/winnt-d.cc b/gcc/config/i386/winnt-d.cc
index 00c28c3964a..a1fd3fa1fbe 100644
--- a/gcc/config/i386/winnt-d.cc
+++ b/gcc/config/i386/winnt-d.cc
@@ -31,12 +31,14 @@  static void
 winnt_d_os_builtins (void)
 {
   d_add_builtin_version ("Windows");
+  d_add_builtin_version ("MinGW");
 
-#define builtin_version(TXT) d_add_builtin_version (TXT)
+  if (TARGET_64BIT && ix86_abi == MS_ABI)
+    d_add_builtin_version ("Win64");
+  else if (!TARGET_64BIT)
+    d_add_builtin_version ("Win32");
 
-#ifdef EXTRA_TARGET_D_OS_VERSIONS
-  EXTRA_TARGET_D_OS_VERSIONS ();
-#endif
+  d_add_builtin_version ("CRuntime_Microsoft");
 }
 
 /* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
diff --git a/gcc/config/kfreebsd-d.cc b/gcc/config/kfreebsd-d.cc
new file mode 100644
index 00000000000..0bfa6bd8a56
--- /dev/null
+++ b/gcc/config/kfreebsd-d.cc
@@ -0,0 +1,65 @@ 
+/* kFreeBSD-based GNU systems support needed only by D front-end.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_d.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for kFreeBSD targets.  */
+
+static void
+kfreebsd_d_os_builtins (void)
+{
+  d_add_builtin_version ("Posix");
+  d_add_builtin_version ("FreeBSD");
+  d_add_builtin_version ("CRuntime_Glibc");
+}
+
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+kfreebsd_d_handle_target_object_format (void)
+{
+  const char *objfmt = "elf";
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for kFreeBSD targets.  */
+
+static void
+kfreebsd_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", kfreebsd_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS kfreebsd_d_os_builtins
+
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO kfreebsd_d_register_target_info
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/kfreebsd-gnu.h b/gcc/config/kfreebsd-gnu.h
index f74a627bc43..c28fcaf54f5 100644
--- a/gcc/config/kfreebsd-gnu.h
+++ b/gcc/config/kfreebsd-gnu.h
@@ -29,12 +29,6 @@  along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
-#define GNU_USER_TARGET_D_OS_VERSIONS()		\
-    do {					\
-	builtin_version ("FreeBSD");		\
-	builtin_version ("CRuntime_Glibc");	\
-    } while (0)
-
 #define GNU_USER_DYNAMIC_LINKER        GLIBC_DYNAMIC_LINKER
 #define GNU_USER_DYNAMIC_LINKER32      GLIBC_DYNAMIC_LINKER32
 #define GNU_USER_DYNAMIC_LINKER64      GLIBC_DYNAMIC_LINKER64
diff --git a/gcc/config/kopensolaris-d.cc b/gcc/config/kopensolaris-d.cc
new file mode 100644
index 00000000000..197471ab927
--- /dev/null
+++ b/gcc/config/kopensolaris-d.cc
@@ -0,0 +1,65 @@ 
+/* kOpenSolaris-based GNU systems support needed only by D front-end.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_d.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for kOpenSolaris targets.  */
+
+static void
+kopensolaris_d_os_builtins (void)
+{
+  d_add_builtin_version ("Posix");
+  d_add_builtin_version ("Solaris");
+  d_add_builtin_version ("CRuntime_Glibc");
+}
+
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+kopensolaris_d_handle_target_object_format (void)
+{
+  const char *objfmt = "elf";
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for kOpenSolaris targets.  */
+
+static void
+kopensolaris_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", kopensolaris_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS kopensolaris_d_os_builtins
+
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO kopensolaris_d_register_target_info
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/kopensolaris-gnu.h b/gcc/config/kopensolaris-gnu.h
index 8379f960b8b..3929d4b6955 100644
--- a/gcc/config/kopensolaris-gnu.h
+++ b/gcc/config/kopensolaris-gnu.h
@@ -30,11 +30,5 @@  along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
-#define GNU_USER_TARGET_D_OS_VERSIONS()		\
-    do {					\
-	builtin_version ("Solaris");		\
-	builtin_version ("CRuntime_Glibc");	\
-    } while (0)
-
 #undef GNU_USER_DYNAMIC_LINKER
 #define GNU_USER_DYNAMIC_LINKER "/lib/ld.so.1"
diff --git a/gcc/config/linux-android.h b/gcc/config/linux-android.h
index cf340660adb..f335ceabab5 100644
--- a/gcc/config/linux-android.h
+++ b/gcc/config/linux-android.h
@@ -25,12 +25,6 @@ 
 	  builtin_define ("__ANDROID__");			\
     } while (0)
 
-#define ANDROID_TARGET_D_OS_VERSIONS()				\
-    do {							\
-	if (TARGET_ANDROID)					\
-	  builtin_version ("Android");				\
-    } while (0)
-
 #if ANDROID_DEFAULT
 # define NOANDROID "mno-android"
 #else
diff --git a/gcc/config/linux-d.cc b/gcc/config/linux-d.cc
new file mode 100644
index 00000000000..f2ef2f03e71
--- /dev/null
+++ b/gcc/config/linux-d.cc
@@ -0,0 +1,78 @@ 
+/* Linux support needed only by D front-end.
+   Copyright (C) 2017-2022 Free Software Foundation, Inc.
+
+GCC 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.
+
+GCC 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 GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_d.h"
+#include "d/d-target.h"
+#include "d/d-target-def.h"
+
+/* Implement TARGET_D_OS_VERSIONS for Linux targets.  */
+
+static void
+linux_d_os_builtins (void)
+{
+  d_add_builtin_version ("Posix");
+
+  d_add_builtin_version ("linux");
+#ifdef TARGET_ANDROID
+  if (TARGET_ANDROID)
+    d_add_builtin_version ("Android");
+#endif
+
+  if (OPTION_GLIBC)
+    d_add_builtin_version ("CRuntime_Glibc");
+  else if (OPTION_UCLIBC)
+    d_add_builtin_version ("CRuntime_UClibc");
+  else if (OPTION_BIONIC)
+    d_add_builtin_version ("CRuntime_Bionic");
+  else if (OPTION_MUSL)
+    d_add_builtin_version ("CRuntime_Musl");
+}
+
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+linux_d_handle_target_object_format (void)
+{
+  const char *objfmt = "elf";
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Linux targets.  */
+
+static void
+linux_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", linux_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
+#undef TARGET_D_OS_VERSIONS
+#define TARGET_D_OS_VERSIONS linux_d_os_builtins
+
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO linux_d_register_target_info
+
+struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index 74f70793d90..d1d6753a2f6 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -58,19 +58,6 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 	builtin_assert ("system=posix");			\
     } while (0)
 
-#define GNU_USER_TARGET_D_OS_VERSIONS()				\
-    do {							\
-	builtin_version ("linux");				\
-	if (OPTION_GLIBC)					\
-	  builtin_version ("CRuntime_Glibc");			\
-	else if (OPTION_UCLIBC)					\
-	  builtin_version ("CRuntime_UClibc");			\
-	else if (OPTION_BIONIC)					\
-	  builtin_version ("CRuntime_Bionic");			\
-	else if (OPTION_MUSL)					\
-	  builtin_version ("CRuntime_Musl");			\
-    } while (0)
-
 /* Determine which dynamic linker to use depending on whether GLIBC or
    uClibc or Bionic or musl is the default C library and whether
    -muclibc or -mglibc or -mbionic or -mmusl has been passed to change
diff --git a/gcc/config/mips/linux-common.h b/gcc/config/mips/linux-common.h
index cf7713b16ea..b29f4aa3a0e 100644
--- a/gcc/config/mips/linux-common.h
+++ b/gcc/config/mips/linux-common.h
@@ -27,9 +27,6 @@  along with GCC; see the file COPYING3.  If not see
     ANDROID_TARGET_OS_CPP_BUILTINS();				\
   } while (0)
 
-#define EXTRA_TARGET_D_OS_VERSIONS()				\
-  ANDROID_TARGET_D_OS_VERSIONS();
-
 #undef  LINK_SPEC
 #define LINK_SPEC							\
   LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LINK_SPEC,			\
diff --git a/gcc/config/t-glibc b/gcc/config/t-glibc
index c8b7d4e524b..f26c37a48ac 100644
--- a/gcc/config/t-glibc
+++ b/gcc/config/t-glibc
@@ -20,6 +20,14 @@  glibc-c.o: config/glibc-c.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
-glibc-d.o: config/glibc-d.cc
+gnu-d.o: config/gnu-d.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
+kfreebsd-d.o: config/kfreebsd-d.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
+kopensolaris-d.o: config/kopensolaris-d.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gcc/config/t-linux b/gcc/config/t-linux
index d9bc9b8c9bf..830b9871b83 100644
--- a/gcc/config/t-linux
+++ b/gcc/config/t-linux
@@ -19,3 +19,7 @@ 
 linux.o: $(srcdir)/config/linux.cc
 	  $(COMPILE) $<
 	  $(POSTCOMPILE)
+
+linux-d.o: $(srcdir)/config/linux-d.cc
+	  $(COMPILE) $<
+	  $(POSTCOMPILE)