[1/3] d: Add TARGET_D_HAS_STDCALL_CONVENTION

Message ID 20210405194342.922021-1-ibuclaw@gdcproject.org
State New
Headers show
Series
  • [1/3] d: Add TARGET_D_HAS_STDCALL_CONVENTION
Related show

Commit Message

Jason Merrill via Gcc-patches April 5, 2021, 7:43 p.m.
Hi,

This patch adds TARGET_D_HAS_STDCALL_CONVENTION as a new D front-end
target hook.  It replaces the use of the D front-end `is64bit' parameter
in determining whether to insert the "stdcall" function attribute.

It is also used to determine whether `extern(System)' should be the same
as `extern(Windows)' in the implementation of Target::systemLinkage.

Both are prerequesites for being able to compile libphobos on MinGW.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
tested on x86_64-w64-mingw64 for getting the libphobos port set-up.

Any issues with the implementation, or OK to commit?

Regards,
Iain.

---
gcc/ChangeLog:

	* config/i386/i386-d.c (ix86_d_has_stdcall_convention): New function.
	* config/i386/i386-protos.h (ix86_d_has_stdcall_convention): Declare.
	* config/i386/i386.h (TARGET_D_HAS_STDCALL_CONVENTION): Define.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (D language and ABI): Add @hook for
	TARGET_D_HAS_STDCALL_CONVENTION.

gcc/d/ChangeLog:

	* d-target.cc (Target::systemLinkage): Return LINKwindows if
	d_has_stdcall_convention applies to LINKsystem.
	* d-target.def (d_has_stdcall_convention): New hook.
	* types.cc (TypeVisitor::visit (TypeFunction *)): Insert "stdcall"
	function attribute if d_has_stdcall_convention applies to LINKwindows.
---
 gcc/config/i386/i386-d.c      | 20 ++++++++++++++++++++
 gcc/config/i386/i386-protos.h |  1 +
 gcc/config/i386/i386.h        |  3 ++-
 gcc/d/d-target.cc             | 12 +++++++++++-
 gcc/d/d-target.def            | 13 +++++++++++++
 gcc/d/types.cc                | 19 +++++++++++++------
 gcc/doc/tm.texi               |  8 ++++++++
 gcc/doc/tm.texi.in            |  2 ++
 8 files changed, 70 insertions(+), 8 deletions(-)

-- 
2.27.0

Patch

diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index b79be85e661..58b4790fdad 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -44,3 +44,23 @@  ix86_d_target_versions (void)
   else
     d_add_builtin_version ("D_SoftFloat");
 }
+
+/* Implement TARGET_D_HAS_STDCALL_CONVENTION for x86 targets.  */
+
+bool
+ix86_d_has_stdcall_convention (unsigned int *link_system,
+			       unsigned int *link_windows)
+{
+  if (ix86_abi == MS_ABI)
+    {
+      *link_system = 1;
+      *link_windows = (!TARGET_64BIT) ? 1 : 0;
+    }
+  else
+    {
+      *link_system = 0;
+      *link_windows = 0;
+    }
+
+  return true;
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..acfb9f5fe87 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@  extern void ix86_register_pragmas (void);
 
 /* In i386-d.c  */
 extern void ix86_d_target_versions (void);
+extern bool ix86_d_has_stdcall_convention (unsigned int *, unsigned int *);
 
 /* In winnt.c  */
 extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b4001d21b70..17e233a4e74 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -801,8 +801,9 @@  extern const char *host_detect_local_cpu (int argc, const char **argv);
 /* Target Pragmas.  */
 #define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
 
-/* Target CPU versions for D.  */
+/* Target hooks for D language.  */
 #define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_HAS_STDCALL_CONVENTION ix86_d_has_stdcall_convention
 
 #ifndef CC1_SPEC
 #define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index a1dc2ee286f..f1814df110d 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -435,11 +435,21 @@  TargetCPP::derivedClassOffset(ClassDeclaration *base_class)
   return base_class->structsize;
 }
 
-/* Return the default system linkage for the target.  */
+/* Return the default `extern (System)' linkage for the target.  */
 
 LINK
 Target::systemLinkage (void)
 {
+  unsigned link_system, link_windows;
+
+  if (targetdm.d_has_stdcall_convention (&link_system, &link_windows))
+    {
+      /* In [attribute/linkage], `System' is the same as `Windows' on Windows
+	 platforms, and `C' on other platforms.  */
+      if (link_system)
+	return LINKwindows;
+    }
+
   return LINKc;
 }
 
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..f79ffb9cd7d 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -71,5 +71,18 @@  as the name of the symbol indicating the end address of the module info\n\
 section",
  const char *, NULL)
 
+/* The "stdcall" convention is really supported on 32-bit x86/Windows only.
+   The following hook is a helper to determine whether to apply the attribute
+   on declarations with `extern(System)' and `extern(Windows)' linkage.  */
+DEFHOOK
+(d_has_stdcall_convention,
+ "Returns @code{true} if the target supports the stdcall calling convention.\n\
+The hook should also set @var{link_system} to @code{1} if the @code{stdcall}\n\
+attribute should be applied to functions with @code{extern(System)} linkage,\n\
+and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with\n\
+@code{extern(Windows)} linkage.",
+ bool, (unsigned int *link_system, unsigned int *link_windows),
+ hook_bool_uintp_uintp_false)
+
 /* Close the 'struct gcc_targetdm' definition.  */
 HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index 924d8298211..b757a075b52 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -40,6 +40,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 
 #include "d-tree.h"
+#include "d-target.h"
 
 
 /* Return the signed or unsigned version of TYPE, an integral type, the
@@ -798,13 +799,19 @@  public:
     switch (t->linkage)
       {
       case LINKwindows:
-	/* [attribute/linkage]
+	{
+	  /* [attribute/linkage]
 
-	   The Windows convention is distinct from the C convention only
-	   on Win32, where it is equivalent to the stdcall convention.  */
-	if (!global.params.is64bit)
-	  t->ctype = insert_type_attribute (t->ctype, "stdcall");
-	break;
+	     The Windows convention is distinct from the C convention only
+	     on Win32, where it is equivalent to the stdcall convention.  */
+	  unsigned link_system, link_windows;
+	  if (targetdm.d_has_stdcall_convention (&link_system, &link_windows))
+	    {
+	      if (link_windows)
+		t->ctype = insert_type_attribute (t->ctype, "stdcall");
+	    }
+	  break;
+	}
 
       case LINKc:
       case LINKcpp:
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..71607c4dc4e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10828,6 +10828,14 @@  as the name of the symbol indicating the end address of the module info
 section
 @end deftypevr
 
+@deftypefn {D Target Hook} bool TARGET_D_HAS_STDCALL_CONVENTION (unsigned int *@var{link_system}, unsigned int *@var{link_windows})
+Returns @code{true} if the target supports the stdcall calling convention.
+The hook should also set @var{link_system} to @code{1} if the @code{stdcall}
+attribute should be applied to functions with @code{extern(System)} linkage,
+and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with
+@code{extern(Windows)} linkage.
+@end deftypefn
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..c8880dafcd4 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7363,6 +7363,8 @@  floating-point support; they are not included in this mechanism.
 
 @hook TARGET_D_MINFO_END_NAME
 
+@hook TARGET_D_HAS_STDCALL_CONVENTION
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces