commit b0d56c97c651b1d91e66fb8153e0270dd2e8817c Author: Jacek Caban Date: Sat Dec 29 18:06:39 2012 +0100 Add implicit C linkage for win32-specific entry points 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 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 36d5ae8..22f30f4 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1526,6 +1526,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 @@ -1565,7 +1568,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..1751622 --- /dev/null +++ b/gcc/config/t-winnt @@ -0,0 +1,22 @@ +# Copyright (C) 2013 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 +# . + +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..d52db62 --- /dev/null +++ b/gcc/config/winnt-c.c @@ -0,0 +1,39 @@ +/* Default C-family target hooks initializer. + Copyright (C) 2013 + 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 +. */ + +#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 b4223aa..f193676 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" @@ -7457,7 +7458,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 d15f53c..9b9df71 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10651,6 +10651,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 b51d7b3..fdc3925 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7985,6 +7985,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 +