diff mbox series

[committed] d: Implement __traits(getTargetInfo, "objectFormat")

Message ID 20210417123810.3103646-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Implement __traits(getTargetInfo, "objectFormat") | expand

Commit Message

Iain Buclaw April 17, 2021, 12:38 p.m. UTC
Hi,

Following on from adding TARGET_D_REGISTER_OS_TARGET_INFO, this adds the
required handlers to implement `__traits(getTargetInfo, "objectFormat")'
for all platforms that have D support files.

Some back-ends (i386, rs6000, and pa) have some awarenes of the what
object format they are compiling for, so new getTargetInfo handlers have
been have added both to those back-ends as well as platform-specific
target files to override the default in the D front-end.

Testing has been done with the following code (also validating other
changes that that been made to the front-end for MinGW support):

    alias SystemFn = extern(System) void function();
    alias WindowsFn = extern(Windows) void function();
    pragma(msg,
        " System: '", __traits(getLinkage, SystemFn),
        "' Windows: '", __traits(getLinkage, WindowsFn),
        "' floatAbi: '", __traits(getTargetInfo, "floatAbi"),
        "' objectFormat: '", __traits(getTargetInfo, "objectFormat"),
        "'");

With the results on these target configurations:

aarch64-linux-gnu:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

arm-eabi:
 System: 'C' Windows: 'Windows' floatAbi: 'soft' objectFormat: 'elf'

hppa2.0-hpux11.9:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'som'

hppa64-linux-gnu:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

i686-pc-linux-gnu:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

i686-pc-msdosdjgpp:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'coff'

i686-solaris2.11:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

mips-netbsd:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

powerpc64-darwin:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'macho'

powerpc-eabi:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

riscv64-unknown-linux-gnu:
 System: 'C' Windows: 'Windows' floatAbi: 'soft' objectFormat: 'elf'

rs6000-ibm-aix7.1:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'coff'

s390x-linux-gnu:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

sparc64-freebsd6:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

x86_64-apple-darwin:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'macho'

x86_64-dragonfly:
 System: 'C' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'elf'

x86_64-w64-mingw32:
 System: 'Windows' Windows: 'Windows' floatAbi: 'hard' objectFormat: 'coff'

As well as the above listed cross-compiled target configurations,
bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to mainline.

Regards,
Iain.

---
gcc/ChangeLog:

	* config/darwin-d.c (darwin_d_handle_target_object_format): New
	function.
	(darwin_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/dragonfly-d.c (dragonfly_d_handle_target_object_format): New
	function.
	(dragonfly_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/freebsd-d.c (freebsd_d_handle_target_object_format): New
	function.
	(freebsd_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/glibc-d.c (glibc_d_handle_target_object_format): New
	function.
	(glibc_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/i386/i386-d.c (ix86_d_handle_target_object_format): New
	function.
	(ix86_d_register_target_info): Add ix86_d_handle_target_object_format
	as handler for objectFormat key.
	* config/i386/winnt-d.c (winnt_d_handle_target_object_format): New
	function.
	(winnt_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/netbsd-d.c (netbsd_d_handle_target_object_format): New
	function.
	(netbsd_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/openbsd-d.c (openbsd_d_handle_target_object_format): New
	function.
	(openbsd_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.
	* config/pa/pa-d.c (pa_d_handle_target_object_format): New function.
	(pa_d_register_target_info): Add pa_d_handle_target_object_format as
	handler for objectFormat key.
	* config/rs6000/rs6000-d.c (rs6000_d_handle_target_object_format): New
	function.
	(rs6000_d_register_target_info): Add
	rs6000_d_handle_target_object_format as handler for objectFormat key.
	* config/sol2-d.c (solaris_d_handle_target_object_format): New
	function.
	(solaris_d_register_target_info): New function.
	(TARGET_D_REGISTER_OS_TARGET_INFO): Define.

gcc/d/ChangeLog:

	* d-target.cc (d_handle_target_object_format): New function.
	(d_language_target_info): Add d_handle_target_object_format as handler
	for objectFormat key.
	(Target::getTargetInfo): Continue if handler returned NULL_TREE.
---
 gcc/config/darwin-d.c        | 26 ++++++++++++++++++++++++++
 gcc/config/dragonfly-d.c     | 26 ++++++++++++++++++++++++++
 gcc/config/freebsd-d.c       | 26 ++++++++++++++++++++++++++
 gcc/config/glibc-d.c         | 26 ++++++++++++++++++++++++++
 gcc/config/i386/i386-d.c     | 19 +++++++++++++++++++
 gcc/config/i386/winnt-d.c    | 25 +++++++++++++++++++++++++
 gcc/config/netbsd-d.c        | 28 ++++++++++++++++++++++++++++
 gcc/config/openbsd-d.c       | 28 ++++++++++++++++++++++++++++
 gcc/config/pa/pa-d.c         | 17 +++++++++++++++++
 gcc/config/rs6000/rs6000-d.c | 21 +++++++++++++++++++++
 gcc/config/sol2-d.c          | 26 ++++++++++++++++++++++++++
 gcc/d/d-target.cc            | 35 +++++++++++++++++++++++++++++++----
 12 files changed, 299 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@  darwin_d_os_builtins (void)
   d_add_builtin_version ("darwin");
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+  const char *objfmt = "macho";
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets.  */
+
+static void
+darwin_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", darwin_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS darwin_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
 /* Define TARGET_D_MINFO_SECTION for Darwin targets.  */
 
 #undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@  dragonfly_d_os_builtins (void)
   d_add_builtin_version ("Posix");
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+dragonfly_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 DragonFly targets.  */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", dragonfly_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 8a8ddd92884..8bebe79c895 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -37,7 +37,33 @@  freebsd_d_os_builtins (void)
   d_add_builtin_version ("Posix");
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+freebsd_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 FreeBSD targets.  */
+
+static void
+freebsd_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", freebsd_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@  glibc_d_os_builtins (void)
 #endif
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+glibc_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.  */
+
+static void
+glibc_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", glibc_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS glibc_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index da5958c3e7d..cb99376cd78 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -60,6 +60,24 @@  ix86_d_handle_target_float_abi (void)
   return build_string_literal (strlen (abi) + 1, abi);
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+ix86_d_handle_target_object_format (void)
+{
+  const char *objfmt = NULL;
+
+  if (TARGET_MACHO)
+    objfmt = "macho";
+  else if (TARGET_COFF || TARGET_PECOFF)
+    objfmt = "coff";
+
+  if (objfmt == NULL)
+    return NULL_TREE;
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
 /* Implement TARGET_D_REGISTER_CPU_TARGET_INFO.  */
 
 void
@@ -67,6 +85,7 @@  ix86_d_register_target_info (void)
 {
   const struct d_target_info_spec handlers[] = {
     { "floatAbi", ix86_d_handle_target_float_abi },
+    { "objectFormat", ix86_d_handle_target_object_format },
     { NULL, NULL },
   };
 
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index 8a6b9c57d8d..b9780258549 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -39,9 +39,34 @@  winnt_d_os_builtins (void)
 #endif
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+winnt_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 Windows targets.  */
+
+static void
+winnt_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", winnt_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS winnt_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO winnt_d_register_target_info
+
 /* Define TARGET_D_MINFO_SECTION for Windows targets.  */
 
 #undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..842644f82a3 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -26,6 +26,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "d/d-target.h"
 #include "d/d-target-def.h"
 
+/* Define TARGET_D_OS_VERSIONS for NetBSD targets.  */
+
 static void
 netbsd_d_os_builtins (void)
 {
@@ -33,7 +35,33 @@  netbsd_d_os_builtins (void)
   d_add_builtin_version ("NetBSD");
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+netbsd_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 NetBSD targets.  */
+
+static void
+netbsd_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", netbsd_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/openbsd-d.c b/gcc/config/openbsd-d.c
index b42727e1d5a..31f8eb496fc 100644
--- a/gcc/config/openbsd-d.c
+++ b/gcc/config/openbsd-d.c
@@ -26,6 +26,8 @@  along with GCC; see the file COPYING3.  If not see
 #include "d/d-target.h"
 #include "d/d-target-def.h"
 
+/* Define TARGET_D_OS_VERSIONS for OpenBSD targets.  */
+
 static void
 openbsd_d_os_builtins (void)
 {
@@ -33,7 +35,33 @@  openbsd_d_os_builtins (void)
   d_add_builtin_version ("OpenBSD");
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+openbsd_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 OpenBSD targets.  */
+
+static void
+openbsd_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", openbsd_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS openbsd_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO openbsd_d_register_target_info
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 41b2f1848e7..6802738e85b 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -55,6 +55,22 @@  pa_d_handle_target_float_abi (void)
   return build_string_literal (strlen (abi) + 1, abi);
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+pa_d_handle_target_object_format (void)
+{
+  const char *objfmt = NULL;
+
+  if (TARGET_SOM)
+    objfmt = "som";
+
+  if (objfmt == NULL)
+    return NULL_TREE;
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
 /* Implement TARGET_D_REGISTER_CPU_TARGET_INFO.  */
 
 void
@@ -62,6 +78,7 @@  pa_d_register_target_info (void)
 {
   const struct d_target_info_spec handlers[] = {
     { "floatAbi", pa_d_handle_target_float_abi },
+    { "objectFormat", pa_d_handle_target_object_format },
     { NULL, NULL },
   };
 
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 755de42733b..6f1f55b01b8 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -63,6 +63,26 @@  rs6000_d_handle_target_float_abi (void)
   return build_string_literal (strlen (abi) + 1, abi);
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+rs6000_d_handle_target_object_format (void)
+{
+  const char *objfmt = NULL;
+
+  if (TARGET_ELF)
+    objfmt = "elf";
+  else if (TARGET_MACHO)
+    objfmt = "macho";
+  else if (TARGET_XCOFF)
+    objfmt = "coff";
+
+  if (objfmt == NULL)
+    return NULL_TREE;
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
 /* Implement TARGET_D_REGISTER_CPU_TARGET_INFO.  */
 
 void
@@ -70,6 +90,7 @@  rs6000_d_register_target_info (void)
 {
   const struct d_target_info_spec handlers[] = {
     { "floatAbi", rs6000_d_handle_target_float_abi },
+    { "objectFormat", rs6000_d_handle_target_object_format },
     { NULL, NULL },
   };
 
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@  solaris_d_os_builtins (void)
   d_add_builtin_version ("Solaris");			\
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+static tree
+solaris_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 Solaris targets.  */
+
+static void
+solaris_d_register_target_info (void)
+{
+  const struct d_target_info_spec handlers[] = {
+    { "objectFormat", solaris_d_handle_target_object_format },
+    { NULL, NULL },
+  };
+
+  d_add_target_info_handlers (handlers);
+}
+
 #undef TARGET_D_OS_VERSIONS
 #define TARGET_D_OS_VERSIONS solaris_d_os_builtins
 
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index be354d9f1f0..1488bcebb2c 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -47,6 +47,7 @@  Target target;
 /* Internal key handlers for `__traits(getTargetInfo)'.  */
 static tree d_handle_target_cpp_std (void);
 static tree d_handle_target_cpp_runtime_library (void);
+static tree d_handle_target_object_format (void);
 
 /* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
    which are always available.  */
@@ -56,7 +57,7 @@  static const struct d_target_info_spec d_language_target_info[] =
   { "cppStd", d_handle_target_cpp_std },
   { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
   { "floatAbi", NULL },
-  { "objectFormat", NULL },
+  { "objectFormat", d_handle_target_object_format },
   { NULL, NULL },
 };
 
@@ -517,6 +518,25 @@  d_handle_target_cpp_runtime_library (void)
   return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
 }
 
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'.  */
+
+tree
+d_handle_target_object_format (void)
+{
+  const char *objfmt;
+
+#ifdef OBJECT_FORMAT_ELF
+  objfmt = "elf";
+#else
+  if (TARGET_COFF || TARGET_PECOFF)
+    objfmt = "coff";
+  else
+    objfmt = "";
+#endif
+
+  return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
 /* Look up the target info KEY in the available getTargetInfo tables, and return
    the result as an Expression, or NULL if KEY is not found.  When the key must
    always exist, but is not supported, an empty string expression is returned.
@@ -533,13 +553,20 @@  Target::getTargetInfo (const char *key, const Loc &loc)
       tree result;
 
       if (strcmp (key, spec->name) != 0)
-       continue;
+	continue;
 
       /* Get the requested information, or empty string if unhandled.  */
       if (spec->handler)
-       result = (spec->handler) ();
+	{
+	  result = (spec->handler) ();
+	  /* Handler didn't return a result, meaning it really does not support
+	     the key in the current target configuration.  Check whether there
+	     are any other handlers which may recognize the key.  */
+	  if (result == NULL_TREE)
+	    continue;
+	}
       else
-       result = build_string_literal (1, "");
+	result = build_string_literal (1, "");
 
       gcc_assert (result);
       return d_eval_constant_expression (loc, result);