Hi,
This is another version of my old patch, changed to use target hooks as
requested by Steven Bosscher.
Tested on i686-w64-mingw32, x86_64-w64-mingw32 and
x86_64-unknown-linux-gnu, bootstrapped on x86_64-unknown-linux-gnu.
Disclaimer: the patch is in public domain.
(because I don't have copyright assignment done).
gcc/c-family/ChangeLog:
c-target.def: New hook
gcc/ChangeLog:
config/config.gcc: Use new winnt-c.c target hooks
config/t-winnt: New file
config/winnt-c.c: New file
doc/tm.texi.in: Document new hook
doc/tm.texi: Regenerated
gcc/cp/Changelog:
decl.c: Use new cxx_implicit_extern_c hook
gcc/testsuite/ChangeLog:
g++.dg/abi/main.C: Added implicit C linkage tests
---
gcc/c-family/c-target.def | 7 +++++++
gcc/config.gcc | 5 ++++-
gcc/config/t-winnt | 22 ++++++++++++++++++++++
gcc/config/winnt-c.c | 39
+++++++++++++++++++++++++++++++++++++++
gcc/cp/decl.c | 5 ++++-
gcc/doc/tm.texi | 4 ++++
gcc/doc/tm.texi.in | 2 ++
gcc/testsuite/g++.dg/abi/main.C | 24 ++++++++++++++++++++++++
8 files changed, 106 insertions(+), 2 deletions(-)
create mode 100644 gcc/config/t-winnt
create mode 100644 gcc/config/winnt-c.c
create mode 100644 gcc/testsuite/g++.dg/abi/main.C
diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def
index 80042df..b9efae5 100644
--- a/gcc/c-family/c-target.def
+++ b/gcc/c-family/c-target.def
@@ -102,5 +102,12 @@ DEFHOOK
than just the compiler.",
const char *, (void),
hook_constcharptr_void_null)
+
+DEFHOOK
+(cxx_implicit_extern_c,
+ "Define this hook to add target-specific C++ implicit extern C functions.\
+ An example of such function is WinMain on Win32 targets.",
+ bool, (const char*),
+ NULL)
HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 5a205df..0cf61b0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1475,6 +1475,9 @@ x86_64-*-cygwin*)
i[34567]86-*-mingw* | x86_64-*-mingw*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h"
xm_file=i386/xm-mingw32.h
+ c_target_objs="${c_target_objs} winnt-c.o"
+ cxx_target_objs="${cxx_target_objs} winnt-c.o"
+ target_has_targetcm="yes"
case ${target} in
x86_64-*-* | *-w64-*)
need_64bit_isa=yes
@@ -1514,7 +1517,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
;;
esac
tm_file="${tm_file} i386/mingw-stdint.h"
- tmake_file="${tmake_file} i386/t-cygming t-slibgcc"
+ tmake_file="${tmake_file} t-winnt i386/t-cygming t-slibgcc"
case ${target} in
x86_64-w64-*)
tmake_file="${tmake_file} i386/t-mingw-w64"
diff --git a/gcc/config/t-winnt b/gcc/config/t-winnt
new file mode 100644
index 0000000..4cc3339
--- /dev/null
+++ b/gcc/config/t-winnt
@@ -0,0 +1,22 @@
+# Copyright (C) 2004, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# 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/>.
+
+winnt-c.o: config/winnt-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(C_TARGET_H) $(C_TARGET_DEF_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
+ $< $(OUTPUT_OPTION)
diff --git a/gcc/config/winnt-c.c b/gcc/config/winnt-c.c
new file mode 100644
index 0000000..da0f49c
--- /dev/null
+++ b/gcc/config/winnt-c.c
@@ -0,0 +1,39 @@
+/* Default C-family target hooks initializer.
+ Copyright (C) 2011
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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 "c-family/c-target.h"
+#include "c-family/c-target-def.h"
+
+static bool
+winnt_implicit_extern_c (const char *ident)
+{
+ return !strcmp(ident, "wmain")
+ || !strcmp(ident, "DllMain")
+ || !strcmp(ident, "WinMain")
+ || !strcmp(ident, "wWinMain");
+}
+
+#undef TARGET_CXX_IMPLICIT_EXTERN_C
+#define TARGET_CXX_IMPLICIT_EXTERN_C winnt_implicit_extern_c
+
+struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b2f1c6e..d96f05b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-common.h"
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
+#include "c-family/c-target.h"
#include "diagnostic.h"
#include "intl.h"
#include "debug.h"
@@ -7465,7 +7466,9 @@ grokfndecl (tree ctype,
|| (IDENTIFIER_LENGTH (declarator) > 10
&& IDENTIFIER_POINTER (declarator)[0] == '_'
&& IDENTIFIER_POINTER (declarator)[1] == '_'
- && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0))
+ && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)
+ || (targetcm.cxx_implicit_extern_c
+ && targetcm.cxx_implicit_extern_c(IDENTIFIER_POINTER (declarator))))
&& current_lang_name == lang_name_cplusplus
&& ctype == NULL_TREE
&& DECL_FILE_SCOPE_P (decl))
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index ec7ef75..dd0528d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10652,6 +10652,10 @@ Define this hook to return the name of a header file to be included at the start
This hook can be used together with a header provided by the system C library to implement ISO C requirements for certain macros to be predefined that describe properties of the whole implementation rather than just the compiler.
@end deftypefn
+@deftypefn {C Target Hook} bool TARGET_CXX_IMPLICIT_EXTERN_C (const char*@var{})
+Define this hook to add target-specific C++ implicit extern C functions. An example of such function is WinMain on Win32 targets.
+@end deftypefn
+
@defmac NO_IMPLICIT_EXTERN_C
Define this macro if the system header files support C++ as well as C@.
This macro inhibits the usual method of using system header files in
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index a418733..d75fdfb 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -10496,6 +10496,8 @@ files @code{__STDC__} will always expand to 1.
@hook TARGET_C_PREINCLUDE
+@hook TARGET_CXX_IMPLICIT_EXTERN_C
+
@defmac NO_IMPLICIT_EXTERN_C
Define this macro if the system header files support C++ as well as C@.
This macro inhibits the usual method of using system header files in
diff --git a/gcc/testsuite/g++.dg/abi/main.C b/gcc/testsuite/g++.dg/abi/main.C
new file mode 100644
index 0000000..4c5f1ea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/main.C
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+/* Check if entry points get implicit C linkage. If they don't, compiler will
+ * error on incompatible declarations */
+
+int main();
+extern "C" int main();
+
+#ifdef __MINGW32__
+
+int wmain();
+extern "C" int wmain();
+
+int DllMain();
+extern "C" int DllMain();
+
+int WinMain();
+extern "C" int WinMain();
+
+int wWinMain();
+extern "C" int wWinMain();
+
+#endif
+